Pitch_Intensity.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /* Pitch_Intensity.cpp
  2. *
  3. * Copyright (C) 1992-2011,2014,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. #include "Pitch_Intensity.h"
  19. static void Pitch_getExtrema (Pitch me, double *minimum, double *maximum) {
  20. *minimum = 1e308, *maximum = -1e308;
  21. for (integer i = 1; i <= my nx; i ++) {
  22. double frequency = my frame [i]. candidate [1]. frequency;
  23. if (frequency == 0.0) continue; // voiceless
  24. if (frequency < *minimum) *minimum = frequency;
  25. if (frequency > *maximum) *maximum = frequency;
  26. }
  27. if (*maximum == -1e308) *maximum = 0.0;
  28. if (*minimum == 1e308) *minimum = 0.0;
  29. }
  30. void Pitch_Intensity_draw (Pitch pitch, Intensity intensity, Graphics g,
  31. double f1, double f2, double s1, double s2, bool garnish, int connect)
  32. {
  33. if (f2 <= f1) Pitch_getExtrema (pitch, & f1, & f2);
  34. if (f1 == 0.0) return; // all voiceless
  35. if (f1 == f2) { f1 -= 1.0; f2 += 1.0; }
  36. if (s2 <= s1) Matrix_getWindowExtrema (intensity, 0, 0, 1, 1, & s1, & s2);
  37. if (s1 == s2) { s1 -= 1.0; s2 += 1.0; }
  38. Graphics_setWindow (g, f1, f2, s1, s2);
  39. Graphics_setInner (g);
  40. double previousX = undefined;
  41. double previousY = undefined;
  42. integer previousI = 0;
  43. for (integer i = 1; i <= pitch -> nx; i ++) {
  44. double t = Sampled_indexToX (pitch, i);
  45. double x = pitch -> frame [i]. candidate [1]. frequency;
  46. double y = Sampled_getValueAtX (intensity, t, Pitch_LEVEL_FREQUENCY, (int) kPitch_unit::HERTZ, true);
  47. if (x == 0) {
  48. continue; // voiceless
  49. }
  50. if (connect & 1) Graphics_speckle (g, x, y);
  51. if ((connect & 2) && isdefined (previousX)) {
  52. if (previousI >= 1 && previousI < i - 1) {
  53. Graphics_setLineType (g, Graphics_DOTTED);
  54. }
  55. Graphics_line (g, previousX, previousY, x, y);
  56. Graphics_setLineType (g, Graphics_DRAWN);
  57. }
  58. previousX = x;
  59. previousY = y;
  60. previousI = i;
  61. }
  62. Graphics_unsetInner (g);
  63. if (garnish) {
  64. Graphics_drawInnerBox (g);
  65. Graphics_textBottom (g, true, U"Fundamental frequency (Hz)");
  66. Graphics_marksBottom (g, 2, true, true, false);
  67. Graphics_textLeft (g, true, U"Intensity (dB)");
  68. Graphics_marksLeft (g, 2, true, true, false);
  69. }
  70. }
  71. double Pitch_Intensity_getMean (Pitch thee, Intensity me) {
  72. integer numberOfValidLocalMeasurements = 0;
  73. double sumOfLocalValues = 0.0;
  74. for (integer iframe = 1; iframe <= my nx; iframe ++) {
  75. double t = Sampled_indexToX (me, iframe);
  76. bool localMeasurentIsValid = Pitch_isVoiced_t (thee, t);
  77. if (localMeasurentIsValid) {
  78. double localValue = my z [1] [iframe];
  79. sumOfLocalValues += localValue;
  80. numberOfValidLocalMeasurements += 1;
  81. }
  82. }
  83. return numberOfValidLocalMeasurements > 0 ? sumOfLocalValues / numberOfValidLocalMeasurements : undefined;
  84. }
  85. double Pitch_Intensity_getMeanAbsoluteSlope (Pitch thee, Intensity me) {
  86. integer numberOfValidLocalMeasurements = 0;
  87. double sumOfLocalAbsoluteSlopes = 0.0;
  88. for (integer iframe = 1; iframe < my nx; iframe ++) {
  89. double t1 = Sampled_indexToX (me, iframe);
  90. double t2 = t1 + my dx;
  91. bool localMeasurentIsValid = ( Pitch_isVoiced_t (thee, t1) && Pitch_isVoiced_t (thee, t2) );
  92. if (localMeasurentIsValid) {
  93. double absoluteLocalSlope = fabs (my z [1] [iframe + 1] - my z [1] [iframe]);
  94. sumOfLocalAbsoluteSlopes += absoluteLocalSlope;
  95. numberOfValidLocalMeasurements += 1;
  96. }
  97. }
  98. sumOfLocalAbsoluteSlopes /= my dx; // convert to dB per second
  99. return numberOfValidLocalMeasurements > 0 ? sumOfLocalAbsoluteSlopes / numberOfValidLocalMeasurements : undefined;
  100. }
  101. /* End of file Pitch_Intensity.cpp */