Pitch_to_Sound.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /* Pitch_to_Sound.cpp
  2. *
  3. * Copyright (C) 1992-2011,2015,2016,2017 Paul Boersma
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. * See the GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*
  19. * pb 2002/07/16 GPL
  20. * pb 2005/02/09 Pitch_to_Sound_sine
  21. * pb 2007/02/25 changed default sampling frequency to 44100 Hz
  22. * pb 2008/01/19 double
  23. * pb 2011/06/05 C++
  24. */
  25. #include "Pitch_to_PointProcess.h"
  26. #include "PointProcess_and_Sound.h"
  27. #include "Pitch_to_Sound.h"
  28. #include "PitchTier_to_Sound.h"
  29. #include "Pitch_to_PitchTier.h"
  30. autoSound Pitch_to_Sound (Pitch me, double tmin, double tmax, bool hum) {
  31. static double formant [1 + 6] { 0.0, 600.0, 1400.0, 2400.0, 3400.0, 4500.0, 5500.0 };
  32. static double bandwidth [1 + 6] { 0.0, 50.0, 100.0, 200.0, 300.0, 400.0, 500.0 };
  33. try {
  34. autoPointProcess point = Pitch_to_PointProcess (me);
  35. autoSound sound = PointProcess_to_Sound_pulseTrain (point.get(), 44100.0, 0.7, 0.05, 30);
  36. if (hum) {
  37. Sound_filterWithFormants (sound.get(), tmin, tmax, 6, formant, bandwidth);
  38. }
  39. return sound;
  40. } catch (MelderError) {
  41. Melder_throw (me, U": not converted to Sound.");
  42. }
  43. }
  44. void Pitch_play (Pitch me, double tmin, double tmax) {
  45. try {
  46. autoSound sound = Pitch_to_Sound (me, tmin, tmax, false);
  47. if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindowing
  48. Sound_playPart (sound.get(), tmin, tmax, nullptr, nullptr);
  49. } catch (MelderError) {
  50. Melder_throw (me, U": not played.");
  51. }
  52. }
  53. void Pitch_hum (Pitch me, double tmin, double tmax) {
  54. try {
  55. autoSound sound = Pitch_to_Sound (me, tmin, tmax, true);
  56. if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindowing
  57. Sound_playPart (sound.get(), tmin, tmax, nullptr, nullptr);
  58. } catch (MelderError) {
  59. Melder_throw (me, U": not played.");
  60. }
  61. }
  62. autoSound Pitch_to_Sound_sine (Pitch me, double tmin, double tmax, double samplingFrequency, bool roundToNearestZeroCrossings) {
  63. try {
  64. autoPitchTier tier = Pitch_to_PitchTier (me);
  65. autoSound sound = PitchTier_to_Sound_sine (tier.get(), tmin, tmax, samplingFrequency);
  66. integer iframe = 1;
  67. double unvoicedMin = my xmin;
  68. double unvoicedMax = my x1 + (iframe - 1.5) * my dx;
  69. for (;;) {
  70. while (! Pitch_isVoiced_i (me, iframe)) {
  71. unvoicedMax = my x1 + (iframe - 0.5) * my dx;
  72. if (++ iframe > my nx) break;
  73. }
  74. if (unvoicedMax > unvoicedMin) {
  75. Sound_setZero (sound.get(), unvoicedMin, unvoicedMax, roundToNearestZeroCrossings);
  76. }
  77. if (iframe > my nx) break;
  78. while (Pitch_isVoiced_i (me, iframe)) {
  79. unvoicedMin = my x1 + (iframe - 0.5) * my dx;
  80. if (++ iframe > my nx) break;
  81. }
  82. if (iframe > my nx) break;
  83. }
  84. unvoicedMax = my xmax;
  85. if (unvoicedMax > unvoicedMin) {
  86. Sound_setZero (sound.get(), unvoicedMin, unvoicedMax, roundToNearestZeroCrossings);
  87. }
  88. return sound;
  89. } catch (MelderError) {
  90. Melder_throw (me, U": not converted to Sound (sine).");
  91. }
  92. }
  93. /* End of file Pitch_to_Sound.cpp */