VocalTractTier.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /* VocalTractTier.cpp
  2. *
  3. * Copyright (C) 2012-2017 David Weenink
  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 "NUM2.h"
  19. #include "RealTier.h"
  20. #include "VocalTractTier.h"
  21. #include "oo_DESTROY.h"
  22. #include "VocalTractTier_def.h"
  23. #include "oo_COPY.h"
  24. #include "VocalTractTier_def.h"
  25. #include "oo_EQUAL.h"
  26. #include "VocalTractTier_def.h"
  27. #include "oo_CAN_WRITE_AS_ENCODING.h"
  28. #include "VocalTractTier_def.h"
  29. #include "oo_WRITE_TEXT.h"
  30. #include "VocalTractTier_def.h"
  31. #include "oo_READ_TEXT.h"
  32. #include "VocalTractTier_def.h"
  33. #include "oo_WRITE_BINARY.h"
  34. #include "VocalTractTier_def.h"
  35. #include "oo_READ_BINARY.h"
  36. #include "VocalTractTier_def.h"
  37. #include "oo_DESCRIPTION.h"
  38. #include "VocalTractTier_def.h"
  39. void VocalTract_drawSegments (VocalTract me, Graphics g, double maxLength, double maxArea, bool closedAtGlottis)
  40. {
  41. Graphics_setInner (g);
  42. double maxCrossection = sqrt (maxArea);
  43. Graphics_setWindow (g, 0.0, maxLength, -maxCrossection, maxCrossection);
  44. for (integer isection = 1; isection <= my nx; isection ++) {
  45. double x1 = (isection - 1.0) * my dx, x2 = x1 + my dx;
  46. double crosssection2 = sqrt (my z [1] [isection]);
  47. Graphics_line (g, x1, crosssection2, x2, crosssection2);
  48. Graphics_line (g, x1, -crosssection2, x2, -crosssection2);
  49. if (isection > 1) {
  50. double crosssection1 = sqrt (my z [1] [isection - 1]);
  51. Graphics_line (g, x1, crosssection1, x1, crosssection2);
  52. Graphics_line (g, x1, -crosssection1, x1, -crosssection2);
  53. } else if (isection == 1 and closedAtGlottis) {
  54. Graphics_line (g, x1, crosssection2, x1, -crosssection2);
  55. }
  56. }
  57. Graphics_unsetInner (g);
  58. }
  59. /***** VocalTractPoint *****/
  60. Thing_implement (VocalTractPoint, AnyPoint, 0);
  61. autoVocalTractPoint VocalTract_to_VocalTractPoint (VocalTract me, double time) {
  62. try {
  63. autoVocalTractPoint thee = Thing_new (VocalTractPoint);
  64. thy number = time;
  65. thy d_vocalTract = Data_copy (me);
  66. return thee;
  67. } catch (MelderError) {
  68. Melder_throw (me, U": not converted to VocalTractPoint.");
  69. }
  70. }
  71. /***** VocalTractTier *****/
  72. Thing_implement (VocalTractTier, Function, 0);
  73. autoVocalTractTier VocalTractTier_create (double fromTime, double toTime) {
  74. try {
  75. autoVocalTractTier me = Thing_new (VocalTractTier);
  76. Function_init (me.get(), fromTime, toTime);
  77. return me;
  78. } catch (MelderError) {
  79. Melder_throw (U": VocalTractTier not created.");
  80. }
  81. }
  82. autoVocalTractTier VocalTract_to_VocalTractTier (VocalTract me, double startTime, double endTime, double time) {
  83. try {
  84. autoVocalTractTier thee = VocalTractTier_create (startTime, endTime);
  85. VocalTractTier_addVocalTract_copy (thee.get(), time, me);
  86. return thee;
  87. } catch (MelderError) {
  88. Melder_throw (me, U": not converted to VocalTractTier");
  89. }
  90. }
  91. void VocalTractTier_addVocalTract_copy (VocalTractTier me, double time, VocalTract vocaltract) {
  92. try {
  93. autoVocalTractPoint thee = VocalTract_to_VocalTractPoint (vocaltract, time);
  94. if (my d_vocalTracts.size > 0) {
  95. VocalTractPoint vtp = my d_vocalTracts.at [1];
  96. integer numberOfSections = vtp -> d_vocalTract -> nx;
  97. if (numberOfSections != vocaltract -> nx) {
  98. Melder_throw (U"The number of sections should be equal to ", numberOfSections, U".");
  99. }
  100. }
  101. my d_vocalTracts. addItem_move (thee.move());
  102. } catch (MelderError) {
  103. Melder_throw (me, U": no VocalTract added.");
  104. }
  105. }
  106. autoVocalTract VocalTractTier_to_VocalTract (VocalTractTier me, double time) {
  107. try {
  108. Melder_assert (my d_vocalTracts.size > 0);
  109. VocalTractPoint vtp = my d_vocalTracts.at [1];
  110. integer numberOfSections = vtp -> d_vocalTract -> nx;
  111. autoVocalTract thee = VocalTract_create (numberOfSections, vtp -> d_vocalTract -> dx);
  112. for (integer isection = 1; isection <= numberOfSections; isection ++) {
  113. autoRealTier section = RealTier_create (my xmin, my xmax);
  114. for (integer i = 1; i <= my d_vocalTracts.size; i ++) {
  115. VocalTractPoint vtpi = my d_vocalTracts.at [i];
  116. double areai = vtpi -> d_vocalTract -> z [1] [isection];
  117. RealTier_addPoint (section.get(), vtpi -> number, areai);
  118. }
  119. thy z[1][isection] = RealTier_getValueAtTime (section.get(), time);
  120. }
  121. return thee;
  122. } catch (MelderError) {
  123. Melder_throw (me, U": no VocalTract created.");
  124. }
  125. }
  126. autoLPC VocalTractTier_to_LPC (VocalTractTier me, double timeStep) {
  127. try {
  128. if (my d_vocalTracts.size == 0) {
  129. Melder_throw (U"Empty VocalTractTier");
  130. }
  131. integer numberOfFrames = Melder_ifloor ((my xmax - my xmin) / timeStep);
  132. VocalTractPoint vtp = my d_vocalTracts.at [1];
  133. integer numberOfSections = vtp -> d_vocalTract -> nx;
  134. double samplingPeriod = 1.0 / (1000.0 * numberOfSections);
  135. autoNUMmatrix<double> area (1, numberOfFrames, 1, numberOfSections + 1);
  136. autoNUMvector<double> areavec (1, numberOfSections + 1);
  137. autoLPC thee = LPC_create (my xmin, my xmax, numberOfFrames, timeStep, timeStep / 2.0, numberOfSections, samplingPeriod);
  138. // interpolate each section
  139. for (integer isection = 1; isection <= numberOfSections; isection ++) {
  140. autoRealTier sectioni = RealTier_create (my xmin, my xmax);
  141. for (integer i = 1; i <= my d_vocalTracts.size; i ++) {
  142. VocalTractPoint vtpi = my d_vocalTracts.at [i];
  143. double areai = vtpi -> d_vocalTract -> z [1] [isection];
  144. RealTier_addPoint (sectioni.get(), vtpi -> number, areai);
  145. }
  146. for (integer iframe = 1; iframe <= numberOfFrames; iframe ++) {
  147. double time = thy x1 + (iframe - 1) * thy dx;
  148. area [iframe] [isection] = RealTier_getValueAtTime (sectioni.get(), time);
  149. area [iframe] [numberOfSections + 1] = 0.0001; // normalisation is area[n+1] = 0.0001
  150. }
  151. }
  152. for (integer iframe = 1; iframe <= numberOfFrames; iframe ++) {
  153. LPC_Frame frame = & thy d_frames [iframe];
  154. LPC_Frame_init (frame, numberOfSections);
  155. for (integer i = 1; i <= numberOfSections + 1; i ++) {
  156. areavec [i] = area [iframe] [numberOfSections + 1 - i];
  157. }
  158. NUMlpc_area_to_lpc (areavec.peek(), numberOfSections + 1, frame -> a.at);
  159. frame -> gain = 1e-6; // something
  160. }
  161. return thee;
  162. } catch (MelderError) {
  163. Melder_throw (U": not converted to LPC.");
  164. }
  165. }
  166. /* End of file VocalTractTier.cpp */