VocalTract.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /* VocalTract.cpp
  2. *
  3. * Copyright (C) 1992-2012,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 "VocalTract.h"
  19. Thing_implement (VocalTract, Vector, 2);
  20. void structVocalTract :: v_info () {
  21. structDaata :: v_info ();
  22. MelderInfo_writeLine (U"Vocal tract length: ", Melder_single (xmax), U" metres");
  23. MelderInfo_writeLine (U"Number of sections: ", nx);
  24. MelderInfo_writeLine (U"Section length: ", Melder_single (dx), U" metres");
  25. }
  26. autoVocalTract VocalTract_create (integer nx, double dx) {
  27. try {
  28. autoVocalTract me = Thing_new (VocalTract);
  29. Matrix_init (me.get(), 0.0, nx * dx, nx, dx, 0.5 * dx, 1.0, 1.0, 1, 1.0, 1.0);
  30. return me;
  31. } catch (MelderError) {
  32. Melder_throw (U"VocalTract not created.");
  33. }
  34. }
  35. namespace theVocalTract {
  36. constexpr double minimumWidth { 0.0001 };
  37. struct { conststring32 phone; int numberOfSections; double area [40]; }
  38. data [] = {
  39. { U"a", 34, { 1.7, 1.2, 1.6, 3.39, 2.1, 1.4, 1, 0.8, 0.8, 0.8, 1, 1.4,
  40. 2.1, 2.9, 3.09, 2.1, 2.5, 4, 5.3, 6.16, 7, 7.6, 8.15, 8.5, 8.6,
  41. 8.4, 8, 7.5, 6.9, 6, 5.1, 5, 5.5, 7.9 } },
  42. { U"e", 33, { 2.3, 1.95, 1.73, 1.7, 5.3, 6.3, 6.8, 7.55, 8.2, 9.1, 9.7,
  43. 10.1, 10.2, 10, 8, 7.2, 7.5, 6.4, 5.4, 4.9, 4.35, 3.9, 3.5, 3.1,
  44. 2.7, 2.4, 2.2, 2.5, 3.4, 5, 6.7, 8.5, 10 } },
  45. { U"i", 35, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55,
  46. 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3,
  47. 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 5, 8 } },
  48. { U"o", 37, { 2.6, 2.05, 1.56, 1.3, 5.2, 4.54, 3.49, 2.6, 2.1, 1.8, 1.6, 1.4,
  49. 1.29, 1.19, 1.22, 2.6, 2.9, 2.2, 2.6, 3.6, 4.55, 5.55, 6.4, 7.15,
  50. 8, 8.9, 9.6, 10.5, 11.8, 14.6, 14.5, 12.9, 10.4, 5, 3.4, 3.4, 4 } },
  51. { U"u", 40, { 2.5, 2.5, 2.5, 2.4, 5, 8.1, 8.9, 8.9, 8.4, 7.5, 5.8, 3.9, 2.3, 1.6, 1.2,
  52. 1.05, 1.1, 1.4, 2.2, 2, 1.3, 2, 2.2, 2.3, 2.8, 3.7, 5, 6.2, 7.9,
  53. 10.9, 12.9, 13.15, 13, 12.5, 9.9, 3.9, 1.8, 0.32, 0.4, 0.6 } },
  54. { U"y1", 37, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55,
  55. 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3,
  56. 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 1.8, 0.32,
  57. 0.4, 0.6 } },
  58. { U"y2", 38, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55,
  59. 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3,
  60. 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 4, 1.8, 0.32,
  61. 0.4, 0.6 } },
  62. { U"y3", 39, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55,
  63. 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3,
  64. 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 4, 4, 1.8, 0.32,
  65. 0.4, 0.6 } },
  66. { U"jery", 38, { 3.2, 3.2, 3.2, 3.2, 10.5, 10.5, 13, 13, 10.5, 10.5, 10.5, 10.5, 10.5,
  67. 8, 6.5, 6.5, 5, 4, 2, 2.6, 1.6, 1.3, 1, 1, 1.3, 1.6, 2, 2, 2.6, 3.2, 5,
  68. 8, 8, 8, 6.5,
  69. 2, 6.5, 6.5 } },
  70. { U"p", 39, { 3.5, 3.2, 2.9, 2.6, 6.9, 6.65, 5.8, 4.9, 4, 3.14, 2.5, 1.84,
  71. 1.25, 0.83, 0.6, 0.53,
  72. 0.5, 0.6, 0.85, 1, 1.6, 2.05, 2.55, 3.08, 3.67, 4.15, 4.8, 5.5, 6.3,
  73. 7.4, 12, 12.98, 12.9, 11.4, 6.6, 2, 0.45, 0.1, minimumWidth } },
  74. { U"t", 36, { 2.8, 2.7, 2.4, 2.6, 6.45, 6.01, 5.31, 4.85, 4.55, 4.32, 4.18, 4.1,
  75. 4.04, 3.97, 3.85, 3.7, 3.4, 3.05, 2.91, 3.1, 3.55, 3.9, 4.1, 4, 3.8,
  76. 3.3, 2.55, 1.8, 1, 0.45, 0.1, minimumWidth, 0.8, 2.5, 6, 9 } },
  77. { U"k", 38, { 2.4, 2.7, 3, 3.3, 7, 9.38, 9.25, 8.62, 7.8, 6.7, 5.4, 4, 2.8, 1.9, 1.35,
  78. 0.9, 0.55, 0.3, 0.19, 0.07, minimumWidth, 0.12, 0.17, 0.3, 0.5, 0.9,
  79. 1.4, 2.2, 3.3, 5, 9, 11.25, 10.9, 7.3, 4.3, 3.5, 3.7, 6 } },
  80. { U"x", 40, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  81. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 } },
  82. { U"pa", 39, { 1.7, 1.2, 1.6, 3.39, 2.1, 1.4, 1, 0.8, 0.8, 0.8, 1, 1.4,
  83. 2.1, 2.9, 3.09, 2.1, 2.5, 4, 5.3, 6.16, 7, 7.6, 8.15, 8.5, 8.6,
  84. 8.4, 8, 7.5, 6.9, 6, 5.1, 5, 5.5, 7.9, 6.6, 2, 0.45, 0.1,
  85. minimumWidth } },
  86. { U"ta", 34, { 1.7, 1.2, 1.6, 3.39, 2.1, 1.4, 1, 0.8, 0.8, 0.8, 1, 1.4,
  87. 2.1, 2.9, 3.09, 2.1, 2.5, 4, 5.3, 6.16, 7, 7.6, 8.15, 8.5, 8.6,
  88. 8.5, 6, 2, 0.45, minimumWidth, 0.8, 2.5, 5.5, 7.9 } },
  89. { U"ka", 34, { 1.7, 1.2, 1.6, 3.39, 2.1, 1.4, 1, 0.8, 0.8, 0.8, 1, 1.4,
  90. 2.1, 2.9, 3.09, 2.1, 0.3, minimumWidth,
  91. 0.3, 2, 5, 7.6, 8.15, 8.5, 8.6,
  92. 8.4, 8, 7.5, 6.9, 6, 5.1, 5, 5.5, 7.9 } },
  93. { U"pi", 39, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55,
  94. 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3,
  95. 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 5,
  96. 6.6, 2, 0.45, 0.1, minimumWidth } },
  97. { U"ti", 35, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55,
  98. 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3,
  99. 0.9, 0.65, 0.55, 0.5, 0.5, 0.5, 0.3, 0.1, minimumWidth,
  100. 0.8, 2.5, 8 } },
  101. { U"ki", 35, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55,
  102. 10.9, 11.15, 11.3, 11.2, 10.8, 8, 6, 2, 0.3, minimumWidth, 0.3, 1.3,
  103. 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 5, 8 } },
  104. { U"pu", 40, { 2.5, 2.5, 2.5, 2.4, 5, 8.1, 8.9, 8.9, 8.4, 7.5, 5.8, 3.9, 2.3, 1.6, 1.2,
  105. 1.05, 1.1, 1.4, 2.2, 2, 1.3, 2, 2.2, 2.3, 2.8, 3.7, 5, 6.2, 7.9,
  106. 10.9, 12.9, 13.15, 13, 12.5, 9.9, 6.6, 2, 0.45, 0.1, minimumWidth } },
  107. { U"tu", 40, { 2.5, 2.5, 2.5, 2.4, 5, 8.1, 8.9, 8.9, 8.4, 7.5, 5.8, 3.9, 2.3, 1.6, 1.2,
  108. 1.05, 1.1, 1.4, 2.2, 2, 1.3, 2, 2.2, 2.3, 2.8, 3.7, 5, 6.2, 7.9,
  109. 10.9, 9, 3, 0.4, minimumWidth, 0.8, 2.5, 1.8, 0.32, 0.4, 0.6 } },
  110. { U"ku", 40, { 2.5, 2.5, 2.5, 2.4, 5, 8.1, 8.9, 8.9, 8.4, 7.5, 5.8, 3.9, 2.3, 1.6, 1.2,
  111. 1.05, 1.1, 1.4, 1.2, 0.3, minimumWidth, 0.3, 2.2, 2.3, 2.8, 3.7, 5, 6.2, 7.9,
  112. 10.9, 12.9, 13.15, 13, 12.5, 9.9, 3.9, 1.8, 0.32, 0.4, 0.6 } },
  113. { nullptr, 0, { 0 } } };
  114. }
  115. autoVocalTract VocalTract_createFromPhone (conststring32 phone) {
  116. try {
  117. int i = 0;
  118. for (;; i ++) {
  119. if (! theVocalTract::data [i]. phone)
  120. Melder_throw (U"Unknown phone ", phone);
  121. if (Melder_equ (theVocalTract::data [i]. phone, phone))
  122. break;
  123. }
  124. autoVocalTract me = VocalTract_create (theVocalTract::data [i]. numberOfSections, 0.005);
  125. for (int isection = 1; isection <= my nx; isection ++)
  126. my z [1] [isection] = theVocalTract::data [i]. area [isection - 1] * 0.0001;
  127. return me;
  128. } catch (MelderError) {
  129. Melder_throw (U"VocalTract not created from phone.");
  130. }
  131. }
  132. void VocalTract_draw (VocalTract me, Graphics g) {
  133. Matrix_drawRows (me, g, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
  134. }
  135. autoMatrix VocalTract_to_Matrix (VocalTract me) {
  136. try {
  137. autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1);
  138. NUMvector_copyElements (my z [1], thy z [1], 1, my nx);
  139. return thee;
  140. } catch (MelderError) {
  141. Melder_throw (me, U": not converted to Matrix.");
  142. }
  143. }
  144. autoVocalTract Matrix_to_VocalTract (Matrix me) {
  145. try {
  146. autoVocalTract thee = VocalTract_create (my nx, my dx);
  147. NUMvector_copyElements (my z [1], thy z [1], 1, my nx);
  148. return thee;
  149. } catch (MelderError) {
  150. Melder_throw (me, U": not converted to VocalTract.");
  151. }
  152. }
  153. /* End of file VocalTract.cpp */