Artword_Speaker_to_Sound.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. /* Artword_Speaker_to_Sound.cpp
  2. *
  3. * Copyright (C) 1992-2005,2007,2008,2011,2012,2015-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 "Speaker_to_Delta.h"
  19. #include "Art_Speaker_Delta.h"
  20. #include "Artword_Speaker_to_Sound.h"
  21. #define Dymin 0.00001
  22. #define criticalVelocity 10.0
  23. #define noiseFactor 0.1
  24. #define MONITOR_SAMPLES 100
  25. /* While debugging, some of these can be 1; otherwise, they are all 0: */
  26. #define EQUAL_TUBE_WIDTHS 0
  27. #define CONSTANT_TUBE_LENGTHS 1
  28. #define NO_MOVING_WALLS 0
  29. #define NO_TURBULENCE 0
  30. #define NO_RADIATION_DAMPING 0
  31. #define NO_BERNOULLI_EFFECT 0
  32. #define MASS_LEAPFROG 0
  33. #define B91 0
  34. autoSound Artword_Speaker_to_Sound (Artword artword, Speaker speaker,
  35. double fsamp, int oversampling,
  36. autoSound *out_w1, int iw1, autoSound *out_w2, int iw2, autoSound *out_w3, int iw3,
  37. autoSound *out_p1, int ip1, autoSound *out_p2, int ip2, autoSound *out_p3, int ip3,
  38. autoSound *out_v1, int iv1, autoSound *out_v2, int iv2, autoSound *out_v3, int iv3)
  39. {
  40. try {
  41. autoSound result = Sound_createSimple (1, artword -> totalTime, fsamp);
  42. integer numberOfSamples = result -> nx;
  43. double minTract [1+78], maxTract [1+78]; // for drawing
  44. double Dt = 1.0 / fsamp / oversampling,
  45. rho0 = 1.14,
  46. c = 353.0,
  47. onebyc2 = 1.0 / (c * c),
  48. rho0c2 = rho0 * c * c,
  49. halfDt = 0.5 * Dt,
  50. twoDt = 2.0 * Dt,
  51. halfc2Dt = 0.5 * c * c * Dt,
  52. twoc2Dt = 2.0 * c * c * Dt,
  53. onebytworho0 = 1.0 / (2.0 * rho0),
  54. Dtbytworho0 = Dt / (2.0 * rho0);
  55. double tension, rrad, onebygrad, totalVolume;
  56. autoArt art = Art_create ();
  57. autoDelta delta = Speaker_to_Delta (speaker);
  58. autoMelderMonitor monitor (U"Articulatory synthesis");
  59. Artword_intoArt (artword, art.get(), 0.0);
  60. Art_Speaker_intoDelta (art.get(), speaker, delta.get());
  61. int M = delta -> numberOfTubes;
  62. autoSound w1, w2, w3, p1, p2, p3, v1, v2, v3;
  63. if (iw1 > 0 && iw1 <= M) w1 = Sound_createSimple (1, artword -> totalTime, fsamp); else iw1 = 0;
  64. if (iw2 > 0 && iw2 <= M) w2 = Sound_createSimple (1, artword -> totalTime, fsamp); else iw2 = 0;
  65. if (iw3 > 0 && iw3 <= M) w3 = Sound_createSimple (1, artword -> totalTime, fsamp); else iw3 = 0;
  66. if (ip1 > 0 && ip1 <= M) p1 = Sound_createSimple (1, artword -> totalTime, fsamp); else ip1 = 0;
  67. if (ip2 > 0 && ip2 <= M) p2 = Sound_createSimple (1, artword -> totalTime, fsamp); else ip2 = 0;
  68. if (ip3 > 0 && ip3 <= M) p3 = Sound_createSimple (1, artword -> totalTime, fsamp); else ip3 = 0;
  69. if (iv1 > 0 && iv1 <= M) v1 = Sound_createSimple (1, artword -> totalTime, fsamp); else iv1 = 0;
  70. if (iv2 > 0 && iv2 <= M) v2 = Sound_createSimple (1, artword -> totalTime, fsamp); else iv2 = 0;
  71. if (iv3 > 0 && iv3 <= M) v3 = Sound_createSimple (1, artword -> totalTime, fsamp); else iv3 = 0;
  72. /* Initialize drawing. */
  73. for (int i = 1; i <= 78; i ++) {
  74. minTract [i] = 100.0;
  75. maxTract [i] = -100.0;
  76. }
  77. totalVolume = 0.0;
  78. for (int m = 1; m <= M; m ++) {
  79. Delta_Tube t = delta->tube + m;
  80. if (! t -> left1 && ! t -> right1) continue;
  81. t->Dx = t->Dxeq; t->dDxdt = 0.0; // 5.113 (numbers refer to equations in Boersma (1998)
  82. t->Dy = t->Dyeq; t->dDydt = 0.0; // 5.113
  83. t->Dz = t->Dzeq; // 5.113
  84. t->A = t->Dz * ( t->Dy >= t->dy ? t->Dy + Dymin :
  85. t->Dy <= - t->dy ? Dymin :
  86. (t->dy + t->Dy) * (t->dy + t->Dy) / (4.0 * t->dy) + Dymin ); // 4.4, 4.5
  87. #if EQUAL_TUBE_WIDTHS
  88. t->A = 0.0001;
  89. #endif
  90. t->Jleft = t->Jright = 0.0; // 5.113
  91. t->Qleft = t->Qright = rho0c2; // 5.113
  92. t->pleft = t->pright = 0.0; // 5.114
  93. t->Kleft = t->Kright = 0.0; // 5.114
  94. t->V = t->A * t->Dx; // 5.114
  95. totalVolume += t->V;
  96. }
  97. //Melder_casual (U"Starting volume: ", totalVolume * 1000, U" litres.");
  98. for (integer sample = 1; sample <= numberOfSamples; sample ++) {
  99. double time = (sample - 1) / fsamp;
  100. Artword_intoArt (artword, art.get(), time);
  101. Art_Speaker_intoDelta (art.get(), speaker, delta.get());
  102. if (sample % MONITOR_SAMPLES == 0 && monitor.graphics()) { // because we can be in batch
  103. Graphics graphics = monitor.graphics();
  104. double area [1+78];
  105. for (int i = 1; i <= 78; i ++) {
  106. area [i] = delta -> tube [i]. A;
  107. if (area [i] < minTract [i]) minTract [i] = area [i];
  108. if (area [i] > maxTract [i]) maxTract [i] = area [i];
  109. }
  110. Graphics_beginMovieFrame (graphics, & Graphics_WHITE);
  111. Graphics_Viewport vp = Graphics_insetViewport (monitor.graphics(), 0.0, 0.5, 0.5, 1.0);
  112. Graphics_setWindow (graphics, 0.0, 1.0, 0.0, 0.05);
  113. Graphics_setColour (graphics, Graphics_RED);
  114. Graphics_function (graphics, minTract, 1, 35, 0.0, 0.9);
  115. Graphics_function (graphics, maxTract, 1, 35, 0.0, 0.9);
  116. Graphics_setColour (graphics, Graphics_BLACK);
  117. Graphics_function (graphics, area, 1, 35, 0.0, 0.9);
  118. Graphics_setLineType (graphics, Graphics_DOTTED);
  119. Graphics_line (graphics, 0.0, 0.0, 1.0, 0.0);
  120. Graphics_setLineType (graphics, Graphics_DRAWN);
  121. Graphics_resetViewport (graphics, vp);
  122. vp = Graphics_insetViewport (graphics, 0, 0.5, 0, 0.5);
  123. Graphics_setWindow (graphics, 0.0, 1.0, -0.000003, 0.00001);
  124. Graphics_setColour (graphics, Graphics_RED);
  125. Graphics_function (graphics, minTract, 36, 37, 0.2, 0.8);
  126. Graphics_function (graphics, maxTract, 36, 37, 0.2, 0.8);
  127. Graphics_setColour (graphics, Graphics_BLACK);
  128. Graphics_function (graphics, area, 36, 37, 0.2, 0.8);
  129. Graphics_setLineType (graphics, Graphics_DOTTED);
  130. Graphics_line (graphics, 0.0, 0.0, 1.0, 0.0);
  131. Graphics_setLineType (graphics, Graphics_DRAWN);
  132. Graphics_resetViewport (graphics, vp);
  133. vp = Graphics_insetViewport (graphics, 0.5, 1.0, 0.5, 1.0);
  134. Graphics_setWindow (graphics, 0.0, 1.0, 0.0, 0.001);
  135. Graphics_setColour (graphics, Graphics_RED);
  136. Graphics_function (graphics, minTract, 38, 64, 0.0, 1.0);
  137. Graphics_function (graphics, maxTract, 38, 64, 0.0, 1.0);
  138. Graphics_setColour (graphics, Graphics_BLACK);
  139. Graphics_function (graphics, area, 38, 64, 0.0, 1.0);
  140. Graphics_setLineType (graphics, Graphics_DOTTED);
  141. Graphics_line (graphics, 0.0, 0.0, 1.0, 0.0);
  142. Graphics_setLineType (graphics, Graphics_DRAWN);
  143. Graphics_resetViewport (graphics, vp);
  144. vp = Graphics_insetViewport (graphics, 0.5, 1.0, 0.0, 0.5);
  145. Graphics_setWindow (graphics, 0.0, 1.0, 0.001, 0.0);
  146. Graphics_setColour (graphics, Graphics_RED);
  147. Graphics_function (graphics, minTract, 65, 78, 0.5, 1.0);
  148. Graphics_function (graphics, maxTract, 65, 78, 0.5, 1.0);
  149. Graphics_setColour (graphics, Graphics_BLACK);
  150. Graphics_function (graphics, area, 65, 78, 0.5, 1.0);
  151. Graphics_setLineType (graphics, Graphics_DRAWN);
  152. Graphics_resetViewport (graphics, vp);
  153. Graphics_endMovieFrame (graphics, 0.0);
  154. Melder_monitor ((double) sample / numberOfSamples, U"Articulatory synthesis: ", Melder_half (time), U" seconds");
  155. }
  156. for (int n = 1; n <= oversampling; n ++) {
  157. for (int m = 1; m <= M; m ++) {
  158. Delta_Tube t = delta -> tube + m;
  159. if (! t -> left1 && ! t -> right1) continue;
  160. /* New geometry. */
  161. #if CONSTANT_TUBE_LENGTHS
  162. t->Dxnew = t->Dx;
  163. #else
  164. t->dDxdtnew = (t->dDxdt + Dt * 10000.0 * (t->Dxeq - t->Dx)) /
  165. (1.0 + 200.0 * Dt); // critical damping, 10 ms
  166. t->Dxnew = t->Dx + t->dDxdtnew * Dt;
  167. #endif
  168. /* 3-way: equal lengths. */
  169. /* This requires left tubes to be processed before right tubes. */
  170. if (t->left1 && t->left1->right2) t->Dxnew = t->left1->Dxnew;
  171. t->Dz = t->Dzeq; /* immediate... */
  172. t->eleft = (t->Qleft - t->Kleft) * t->V; // 5.115
  173. t->eright = (t->Qright - t->Kright) * t->V; // 5.115
  174. t->e = 0.5 * (t->eleft + t->eright); // 5.116
  175. t->p = 0.5 * (t->pleft + t->pright); // 5.116
  176. t->DeltaP = t->e / t->V - rho0c2; // 5.117
  177. t->v = t->p / (rho0 + onebyc2 * t->DeltaP); // 5.118
  178. {
  179. double dDy = t->Dyeq - t->Dy;
  180. double cubic = t->k3 * dDy * dDy;
  181. Delta_Tube l1 = t->left1, l2 = t->left2, r1 = t->right1, r2 = t->right2;
  182. tension = dDy * (t->k1 + cubic);
  183. t->B = 2.0 * t->Brel * sqrt (t->mass * (t->k1 + 3.0 * cubic));
  184. if (t->k1left1 != 0.0 && l1)
  185. tension += t->k1left1 * t->k1 * (dDy - (l1->Dyeq - l1->Dy));
  186. if (t->k1left2 != 0.0 && l2)
  187. tension += t->k1left2 * t->k1 * (dDy - (l2->Dyeq - l2->Dy));
  188. if (t->k1right1 != 0.0 && r1)
  189. tension += t->k1right1 * t->k1 * (dDy - (r1->Dyeq - r1->Dy));
  190. if (t->k1right2 != 0.0 && r2)
  191. tension += t->k1right2 * t->k1 * (dDy - (r2->Dyeq - r2->Dy));
  192. }
  193. if (t->Dy < t->dy) {
  194. if (t->Dy >= - t->dy) {
  195. double dDy = t->dy - t->Dy, dDy2 = dDy * dDy;
  196. tension += dDy2 / (4.0 * t->dy) * (t->s1 + 0.5 * t->s3 * dDy2);
  197. t->B += 2.0 * dDy / (2.0 * t->dy) *
  198. sqrt (t->mass * (t->s1 + t->s3 * dDy2));
  199. } else {
  200. tension -= t->Dy * (t->s1 + t->s3 * (t->Dy * t->Dy + t->dy * t->dy));
  201. t->B += 2.0 * sqrt (t->mass * (t->s1 + t->s3 * (3.0 * t->Dy * t->Dy + t->dy * t->dy)));
  202. }
  203. }
  204. t->dDydtnew = (t->dDydt + Dt / t->mass * (tension + 2.0 * t->DeltaP * t->Dz * t->Dx)) /
  205. (1.0 + t->B * Dt / t->mass); // 5.119
  206. t->Dynew = t->Dy + t->dDydtnew * Dt; // 5.119
  207. #if NO_MOVING_WALLS
  208. t->Dynew = t->Dy;
  209. #endif
  210. t->Anew = t->Dz * ( t->Dynew >= t->dy ? t->Dynew + Dymin :
  211. t->Dynew <= - t->dy ? Dymin :
  212. (t->dy + t->Dynew) * (t->dy + t->Dynew) / (4.0 * t->dy) + Dymin ); // 4.4, 4.5
  213. #if EQUAL_TUBE_WIDTHS
  214. t->Anew = 0.0001;
  215. #endif
  216. t->Ahalf = 0.5 * (t->A + t->Anew); // 5.120
  217. t->Dxhalf = 0.5 * (t->Dxnew + t->Dx); // 5.121
  218. t->Vnew = t->Anew * t->Dxnew; // 5.128
  219. { double oneByDyav = t->Dz / t->A;
  220. /*t->R = 12.0 * 1.86e-5 * t->parallel * t->parallel * oneByDyav * oneByDyav;*/
  221. if (t->Dy < 0.0)
  222. t->R = 12.0 * 1.86e-5 / (Dymin * Dymin + t->dy * t->dy);
  223. else
  224. t->R = 12.0 * 1.86e-5 * t->parallel * t->parallel /
  225. ((t->Dy + Dymin) * (t->Dy + Dymin) + t->dy * t->dy);
  226. t->R += 0.3 * t->parallel * oneByDyav; /* 5.23 */ }
  227. t->r = (1.0 + t->R * Dt / rho0) * t->Dxhalf / t->Anew; // 5.122
  228. t->ehalf = t->e + halfc2Dt * (t->Jleft - t->Jright); // 5.123
  229. t->phalf = (t->p + halfDt * (t->Qleft - t->Qright) / t->Dx) / (1.0 + Dtbytworho0 * t->R); // 5.123
  230. #if MASS_LEAPFROG
  231. t->ehalf = t->ehalfold + 2.0 * halfc2Dt * (t->Jleft - t->Jright);
  232. #endif
  233. t->Jhalf = t->phalf * t->Ahalf; // 5.124
  234. t->Qhalf = t->ehalf / (t->Ahalf * t->Dxhalf) + onebytworho0 * t->phalf * t->phalf; // 5.124
  235. #if NO_BERNOULLI_EFFECT
  236. t->Qhalf = t->ehalf / (t->Ahalf * t->Dxhalf);
  237. #endif
  238. }
  239. for (int m = 1; m <= M; m ++) { // compute Jleftnew and Qleftnew
  240. Delta_Tube l = delta->tube + m, r1 = l -> right1, r2 = l -> right2, r = r1;
  241. Delta_Tube l1 = l, l2 = r ? r -> left2 : nullptr;
  242. if (! l->left1) { // closed boundary at the left side (diaphragm)?
  243. if (! r) continue; // tube not connected at all
  244. l->Jleftnew = 0; // 5.132
  245. l->Qleftnew = (l->eleft - twoc2Dt * l->Jhalf) / l->Vnew; // 5.132
  246. }
  247. else // left boundary open to another tube will be handled...
  248. (void) 0; // ...together with the right boundary of the tube to the left
  249. if (! r) { // open boundary at the right side (lips, nostrils)?
  250. rrad = 1.0 - c * Dt / 0.02; // radiation resistance, 5.135
  251. onebygrad = 1.0 / (1.0 + c * Dt / 0.02); // radiation conductance, 5.135
  252. #if NO_RADIATION_DAMPING
  253. rrad = 0;
  254. onebygrad = 0;
  255. #endif
  256. l->prightnew = ((l->Dxhalf / Dt + c * onebygrad) * l->pright +
  257. 2.0 * ((l->Qhalf - rho0c2) - (l->Qright - rho0c2) * onebygrad)) /
  258. (l->r * l->Anew / Dt + c * onebygrad); // 5.136
  259. l->Jrightnew = l->prightnew * l->Anew; // 5.136
  260. l->Qrightnew = (rrad * (l->Qright - rho0c2) +
  261. c * (l->prightnew - l->pright)) * onebygrad + rho0c2; // 5.136
  262. } else if (! l2 && ! r2) { // two-way boundary
  263. if (l->v > criticalVelocity && l->A < r->A) {
  264. l->Pturbrightnew = -0.5 * rho0 * (l->v - criticalVelocity) *
  265. (1.0 - l->A / r->A) * (1.0 - l->A / r->A) * l->v;
  266. if (l->Pturbrightnew != 0.0)
  267. l->Pturbrightnew *= NUMrandomGauss (1.0, noiseFactor) /* * l->A */;
  268. }
  269. if (r->v < - criticalVelocity && r->A < l->A) {
  270. l->Pturbrightnew = 0.5 * rho0 * (r->v + criticalVelocity) *
  271. (1.0 - r->A / l->A) * (1.0 - r->A / l->A) * r->v;
  272. if (l->Pturbrightnew != 0.0)
  273. l->Pturbrightnew *= NUMrandomGauss (1.0, noiseFactor) /* * r->A */;
  274. }
  275. #if NO_TURBULENCE
  276. l->Pturbrightnew = 0.0;
  277. #endif
  278. l->Jrightnew = r->Jleftnew =
  279. (l->Dxhalf * l->pright + r->Dxhalf * r->pleft +
  280. twoDt * (l->Qhalf - r->Qhalf + l->Pturbright)) /
  281. (l->r + r->r); // 5.127
  282. #if B91
  283. l->Jrightnew = r->Jleftnew =
  284. (l->pright + r->pleft +
  285. 2.0 * twoDt * (l->Qhalf - r->Qhalf + l->Pturbright) / (l->Dxhalf + r->Dxhalf)) /
  286. (l->r / l->Dxhalf + r->r / r->Dxhalf);
  287. #endif
  288. l->prightnew = l->Jrightnew / l->Anew; // 5.128
  289. r->pleftnew = r->Jleftnew / r->Anew; // 5.128
  290. l->Krightnew = onebytworho0 * l->prightnew * l->prightnew; // 5.128
  291. r->Kleftnew = onebytworho0 * r->pleftnew * r->pleftnew; // 5.128
  292. #if NO_BERNOULLI_EFFECT
  293. l->Krightnew = r->Kleftnew = 0.0;
  294. #endif
  295. l->Qrightnew =
  296. (l->eright + r->eleft + twoc2Dt * (l->Jhalf - r->Jhalf)
  297. + l->Krightnew * l->Vnew + (r->Kleftnew - l->Pturbrightnew) * r->Vnew) /
  298. (l->Vnew + r->Vnew); // 5.131
  299. r->Qleftnew = l->Qrightnew + l->Pturbrightnew; // 5.131
  300. } else if (r2) { // two adjacent tubes at the right side (velic)
  301. r1->Jleftnew =
  302. (r1->Jleft * r1->Dxhalf * (1.0 / (l->A + r2->A) + 1.0 / r1->A) +
  303. twoDt * ((l->Ahalf * l->Qhalf + r2->Ahalf * r2->Qhalf ) / (l->Ahalf + r2->Ahalf) - r1->Qhalf)) /
  304. (1.0 / (1.0 / l->r + 1.0 / r2->r) + r1->r); // 5.138
  305. r2->Jleftnew =
  306. (r2->Jleft * r2->Dxhalf * (1.0 / (l->A + r1->A) + 1.0 / r2->A) +
  307. twoDt * ((l->Ahalf * l->Qhalf + r1->Ahalf * r1->Qhalf ) / (l->Ahalf + r1->Ahalf) - r2->Qhalf)) /
  308. (1.0 / (1.0 / l->r + 1.0 / r1->r) + r2->r); // 5.138
  309. l->Jrightnew = r1->Jleftnew + r2->Jleftnew; // 5.139
  310. l->prightnew = l->Jrightnew / l->Anew; // 5.128
  311. r1->pleftnew = r1->Jleftnew / r1->Anew; // 5.128
  312. r2->pleftnew = r2->Jleftnew / r2->Anew; // 5.128
  313. l->Krightnew = onebytworho0 * l->prightnew * l->prightnew; // 5.128
  314. r1->Kleftnew = onebytworho0 * r1->pleftnew * r1->pleftnew; // 5.128
  315. r2->Kleftnew = onebytworho0 * r2->pleftnew * r2->pleftnew; // 5.128
  316. #if NO_BERNOULLI_EFFECT
  317. l->Krightnew = r1->Kleftnew = r2->Kleftnew = 0;
  318. #endif
  319. l->Qrightnew = r1->Qleftnew = r2->Qleftnew =
  320. (l->eright + r1->eleft + r2->eleft + twoc2Dt * (l->Jhalf - r1->Jhalf - r2->Jhalf) +
  321. l->Krightnew * l->Vnew + r1->Kleftnew * r1->Vnew + r2->Kleftnew * r2->Vnew) /
  322. (l->Vnew + r1->Vnew + r2->Vnew); // 5.137
  323. } else {
  324. Melder_assert (l2 != nullptr);
  325. l1->Jrightnew =
  326. (l1->Jright * l1->Dxhalf * (1.0 / (r->A + l2->A) + 1.0 / l1->A) -
  327. twoDt * ((r->Ahalf * r->Qhalf + l2->Ahalf * l2->Qhalf ) / (r->Ahalf + l2->Ahalf) - l1->Qhalf)) /
  328. (1.0 / (1.0 / r->r + 1.0 / l2->r) + l1->r); // 5.138
  329. l2->Jrightnew =
  330. (l2->Jright * l2->Dxhalf * (1.0 / (r->A + l1->A) + 1.0 / l2->A) -
  331. twoDt * ((r->Ahalf * r->Qhalf + l1->Ahalf * l1->Qhalf ) / (r->Ahalf + l1->Ahalf) - l2->Qhalf)) /
  332. (1.0 / (1.0 / r->r + 1.0 / l1->r) + l2->r); // 5.138
  333. r->Jleftnew = l1->Jrightnew + l2->Jrightnew; // 5.139
  334. r->pleftnew = r->Jleftnew / r->Anew; // 5.128
  335. l1->prightnew = l1->Jrightnew / l1->Anew; // 5.128
  336. l2->prightnew = l2->Jrightnew / l2->Anew; // 5.128
  337. r->Kleftnew = onebytworho0 * r->pleftnew * r->pleftnew; // 5.128
  338. l1->Krightnew = onebytworho0 * l1->prightnew * l1->prightnew; // 5.128
  339. l2->Krightnew = onebytworho0 * l2->prightnew * l2->prightnew; // 5.128
  340. #if NO_BERNOULLI_EFFECT
  341. r->Kleftnew = l1->Krightnew = l2->Krightnew = 0.0;
  342. #endif
  343. r->Qleftnew = l1->Qrightnew = l2->Qrightnew =
  344. (r->eleft + l1->eright + l2->eright + twoc2Dt * (l1->Jhalf + l2->Jhalf - r->Jhalf) +
  345. r->Kleftnew * r->Vnew + l1->Krightnew * l1->Vnew + l2->Krightnew * l2->Vnew) /
  346. (r->Vnew + l1->Vnew + l2->Vnew); // 5.137
  347. }
  348. }
  349. /* Save some results. */
  350. if (n == (oversampling + 1) / 2) {
  351. double out = 0.0;
  352. for (int m = 1; m <= M; m ++) {
  353. Delta_Tube t = delta->tube + m;
  354. out += rho0 * t->Dx * t->Dz * t->dDydt * Dt * 1000.0; // radiation of wall movement, 5.140
  355. if (! t->right1)
  356. out += t->Jrightnew - t->Jright; // radiation of open tube end
  357. }
  358. result -> z [1] [sample] = out /= 4.0 * NUMpi * 0.4 * Dt; // at 0.4 metres
  359. if (iw1) w1 -> z [1] [sample] = delta->tube[iw1].Dy;
  360. if (iw2) w2 -> z [1] [sample] = delta->tube[iw2].Dy;
  361. if (iw3) w3 -> z [1] [sample] = delta->tube[iw3].Dy;
  362. if (ip1) p1 -> z [1] [sample] = delta->tube[ip1].DeltaP;
  363. if (ip2) p2 -> z [1] [sample] = delta->tube[ip2].DeltaP;
  364. if (ip3) p3 -> z [1] [sample] = delta->tube[ip3].DeltaP;
  365. if (iv1) v1 -> z [1] [sample] = delta->tube[iv1].v;
  366. if (iv2) v2 -> z [1] [sample] = delta->tube[iv2].v;
  367. if (iv3) v3 -> z [1] [sample] = delta->tube[iv3].v;
  368. }
  369. for (int m = 1; m <= M; m ++) {
  370. Delta_Tube t = delta->tube + m;
  371. t->Jleft = t->Jleftnew;
  372. t->Jright = t->Jrightnew;
  373. t->Qleft = t->Qleftnew;
  374. t->Qright = t->Qrightnew;
  375. t->Dy = t->Dynew;
  376. t->dDydt = t->dDydtnew;
  377. t->A = t->Anew;
  378. t->Dx = t->Dxnew;
  379. t->dDxdt = t->dDxdtnew;
  380. t->eleft = t->eleftnew;
  381. t->eright = t->erightnew;
  382. #if MASS_LEAPFROG
  383. t->ehalfold = t->ehalf;
  384. #endif
  385. t->pleft = t->pleftnew;
  386. t->pright = t->prightnew;
  387. t->Kleft = t->Kleftnew;
  388. t->Kright = t->Krightnew;
  389. t->V = t->Vnew;
  390. t->Pturbright = t->Pturbrightnew;
  391. }
  392. }
  393. }
  394. totalVolume = 0.0;
  395. for (int m = 1; m <= M; m ++)
  396. totalVolume += delta->tube [m]. V;
  397. //Melder_casual (U"Ending volume: ", totalVolume * 1000, U" litres.");
  398. if (out_w1) *out_w1 = w1.move();
  399. if (out_w2) *out_w2 = w2.move();
  400. if (out_w3) *out_w3 = w3.move();
  401. if (out_p1) *out_p1 = p1.move();
  402. if (out_p2) *out_p2 = p2.move();
  403. if (out_p3) *out_p3 = p3.move();
  404. if (out_v1) *out_v1 = v1.move();
  405. if (out_v2) *out_v2 = v2.move();
  406. if (out_v3) *out_v3 = v3.move();
  407. return result;
  408. } catch (MelderError) {
  409. Melder_throw (artword, U" & ", speaker, U": articulatory synthesis not performed.");
  410. }
  411. }
  412. /* End of file Artword_Speaker_to_Sound.cpp */