eSpeak NG is an open source speech synthesizer that supports more than hundred languages and accents.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wavegen.c 45KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701
  1. /*
  2. * Copyright (C) 2005 to 2013 by Jonathan Duddington
  3. * email: [email protected]
  4. * Copyright (C) 2015-2016 Reece H. Dunn
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, see: <http://www.gnu.org/licenses/>.
  18. */
  19. // this version keeps wavemult window as a constant fraction
  20. // of the cycle length - but that spreads out the HF peaks too much
  21. #include "config.h"
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <math.h>
  26. #if HAVE_STDINT_H
  27. #include <stdint.h>
  28. #endif
  29. #include "espeak_ng.h"
  30. #include "speak_lib.h"
  31. #include "speech.h"
  32. #include "phoneme.h"
  33. #include "synthesize.h"
  34. #include "voice.h"
  35. #if HAVE_SONIC_H
  36. #include "sonic.h"
  37. #endif
  38. #ifdef USE_PORTAUDIO
  39. #include "portaudio.h"
  40. #undef USE_PORTAUDIO
  41. // determine portaudio version by looking for a #define which is not in V18
  42. #ifdef paNeverDropInput
  43. #define USE_PORTAUDIO 19
  44. #else
  45. #define USE_PORTAUDIO 18
  46. #endif
  47. #endif
  48. #include "sintab.h"
  49. #define PI 3.1415927
  50. #define PI2 6.283185307
  51. #define N_WAV_BUF 10
  52. voice_t *wvoice;
  53. FILE *f_log = NULL;
  54. int option_waveout = 0;
  55. static int option_harmonic1 = 10;
  56. static int flutter_amp = 64;
  57. static int general_amplitude = 60;
  58. static int consonant_amp = 26;
  59. int embedded_value[N_EMBEDDED_VALUES];
  60. static int PHASE_INC_FACTOR;
  61. int samplerate = 0; // this is set by Wavegeninit()
  62. int samplerate_native = 0;
  63. extern int option_device_number;
  64. extern int option_quiet;
  65. static wavegen_peaks_t peaks[N_PEAKS];
  66. static int peak_harmonic[N_PEAKS];
  67. static int peak_height[N_PEAKS];
  68. int echo_head;
  69. int echo_tail;
  70. int echo_amp = 0;
  71. short echo_buf[N_ECHO_BUF];
  72. static int echo_length = 0; // period (in sample\) to ensure completion of echo at the end of speech, set in WavegenSetEcho()
  73. static int voicing;
  74. static RESONATOR rbreath[N_PEAKS];
  75. static int harm_sqrt_n = 0;
  76. #define N_LOWHARM 30
  77. static int harm_inc[N_LOWHARM]; // only for these harmonics do we interpolate amplitude between steps
  78. static int *harmspect;
  79. static int hswitch = 0;
  80. static int hspect[2][MAX_HARMONIC]; // 2 copies, we interpolate between then
  81. static int max_hval = 0;
  82. static int nsamples = 0; // number to do
  83. static int modulation_type = 0;
  84. static int glottal_flag = 0;
  85. static int glottal_reduce = 0;
  86. WGEN_DATA wdata;
  87. static int amp_ix;
  88. static int amp_inc;
  89. static unsigned char *amplitude_env = NULL;
  90. static int samplecount = 0; // number done
  91. static int samplecount_start = 0; // count at start of this segment
  92. static int end_wave = 0; // continue to end of wave cycle
  93. static int wavephase;
  94. static int phaseinc;
  95. static int cycle_samples; // number of samples in a cycle at current pitch
  96. static int cbytes;
  97. static int hf_factor;
  98. static double minus_pi_t;
  99. static double two_pi_t;
  100. unsigned char *out_ptr;
  101. unsigned char *out_start;
  102. unsigned char *out_end;
  103. int outbuf_size = 0;
  104. // the queue of operations passed to wavegen from sythesize
  105. intptr_t wcmdq[N_WCMDQ][4];
  106. int wcmdq_head = 0;
  107. int wcmdq_tail = 0;
  108. // pitch,speed,
  109. int embedded_default[N_EMBEDDED_VALUES] = { 0, 50, 175, 100, 50, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0 };
  110. static int embedded_max[N_EMBEDDED_VALUES] = { 0, 0x7fff, 750, 300, 99, 99, 99, 0, 750, 0, 0, 0, 0, 4, 0 };
  111. int current_source_index = 0;
  112. extern FILE *f_wave;
  113. #if (USE_PORTAUDIO == 18)
  114. static PortAudioStream *pa_stream = NULL;
  115. #endif
  116. #if (USE_PORTAUDIO == 19)
  117. static PaStream *pa_stream = NULL;
  118. #endif
  119. #if HAVE_SONIC_H
  120. static sonicStream sonicSpeedupStream = NULL;
  121. double sonicSpeed = 1.0;
  122. #endif
  123. // 1st index=roughness
  124. // 2nd index=modulation_type
  125. // value: bits 0-3 amplitude (16ths), bits 4-7 every n cycles
  126. #define N_ROUGHNESS 8
  127. static unsigned char modulation_tab[N_ROUGHNESS][8] = {
  128. { 0, 0x00, 0x00, 0x00, 0, 0x46, 0xf2, 0x29 },
  129. { 0, 0x2f, 0x00, 0x2f, 0, 0x45, 0xf2, 0x29 },
  130. { 0, 0x2f, 0x00, 0x2e, 0, 0x45, 0xf2, 0x28 },
  131. { 0, 0x2e, 0x00, 0x2d, 0, 0x34, 0xf2, 0x28 },
  132. { 0, 0x2d, 0x2d, 0x2c, 0, 0x34, 0xf2, 0x28 },
  133. { 0, 0x2b, 0x2b, 0x2b, 0, 0x34, 0xf2, 0x28 },
  134. { 0, 0x2a, 0x2a, 0x2a, 0, 0x34, 0xf2, 0x28 },
  135. { 0, 0x29, 0x29, 0x29, 0, 0x34, 0xf2, 0x28 },
  136. };
  137. // Flutter table, to add natural variations to the pitch
  138. #define N_FLUTTER 0x170
  139. static int Flutter_inc;
  140. static const unsigned char Flutter_tab[N_FLUTTER] = {
  141. 0x80, 0x9b, 0xb5, 0xcb, 0xdc, 0xe8, 0xed, 0xec,
  142. 0xe6, 0xdc, 0xce, 0xbf, 0xb0, 0xa3, 0x98, 0x90,
  143. 0x8c, 0x8b, 0x8c, 0x8f, 0x92, 0x94, 0x95, 0x92,
  144. 0x8c, 0x83, 0x78, 0x69, 0x59, 0x49, 0x3c, 0x31,
  145. 0x2a, 0x29, 0x2d, 0x36, 0x44, 0x56, 0x69, 0x7d,
  146. 0x8f, 0x9f, 0xaa, 0xb1, 0xb2, 0xad, 0xa4, 0x96,
  147. 0x87, 0x78, 0x69, 0x5c, 0x53, 0x4f, 0x4f, 0x55,
  148. 0x5e, 0x6b, 0x7a, 0x88, 0x96, 0xa2, 0xab, 0xb0,
  149. 0xb1, 0xae, 0xa8, 0xa0, 0x98, 0x91, 0x8b, 0x88,
  150. 0x89, 0x8d, 0x94, 0x9d, 0xa8, 0xb2, 0xbb, 0xc0,
  151. 0xc1, 0xbd, 0xb4, 0xa5, 0x92, 0x7c, 0x63, 0x4a,
  152. 0x32, 0x1e, 0x0e, 0x05, 0x02, 0x05, 0x0f, 0x1e,
  153. 0x30, 0x44, 0x59, 0x6d, 0x7f, 0x8c, 0x96, 0x9c,
  154. 0x9f, 0x9f, 0x9d, 0x9b, 0x99, 0x99, 0x9c, 0xa1,
  155. 0xa9, 0xb3, 0xbf, 0xca, 0xd5, 0xdc, 0xe0, 0xde,
  156. 0xd8, 0xcc, 0xbb, 0xa6, 0x8f, 0x77, 0x60, 0x4b,
  157. 0x3a, 0x2e, 0x28, 0x29, 0x2f, 0x3a, 0x48, 0x59,
  158. 0x6a, 0x7a, 0x86, 0x90, 0x94, 0x95, 0x91, 0x89,
  159. 0x80, 0x75, 0x6b, 0x62, 0x5c, 0x5a, 0x5c, 0x61,
  160. 0x69, 0x74, 0x80, 0x8a, 0x94, 0x9a, 0x9e, 0x9d,
  161. 0x98, 0x90, 0x86, 0x7c, 0x71, 0x68, 0x62, 0x60,
  162. 0x63, 0x6b, 0x78, 0x88, 0x9b, 0xaf, 0xc2, 0xd2,
  163. 0xdf, 0xe6, 0xe7, 0xe2, 0xd7, 0xc6, 0xb2, 0x9c,
  164. 0x84, 0x6f, 0x5b, 0x4b, 0x40, 0x39, 0x37, 0x38,
  165. 0x3d, 0x43, 0x4a, 0x50, 0x54, 0x56, 0x55, 0x52,
  166. 0x4d, 0x48, 0x42, 0x3f, 0x3e, 0x41, 0x49, 0x56,
  167. 0x67, 0x7c, 0x93, 0xab, 0xc3, 0xd9, 0xea, 0xf6,
  168. 0xfc, 0xfb, 0xf4, 0xe7, 0xd5, 0xc0, 0xaa, 0x94,
  169. 0x80, 0x71, 0x64, 0x5d, 0x5a, 0x5c, 0x61, 0x68,
  170. 0x70, 0x77, 0x7d, 0x7f, 0x7f, 0x7b, 0x74, 0x6b,
  171. 0x61, 0x57, 0x4e, 0x48, 0x46, 0x48, 0x4e, 0x59,
  172. 0x66, 0x75, 0x84, 0x93, 0x9f, 0xa7, 0xab, 0xaa,
  173. 0xa4, 0x99, 0x8b, 0x7b, 0x6a, 0x5b, 0x4e, 0x46,
  174. 0x43, 0x45, 0x4d, 0x5a, 0x6b, 0x7f, 0x92, 0xa6,
  175. 0xb8, 0xc5, 0xcf, 0xd3, 0xd2, 0xcd, 0xc4, 0xb9,
  176. 0xad, 0xa1, 0x96, 0x8e, 0x89, 0x87, 0x87, 0x8a,
  177. 0x8d, 0x91, 0x92, 0x91, 0x8c, 0x84, 0x78, 0x68,
  178. 0x55, 0x41, 0x2e, 0x1c, 0x0e, 0x05, 0x01, 0x05,
  179. 0x0f, 0x1f, 0x34, 0x4d, 0x68, 0x81, 0x9a, 0xb0,
  180. 0xc1, 0xcd, 0xd3, 0xd3, 0xd0, 0xc8, 0xbf, 0xb5,
  181. 0xab, 0xa4, 0x9f, 0x9c, 0x9d, 0xa0, 0xa5, 0xaa,
  182. 0xae, 0xb1, 0xb0, 0xab, 0xa3, 0x96, 0x87, 0x76,
  183. 0x63, 0x51, 0x42, 0x36, 0x2f, 0x2d, 0x31, 0x3a,
  184. 0x48, 0x59, 0x6b, 0x7e, 0x8e, 0x9c, 0xa6, 0xaa,
  185. 0xa9, 0xa3, 0x98, 0x8a, 0x7b, 0x6c, 0x5d, 0x52,
  186. 0x4a, 0x48, 0x4a, 0x50, 0x5a, 0x67, 0x75, 0x82
  187. };
  188. // waveform shape table for HF peaks, formants 6,7,8
  189. #define N_WAVEMULT 128
  190. static int wavemult_offset = 0;
  191. static int wavemult_max = 0;
  192. // the presets are for 22050 Hz sample rate.
  193. // A different rate will need to recalculate the presets in WavegenInit()
  194. static unsigned char wavemult[N_WAVEMULT] = {
  195. 0, 0, 0, 2, 3, 5, 8, 11, 14, 18, 22, 27, 32, 37, 43, 49,
  196. 55, 62, 69, 76, 83, 90, 98, 105, 113, 121, 128, 136, 144, 152, 159, 166,
  197. 174, 181, 188, 194, 201, 207, 213, 218, 224, 228, 233, 237, 240, 244, 246, 249,
  198. 251, 252, 253, 253, 253, 253, 252, 251, 249, 246, 244, 240, 237, 233, 228, 224,
  199. 218, 213, 207, 201, 194, 188, 181, 174, 166, 159, 152, 144, 136, 128, 121, 113,
  200. 105, 98, 90, 83, 76, 69, 62, 55, 49, 43, 37, 32, 27, 22, 18, 14,
  201. 11, 8, 5, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  202. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  203. };
  204. // set from y = pow(2,x) * 128, x=-1 to 1
  205. unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1] = {
  206. 64, 65, 66, 67, 68, 69, 70, 71,
  207. 72, 73, 74, 75, 76, 77, 78, 79,
  208. 80, 81, 82, 83, 84, 86, 87, 88,
  209. 89, 91, 92, 93, 94, 96, 97, 98,
  210. 100, 101, 103, 104, 105, 107, 108, 110,
  211. 111, 113, 115, 116, 118, 119, 121, 123,
  212. 124, 126, 128, 130, 132, 133, 135, 137,
  213. 139, 141, 143, 145, 147, 149, 151, 153,
  214. 155, 158, 160, 162, 164, 167, 169, 171,
  215. 174, 176, 179, 181, 184, 186, 189, 191,
  216. 194, 197, 199, 202, 205, 208, 211, 214,
  217. 217, 220, 223, 226, 229, 232, 236, 239,
  218. 242, 246, 249, 252, 254, 255
  219. };
  220. void WcmdqStop()
  221. {
  222. wcmdq_head = 0;
  223. wcmdq_tail = 0;
  224. #if HAVE_SONIC_H
  225. if (sonicSpeedupStream != NULL) {
  226. sonicDestroyStream(sonicSpeedupStream);
  227. sonicSpeedupStream = NULL;
  228. }
  229. #endif
  230. #ifdef USE_PORTAUDIO
  231. Pa_AbortStream(pa_stream);
  232. #endif
  233. if (mbrola_name[0] != 0)
  234. MbrolaReset();
  235. }
  236. int WcmdqFree()
  237. {
  238. int i;
  239. i = wcmdq_head - wcmdq_tail;
  240. if (i <= 0) i += N_WCMDQ;
  241. return i;
  242. }
  243. int WcmdqUsed()
  244. {
  245. return N_WCMDQ - WcmdqFree();
  246. }
  247. void WcmdqInc()
  248. {
  249. wcmdq_tail++;
  250. if (wcmdq_tail >= N_WCMDQ) wcmdq_tail = 0;
  251. }
  252. static void WcmdqIncHead()
  253. {
  254. wcmdq_head++;
  255. if (wcmdq_head >= N_WCMDQ) wcmdq_head = 0;
  256. }
  257. #define PEAKSHAPEW 256
  258. unsigned char pk_shape1[PEAKSHAPEW+1] = {
  259. 255, 254, 254, 254, 254, 254, 253, 253, 252, 251, 251, 250, 249, 248, 247, 246,
  260. 245, 244, 242, 241, 239, 238, 236, 234, 233, 231, 229, 227, 225, 223, 220, 218,
  261. 216, 213, 211, 209, 207, 205, 203, 201, 199, 197, 195, 193, 191, 189, 187, 185,
  262. 183, 180, 178, 176, 173, 171, 169, 166, 164, 161, 159, 156, 154, 151, 148, 146,
  263. 143, 140, 138, 135, 132, 129, 126, 123, 120, 118, 115, 112, 108, 105, 102, 99,
  264. 96, 95, 93, 91, 90, 88, 86, 85, 83, 82, 80, 79, 77, 76, 74, 73,
  265. 72, 70, 69, 68, 67, 66, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55,
  266. 55, 54, 53, 52, 52, 51, 50, 50, 49, 48, 48, 47, 47, 46, 46, 46,
  267. 45, 45, 45, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 44, 43,
  268. 42, 42, 41, 40, 40, 39, 38, 38, 37, 36, 36, 35, 35, 34, 33, 33,
  269. 32, 32, 31, 30, 30, 29, 29, 28, 28, 27, 26, 26, 25, 25, 24, 24,
  270. 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 18, 17, 17, 16,
  271. 16, 15, 15, 15, 14, 14, 13, 13, 13, 12, 12, 11, 11, 11, 10, 10,
  272. 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 5, 5,
  273. 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2,
  274. 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  275. 0
  276. };
  277. static unsigned char pk_shape2[PEAKSHAPEW+1] = {
  278. 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253, 253, 253, 252, 252,
  279. 252, 251, 251, 251, 250, 250, 249, 249, 248, 248, 247, 247, 246, 245, 245, 244,
  280. 243, 243, 242, 241, 239, 237, 235, 233, 231, 229, 227, 225, 223, 221, 218, 216,
  281. 213, 211, 208, 205, 203, 200, 197, 194, 191, 187, 184, 181, 178, 174, 171, 167,
  282. 163, 160, 156, 152, 148, 144, 140, 136, 132, 127, 123, 119, 114, 110, 105, 100,
  283. 96, 94, 91, 88, 86, 83, 81, 78, 76, 74, 71, 69, 66, 64, 62, 60,
  284. 57, 55, 53, 51, 49, 47, 44, 42, 40, 38, 36, 34, 32, 30, 29, 27,
  285. 25, 23, 21, 19, 18, 16, 14, 12, 11, 9, 7, 6, 4, 3, 1, 0,
  286. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  287. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  288. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  289. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  290. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  291. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  292. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  293. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  294. 0
  295. };
  296. static unsigned char *pk_shape;
  297. #ifdef USE_PORTAUDIO
  298. // PortAudio interface
  299. static int userdata[4];
  300. static PaError pa_init_err = 0;
  301. static int out_channels = 1;
  302. unsigned char *outbuffer = NULL;
  303. int outbuffer_size = 0;
  304. #if USE_PORTAUDIO == 18
  305. static int WaveCallback(void *inputBuffer, void *outputBuffer,
  306. unsigned long framesPerBuffer, PaTimestamp outTime, void *userData)
  307. #else
  308. static int WaveCallback(const void *inputBuffer, void *outputBuffer,
  309. long unsigned int framesPerBuffer, const PaStreamCallbackTimeInfo *outTime,
  310. PaStreamCallbackFlags flags, void *userData)
  311. #endif
  312. {
  313. (void)inputBuffer; // unused
  314. (void)outTime; // unused
  315. (void)userData; // unused
  316. int ix;
  317. int result;
  318. unsigned char *p;
  319. unsigned char *out_buf;
  320. unsigned char *out_end2;
  321. int pa_size;
  322. pa_size = framesPerBuffer*2;
  323. // make a buffer 3x size of the portaudio output
  324. ix = pa_size*3;
  325. if (ix > outbuffer_size) {
  326. outbuffer = (unsigned char *)realloc(outbuffer, ix);
  327. if (outbuffer == NULL) {
  328. fprintf(stderr, "espeak: out of memory\n");
  329. }
  330. outbuffer_size = ix;
  331. out_ptr = NULL;
  332. }
  333. if (out_ptr == NULL) {
  334. out_ptr = out_start = outbuffer;
  335. out_end = out_start + outbuffer_size;
  336. }
  337. out_end2 = &outbuffer[pa_size]; // top of data needed for the portaudio buffer
  338. event_list_ix = 0;
  339. result = WavegenFill();
  340. // copy from the outbut buffer into the portaudio buffer
  341. if (result && (out_ptr > out_end2))
  342. result = 0; // don't end yet, there is more data in the buffer than can fit in portaudio
  343. while (out_ptr < out_end2)
  344. *out_ptr++ = 0; // fill with zeros up to the size of the portaudio buffer
  345. memcpy(outputBuffer, outbuffer, pa_size);
  346. // move the remaining contents of the start of the output buffer
  347. for (p = out_end2; p < out_end; p++)
  348. p[-pa_size] = p[0];
  349. out_ptr -= pa_size;
  350. count_samples += framesPerBuffer;
  351. if (synth_callback) {
  352. // synchronous-playback mode, allow the calling process to abort the speech
  353. event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list
  354. event_list[event_list_ix].user_data = 0;
  355. if (synth_callback(NULL, 0, event_list) == 1) {
  356. SpeakNextClause(NULL, NULL, 2); // stop speaking
  357. result = 1;
  358. }
  359. }
  360. #ifdef ARCH_BIG
  361. // swap the order of bytes in each sound sample in the portaudio buffer
  362. int c;
  363. unsigned char *buf_end;
  364. out_buf = (unsigned char *)outputBuffer;
  365. buf_end = out_buf + framesPerBuffer*2;
  366. while (out_buf < buf_end) {
  367. c = out_buf[0];
  368. out_buf[0] = out_buf[1];
  369. out_buf[1] = c;
  370. out_buf += 2;
  371. }
  372. #endif
  373. if (out_channels == 2) {
  374. // sound output can only do stereo, not mono. Duplicate each sound sample to
  375. // produce 2 channels.
  376. out_buf = (unsigned char *)outputBuffer;
  377. for (ix = framesPerBuffer-1; ix >= 0; ix--) {
  378. p = &out_buf[ix*4];
  379. p[3] = p[1] = out_buf[ix*2 + 1];
  380. p[2] = p[0] = out_buf[ix*2];
  381. }
  382. }
  383. #if USE_PORTAUDIO == 18
  384. #ifdef PLATFORM_WINDOWS
  385. return result;
  386. #endif
  387. if (result != 0) {
  388. static int end_timer = 0;
  389. if (end_timer == 0)
  390. end_timer = 4;
  391. if (end_timer > 0) {
  392. end_timer--;
  393. if (end_timer == 0)
  394. return 1;
  395. }
  396. }
  397. return 0;
  398. #else
  399. return result;
  400. #endif
  401. }
  402. #if USE_PORTAUDIO == 19
  403. /* This is a fixed version of Pa_OpenDefaultStream() for use if the version in portaudio V19
  404. is broken */
  405. static PaError Pa_OpenDefaultStream2(PaStream **stream,
  406. int inputChannelCount,
  407. int outputChannelCount,
  408. PaSampleFormat sampleFormat,
  409. double sampleRate,
  410. unsigned long framesPerBuffer,
  411. PaStreamCallback *streamCallback,
  412. void *userData)
  413. {
  414. PaError result;
  415. PaStreamParameters hostApiOutputParameters;
  416. if (option_device_number >= 0)
  417. hostApiOutputParameters.device = option_device_number;
  418. else
  419. hostApiOutputParameters.device = Pa_GetDefaultOutputDevice();
  420. if (hostApiOutputParameters.device == paNoDevice)
  421. return paDeviceUnavailable;
  422. hostApiOutputParameters.channelCount = outputChannelCount;
  423. hostApiOutputParameters.sampleFormat = sampleFormat;
  424. /* defaultHighOutputLatency is used below instead of
  425. defaultLowOutputLatency because it is more important for the default
  426. stream to work reliably than it is for it to work with the lowest
  427. latency.
  428. */
  429. hostApiOutputParameters.suggestedLatency =
  430. Pa_GetDeviceInfo(hostApiOutputParameters.device)->defaultHighOutputLatency;
  431. hostApiOutputParameters.hostApiSpecificStreamInfo = NULL;
  432. result = Pa_OpenStream(
  433. stream, NULL, &hostApiOutputParameters, sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData);
  434. return result;
  435. }
  436. #endif
  437. int WavegenOpenSound()
  438. {
  439. PaError err, err2;
  440. PaError active;
  441. if (option_waveout || option_quiet) {
  442. // writing to WAV file, not to portaudio
  443. return 0;
  444. }
  445. #if USE_PORTAUDIO == 18
  446. active = Pa_StreamActive(pa_stream);
  447. #else
  448. active = Pa_IsStreamActive(pa_stream);
  449. #endif
  450. if (active == 1)
  451. return 0;
  452. if (active < 0) {
  453. out_channels = 1;
  454. #if USE_PORTAUDIO == 18
  455. err2 = Pa_OpenDefaultStream(&pa_stream, 0, 1, paInt16, samplerate, 512, N_WAV_BUF, WaveCallback, (void *)userdata);
  456. if (err2 == paInvalidChannelCount) {
  457. // failed to open with mono, try stereo
  458. out_channels = 2;
  459. err2 = Pa_OpenDefaultStream(&pa_stream, 0, 2, paInt16, samplerate, 512, N_WAV_BUF, WaveCallback, (void *)userdata);
  460. }
  461. #else
  462. err2 = Pa_OpenDefaultStream2(&pa_stream, 0, 1, paInt16, (double)samplerate, 512, WaveCallback, (void *)userdata);
  463. if (err2 == paInvalidChannelCount) {
  464. // failed to open with mono, try stereo
  465. out_channels = 2;
  466. err2 = Pa_OpenDefaultStream(&pa_stream, 0, 2, paInt16, (double)samplerate, 512, WaveCallback, (void *)userdata);
  467. }
  468. #endif
  469. }
  470. err = Pa_StartStream(pa_stream);
  471. #if USE_PORTAUDIO == 19
  472. if (err == paStreamIsNotStopped) {
  473. // not sure why we need this, but PA v19 seems to need it
  474. err = Pa_StopStream(pa_stream);
  475. err = Pa_StartStream(pa_stream);
  476. }
  477. #endif
  478. if (err != paNoError) {
  479. // exit speak if we can't open the sound device - this is OK if speak is being run for each utterance
  480. exit(2);
  481. }
  482. return 0;
  483. }
  484. int WavegenCloseSound()
  485. {
  486. PaError active;
  487. // check whether speaking has finished, and close the stream
  488. if (pa_stream != NULL) {
  489. #if USE_PORTAUDIO == 18
  490. active = Pa_StreamActive(pa_stream);
  491. #else
  492. active = Pa_IsStreamActive(pa_stream);
  493. #endif
  494. if (WcmdqUsed() == 0) { // also check that the queue is empty
  495. if (active == 0) {
  496. Pa_CloseStream(pa_stream);
  497. pa_stream = NULL;
  498. return 1;
  499. }
  500. } else
  501. WavegenOpenSound(); // still items in the queue, shouldn't be closed
  502. }
  503. return 0;
  504. }
  505. int WavegenInitSound()
  506. {
  507. PaError err;
  508. if (option_quiet)
  509. return 0;
  510. // PortAudio sound output library
  511. err = Pa_Initialize();
  512. pa_init_err = err;
  513. if (err != paNoError) {
  514. fprintf(stderr, "Failed to initialise the PortAudio sound\n");
  515. return 1;
  516. }
  517. return 0;
  518. }
  519. #else
  520. int WavegenOpenSound()
  521. {
  522. return 0;
  523. }
  524. int WavegenCloseSound()
  525. {
  526. return 0;
  527. }
  528. int WavegenInitSound()
  529. {
  530. return 0;
  531. }
  532. #endif
  533. void WavegenInit(int rate, int wavemult_fact)
  534. {
  535. int ix;
  536. double x;
  537. if (wavemult_fact == 0)
  538. wavemult_fact = 60; // default
  539. wvoice = NULL;
  540. samplerate = samplerate_native = rate;
  541. PHASE_INC_FACTOR = 0x8000000 / samplerate; // assumes pitch is Hz*32
  542. Flutter_inc = (64 * samplerate)/rate;
  543. samplecount = 0;
  544. nsamples = 0;
  545. wavephase = 0x7fffffff;
  546. max_hval = 0;
  547. wdata.amplitude = 32;
  548. wdata.amplitude_fmt = 100;
  549. for (ix = 0; ix < N_EMBEDDED_VALUES; ix++)
  550. embedded_value[ix] = embedded_default[ix];
  551. // set up window to generate a spread of harmonics from a
  552. // single peak for HF peaks
  553. wavemult_max = (samplerate * wavemult_fact)/(256 * 50);
  554. if (wavemult_max > N_WAVEMULT) wavemult_max = N_WAVEMULT;
  555. wavemult_offset = wavemult_max/2;
  556. if (samplerate != 22050) {
  557. // wavemult table has preset values for 22050 Hz, we only need to
  558. // recalculate them if we have a different sample rate
  559. for (ix = 0; ix < wavemult_max; ix++) {
  560. x = 127*(1.0 - cos(PI2*ix/wavemult_max));
  561. wavemult[ix] = (int)x;
  562. }
  563. }
  564. pk_shape = pk_shape2;
  565. #ifdef INCLUDE_KLATT
  566. KlattInit();
  567. #endif
  568. }
  569. int GetAmplitude(void)
  570. {
  571. int amp;
  572. // normal, none, reduced, moderate, strong
  573. static const unsigned char amp_emphasis[5] = { 16, 16, 10, 16, 22 };
  574. amp = (embedded_value[EMBED_A])*55/100;
  575. general_amplitude = amp * amp_emphasis[embedded_value[EMBED_F]] / 16;
  576. return general_amplitude;
  577. }
  578. static void WavegenSetEcho(void)
  579. {
  580. int delay;
  581. int amp;
  582. voicing = wvoice->voicing;
  583. delay = wvoice->echo_delay;
  584. amp = wvoice->echo_amp;
  585. if (delay >= N_ECHO_BUF)
  586. delay = N_ECHO_BUF-1;
  587. if (amp > 100)
  588. amp = 100;
  589. memset(echo_buf, 0, sizeof(echo_buf));
  590. echo_tail = 0;
  591. if (embedded_value[EMBED_H] > 0) {
  592. // set echo from an embedded command in the text
  593. amp = embedded_value[EMBED_H];
  594. delay = 130;
  595. }
  596. if (delay == 0)
  597. amp = 0;
  598. echo_head = (delay * samplerate)/1000;
  599. echo_length = echo_head; // ensure completion of echo at the end of speech. Use 1 delay period?
  600. if (amp == 0)
  601. echo_length = 0;
  602. if (amp > 20)
  603. echo_length = echo_head * 2; // perhaps allow 2 echo periods if the echo is loud.
  604. // echo_amp units are 1/256ths of the amplitude of the original sound.
  605. echo_amp = amp;
  606. // compensate (partially) for increase in amplitude due to echo
  607. general_amplitude = GetAmplitude();
  608. general_amplitude = ((general_amplitude * (500-amp))/500);
  609. }
  610. int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
  611. {
  612. // Calculate the amplitude of each harmonics from the formants
  613. // Only for formants 0 to 5
  614. // control 0=initial call, 1=every 64 cycles
  615. // pitch and freqs are Hz<<16
  616. int f;
  617. wavegen_peaks_t *p;
  618. int fp; // centre freq of peak
  619. int fhi; // high freq of peak
  620. int h; // harmonic number
  621. int pk;
  622. int hmax;
  623. int hmax_samplerate; // highest harmonic allowed for the samplerate
  624. int x;
  625. int ix;
  626. int h1;
  627. // initialise as much of *out as we will need
  628. if (wvoice == NULL)
  629. return 1;
  630. hmax = (peaks[wvoice->n_harmonic_peaks].freq + peaks[wvoice->n_harmonic_peaks].right)/pitch;
  631. if (hmax >= MAX_HARMONIC)
  632. hmax = MAX_HARMONIC-1;
  633. // restrict highest harmonic to half the samplerate
  634. hmax_samplerate = (((samplerate * 19)/40) << 16)/pitch; // only 95% of Nyquist freq
  635. if (hmax > hmax_samplerate)
  636. hmax = hmax_samplerate;
  637. for (h = 0; h <= hmax; h++)
  638. htab[h] = 0;
  639. h = 0;
  640. for (pk = 0; pk <= wvoice->n_harmonic_peaks; pk++) {
  641. p = &peaks[pk];
  642. if ((p->height == 0) || (fp = p->freq) == 0)
  643. continue;
  644. fhi = p->freq + p->right;
  645. h = ((p->freq - p->left) / pitch) + 1;
  646. if (h <= 0) h = 1;
  647. for (f = pitch*h; f < fp; f += pitch)
  648. htab[h++] += pk_shape[(fp-f)/(p->left>>8)] * p->height;
  649. for (; f < fhi; f += pitch)
  650. htab[h++] += pk_shape[(f-fp)/(p->right>>8)] * p->height;
  651. }
  652. int y;
  653. int h2;
  654. // increase bass
  655. y = peaks[1].height * 10; // addition as a multiple of 1/256s
  656. h2 = (1000<<16)/pitch; // decrease until 1000Hz
  657. if (h2 > 0) {
  658. x = y/h2;
  659. h = 1;
  660. while (y > 0) {
  661. htab[h++] += y;
  662. y -= x;
  663. }
  664. }
  665. // find the nearest harmonic for HF peaks where we don't use shape
  666. for (; pk < N_PEAKS; pk++) {
  667. x = peaks[pk].height >> 14;
  668. peak_height[pk] = (x * x * 5)/2;
  669. // find the nearest harmonic for HF peaks where we don't use shape
  670. if (control == 0) {
  671. // set this initially, but make changes only at the quiet point
  672. peak_harmonic[pk] = peaks[pk].freq / pitch;
  673. }
  674. // only use harmonics up to half the samplerate
  675. if (peak_harmonic[pk] >= hmax_samplerate)
  676. peak_height[pk] = 0;
  677. }
  678. // convert from the square-rooted values
  679. f = 0;
  680. for (h = 0; h <= hmax; h++, f += pitch) {
  681. x = htab[h] >> 15;
  682. htab[h] = (x * x) >> 8;
  683. if ((ix = (f >> 19)) < N_TONE_ADJUST)
  684. htab[h] = (htab[h] * wvoice->tone_adjust[ix]) >> 13; // index tone_adjust with Hz/8
  685. }
  686. // adjust the amplitude of the first harmonic, affects tonal quality
  687. h1 = htab[1] * option_harmonic1;
  688. htab[1] = h1/8;
  689. // calc intermediate increments of LF harmonics
  690. if (control & 1) {
  691. for (h = 1; h < N_LOWHARM; h++)
  692. harm_inc[h] = (htab[h] - harmspect[h]) >> 3;
  693. }
  694. return hmax; // highest harmonic number
  695. }
  696. static void AdvanceParameters()
  697. {
  698. // Called every 64 samples to increment the formant freq, height, and widths
  699. int x;
  700. int ix;
  701. static int Flutter_ix = 0;
  702. // advance the pitch
  703. wdata.pitch_ix += wdata.pitch_inc;
  704. if ((ix = wdata.pitch_ix>>8) > 127) ix = 127;
  705. x = wdata.pitch_env[ix] * wdata.pitch_range;
  706. wdata.pitch = (x>>8) + wdata.pitch_base;
  707. amp_ix += amp_inc;
  708. /* add pitch flutter */
  709. if (Flutter_ix >= (N_FLUTTER*64))
  710. Flutter_ix = 0;
  711. x = ((int)(Flutter_tab[Flutter_ix >> 6])-0x80) * flutter_amp;
  712. Flutter_ix += Flutter_inc;
  713. wdata.pitch += x;
  714. if (wdata.pitch < 102400)
  715. wdata.pitch = 102400; // min pitch, 25 Hz (25 << 12)
  716. if (samplecount == samplecount_start)
  717. return;
  718. for (ix = 0; ix <= wvoice->n_harmonic_peaks; ix++) {
  719. peaks[ix].freq1 += peaks[ix].freq_inc;
  720. peaks[ix].freq = (int)peaks[ix].freq1;
  721. peaks[ix].height1 += peaks[ix].height_inc;
  722. if ((peaks[ix].height = (int)peaks[ix].height1) < 0)
  723. peaks[ix].height = 0;
  724. peaks[ix].left1 += peaks[ix].left_inc;
  725. peaks[ix].left = (int)peaks[ix].left1;
  726. if (ix < 3) {
  727. peaks[ix].right1 += peaks[ix].right_inc;
  728. peaks[ix].right = (int)peaks[ix].right1;
  729. } else
  730. peaks[ix].right = peaks[ix].left;
  731. }
  732. for (; ix < 8; ix++) {
  733. // formants 6,7,8 don't have a width parameter
  734. if (ix < 7) {
  735. peaks[ix].freq1 += peaks[ix].freq_inc;
  736. peaks[ix].freq = (int)peaks[ix].freq1;
  737. }
  738. peaks[ix].height1 += peaks[ix].height_inc;
  739. if ((peaks[ix].height = (int)peaks[ix].height1) < 0)
  740. peaks[ix].height = 0;
  741. }
  742. }
  743. static double resonator(RESONATOR *r, double input)
  744. {
  745. double x;
  746. x = r->a * input + r->b * r->x1 + r->c * r->x2;
  747. r->x2 = r->x1;
  748. r->x1 = x;
  749. return x;
  750. }
  751. static void setresonator(RESONATOR *rp, int freq, int bwidth, int init)
  752. {
  753. // freq Frequency of resonator in Hz
  754. // bwidth Bandwidth of resonator in Hz
  755. // init Initialize internal data
  756. double x;
  757. double arg;
  758. if (init) {
  759. rp->x1 = 0;
  760. rp->x2 = 0;
  761. }
  762. arg = minus_pi_t * bwidth;
  763. x = exp(arg);
  764. rp->c = -(x * x);
  765. arg = two_pi_t * freq;
  766. rp->b = x * cos(arg) * 2.0;
  767. rp->a = 1.0 - rp->b - rp->c;
  768. }
  769. void InitBreath(void)
  770. {
  771. int ix;
  772. minus_pi_t = -PI / samplerate;
  773. two_pi_t = -2.0 * minus_pi_t;
  774. for (ix = 0; ix < N_PEAKS; ix++)
  775. setresonator(&rbreath[ix], 2000, 200, 1);
  776. }
  777. static void SetBreath()
  778. {
  779. int pk;
  780. if (wvoice->breath[0] == 0)
  781. return;
  782. for (pk = 1; pk < N_PEAKS; pk++) {
  783. if (wvoice->breath[pk] != 0) {
  784. // breath[0] indicates that some breath formants are needed
  785. // set the freq from the current ynthesis formant and the width from the voice data
  786. setresonator(&rbreath[pk], peaks[pk].freq >> 16, wvoice->breathw[pk], 0);
  787. }
  788. }
  789. }
  790. static int ApplyBreath(void)
  791. {
  792. int value = 0;
  793. int noise;
  794. int ix;
  795. int amp;
  796. // use two random numbers, for alternate formants
  797. noise = (rand() & 0x3fff) - 0x2000;
  798. for (ix = 1; ix < N_PEAKS; ix++) {
  799. if ((amp = wvoice->breath[ix]) != 0) {
  800. amp *= (peaks[ix].height >> 14);
  801. value += (int)resonator(&rbreath[ix], noise) * amp;
  802. }
  803. }
  804. return value;
  805. }
  806. int Wavegen()
  807. {
  808. unsigned short waveph;
  809. unsigned short theta;
  810. int total;
  811. int h;
  812. int ix;
  813. int z, z1, z2;
  814. int echo;
  815. int ov;
  816. static int maxh, maxh2;
  817. int pk;
  818. signed char c;
  819. int sample;
  820. int amp;
  821. int modn_amp = 1, modn_period;
  822. static int agc = 256;
  823. static int h_switch_sign = 0;
  824. static int cycle_count = 0;
  825. static int amplitude2 = 0; // adjusted for pitch
  826. // continue until the output buffer is full, or
  827. // the required number of samples have been produced
  828. for (;;) {
  829. if ((end_wave == 0) && (samplecount == nsamples))
  830. return 0;
  831. if ((samplecount & 0x3f) == 0) {
  832. // every 64 samples, adjust the parameters
  833. if (samplecount == 0) {
  834. hswitch = 0;
  835. harmspect = hspect[0];
  836. maxh2 = PeaksToHarmspect(peaks, wdata.pitch<<4, hspect[0], 0);
  837. // adjust amplitude to compensate for fewer harmonics at higher pitch
  838. amplitude2 = (wdata.amplitude * (wdata.pitch >> 8) * wdata.amplitude_fmt)/(10000 << 3);
  839. // switch sign of harmonics above about 900Hz, to reduce max peak amplitude
  840. h_switch_sign = 890 / (wdata.pitch >> 12);
  841. } else
  842. AdvanceParameters();
  843. // pitch is Hz<<12
  844. phaseinc = (wdata.pitch>>7) * PHASE_INC_FACTOR;
  845. cycle_samples = samplerate/(wdata.pitch >> 12); // sr/(pitch*2)
  846. hf_factor = wdata.pitch >> 11;
  847. maxh = maxh2;
  848. harmspect = hspect[hswitch];
  849. hswitch ^= 1;
  850. maxh2 = PeaksToHarmspect(peaks, wdata.pitch<<4, hspect[hswitch], 1);
  851. SetBreath();
  852. } else if ((samplecount & 0x07) == 0) {
  853. for (h = 1; h < N_LOWHARM && h <= maxh2 && h <= maxh; h++)
  854. harmspect[h] += harm_inc[h];
  855. // bring automctic gain control back towards unity
  856. if (agc < 256) agc++;
  857. }
  858. samplecount++;
  859. if (wavephase > 0) {
  860. wavephase += phaseinc;
  861. if (wavephase < 0) {
  862. // sign has changed, reached a quiet point in the waveform
  863. cbytes = wavemult_offset - (cycle_samples)/2;
  864. if (samplecount > nsamples)
  865. return 0;
  866. cycle_count++;
  867. for (pk = wvoice->n_harmonic_peaks+1; pk < N_PEAKS; pk++) {
  868. // find the nearest harmonic for HF peaks where we don't use shape
  869. peak_harmonic[pk] = ((peaks[pk].freq / (wdata.pitch*8)) + 1) / 2;
  870. }
  871. // adjust amplitude to compensate for fewer harmonics at higher pitch
  872. amplitude2 = (wdata.amplitude * (wdata.pitch >> 8) * wdata.amplitude_fmt)/(10000 << 3);
  873. if (glottal_flag > 0) {
  874. if (glottal_flag == 3) {
  875. if ((nsamples-samplecount) < (cycle_samples*2)) {
  876. // Vowel before glottal-stop.
  877. // This is the start of the penultimate cycle, reduce its amplitude
  878. glottal_flag = 2;
  879. amplitude2 = (amplitude2 * glottal_reduce)/256;
  880. }
  881. } else if (glottal_flag == 4) {
  882. // Vowel following a glottal-stop.
  883. // This is the start of the second cycle, reduce its amplitude
  884. glottal_flag = 2;
  885. amplitude2 = (amplitude2 * glottal_reduce)/256;
  886. } else
  887. glottal_flag--;
  888. }
  889. if (amplitude_env != NULL) {
  890. // amplitude envelope is only used for creaky voice effect on certain vowels/tones
  891. if ((ix = amp_ix>>8) > 127) ix = 127;
  892. amp = amplitude_env[ix];
  893. amplitude2 = (amplitude2 * amp)/128;
  894. }
  895. // introduce roughness into the sound by reducing the amplitude of
  896. modn_period = 0;
  897. if (voice->roughness < N_ROUGHNESS) {
  898. modn_period = modulation_tab[voice->roughness][modulation_type];
  899. modn_amp = modn_period & 0xf;
  900. modn_period = modn_period >> 4;
  901. }
  902. if (modn_period != 0) {
  903. if (modn_period == 0xf) {
  904. // just once */
  905. amplitude2 = (amplitude2 * modn_amp)/16;
  906. modulation_type = 0;
  907. } else {
  908. // reduce amplitude every [modn_period} cycles
  909. if ((cycle_count % modn_period) == 0)
  910. amplitude2 = (amplitude2 * modn_amp)/16;
  911. }
  912. }
  913. }
  914. } else
  915. wavephase += phaseinc;
  916. waveph = (unsigned short)(wavephase >> 16);
  917. total = 0;
  918. // apply HF peaks, formants 6,7,8
  919. // add a single harmonic and then spread this my multiplying by a
  920. // window. This is to reduce the processing power needed to add the
  921. // higher frequence harmonics.
  922. cbytes++;
  923. if (cbytes >= 0 && cbytes < wavemult_max) {
  924. for (pk = wvoice->n_harmonic_peaks+1; pk < N_PEAKS; pk++) {
  925. theta = peak_harmonic[pk] * waveph;
  926. total += (long)sin_tab[theta >> 5] * peak_height[pk];
  927. }
  928. // spread the peaks by multiplying by a window
  929. total = (long)(total / hf_factor) * wavemult[cbytes];
  930. }
  931. // apply main peaks, formants 0 to 5
  932. #ifdef USE_ASSEMBLER_1
  933. // use an optimised routine for this loop, if available
  934. total += AddSineWaves(waveph, h_switch_sign, maxh, harmspect); // call an assembler code routine
  935. #else
  936. theta = waveph;
  937. for (h = 1; h <= h_switch_sign; h++) {
  938. total += ((int)sin_tab[theta >> 5] * harmspect[h]);
  939. theta += waveph;
  940. }
  941. while (h <= maxh) {
  942. total -= ((int)sin_tab[theta >> 5] * harmspect[h]);
  943. theta += waveph;
  944. h++;
  945. }
  946. #endif
  947. if (voicing != 64)
  948. total = (total >> 6) * voicing;
  949. if (wvoice->breath[0])
  950. total += ApplyBreath();
  951. // mix with sampled wave if required
  952. z2 = 0;
  953. if (wdata.mix_wavefile_ix < wdata.n_mix_wavefile) {
  954. if (wdata.mix_wave_scale == 0) {
  955. // a 16 bit sample
  956. c = wdata.mix_wavefile[wdata.mix_wavefile_ix+wdata.mix_wavefile_offset+1];
  957. sample = wdata.mix_wavefile[wdata.mix_wavefile_ix+wdata.mix_wavefile_offset] + (c * 256);
  958. wdata.mix_wavefile_ix += 2;
  959. } else {
  960. // a 8 bit sample, scaled
  961. sample = (signed char)wdata.mix_wavefile[wdata.mix_wavefile_offset+wdata.mix_wavefile_ix++] * wdata.mix_wave_scale;
  962. }
  963. z2 = (sample * wdata.amplitude_v) >> 10;
  964. z2 = (z2 * wdata.mix_wave_amp)/32;
  965. if ((wdata.mix_wavefile_ix + wdata.mix_wavefile_offset) >= wdata.mix_wavefile_max) // reached the end of available WAV data
  966. wdata.mix_wavefile_offset -= (wdata.mix_wavefile_max*3)/4;
  967. }
  968. z1 = z2 + (((total>>8) * amplitude2) >> 13);
  969. echo = (echo_buf[echo_tail++] * echo_amp);
  970. z1 += echo >> 8;
  971. if (echo_tail >= N_ECHO_BUF)
  972. echo_tail = 0;
  973. z = (z1 * agc) >> 8;
  974. // check for overflow, 16bit signed samples
  975. if (z >= 32768) {
  976. ov = 8388608/z1 - 1; // 8388608 is 2^23, i.e. max value * 256
  977. if (ov < agc) agc = ov; // set agc to number of 1/256ths to multiply the sample by
  978. z = (z1 * agc) >> 8; // reduce sample by agc value to prevent overflow
  979. } else if (z <= -32768) {
  980. ov = -8388608/z1 - 1;
  981. if (ov < agc) agc = ov;
  982. z = (z1 * agc) >> 8;
  983. }
  984. *out_ptr++ = z;
  985. *out_ptr++ = z >> 8;
  986. echo_buf[echo_head++] = z;
  987. if (echo_head >= N_ECHO_BUF)
  988. echo_head = 0;
  989. if (out_ptr >= out_end)
  990. return 1;
  991. }
  992. }
  993. static int PlaySilence(int length, int resume)
  994. {
  995. static int n_samples;
  996. int value = 0;
  997. nsamples = 0;
  998. samplecount = 0;
  999. wavephase = 0x7fffffff;
  1000. if (length == 0)
  1001. return 0;
  1002. if (resume == 0)
  1003. n_samples = length;
  1004. while (n_samples-- > 0) {
  1005. value = (echo_buf[echo_tail++] * echo_amp) >> 8;
  1006. if (echo_tail >= N_ECHO_BUF)
  1007. echo_tail = 0;
  1008. *out_ptr++ = value;
  1009. *out_ptr++ = value >> 8;
  1010. echo_buf[echo_head++] = value;
  1011. if (echo_head >= N_ECHO_BUF)
  1012. echo_head = 0;
  1013. if (out_ptr >= out_end)
  1014. return 1;
  1015. }
  1016. return 0;
  1017. }
  1018. static int PlayWave(int length, int resume, unsigned char *data, int scale, int amp)
  1019. {
  1020. static int n_samples;
  1021. static int ix = 0;
  1022. int value;
  1023. signed char c;
  1024. if (resume == 0) {
  1025. n_samples = length;
  1026. ix = 0;
  1027. }
  1028. nsamples = 0;
  1029. samplecount = 0;
  1030. while (n_samples-- > 0) {
  1031. if (scale == 0) {
  1032. // 16 bits data
  1033. c = data[ix+1];
  1034. value = data[ix] + (c * 256);
  1035. ix += 2;
  1036. } else {
  1037. // 8 bit data, shift by the specified scale factor
  1038. value = (signed char)data[ix++] * scale;
  1039. }
  1040. value *= (consonant_amp * general_amplitude); // reduce strength of consonant
  1041. value = value >> 10;
  1042. value = (value * amp)/32;
  1043. value += ((echo_buf[echo_tail++] * echo_amp) >> 8);
  1044. if (value > 32767)
  1045. value = 32768;
  1046. else if (value < -32768)
  1047. value = -32768;
  1048. if (echo_tail >= N_ECHO_BUF)
  1049. echo_tail = 0;
  1050. out_ptr[0] = value;
  1051. out_ptr[1] = value >> 8;
  1052. out_ptr += 2;
  1053. echo_buf[echo_head++] = (value*3)/4;
  1054. if (echo_head >= N_ECHO_BUF)
  1055. echo_head = 0;
  1056. if (out_ptr >= out_end)
  1057. return 1;
  1058. }
  1059. return 0;
  1060. }
  1061. static int SetWithRange0(int value, int max)
  1062. {
  1063. if (value < 0)
  1064. return 0;
  1065. if (value > max)
  1066. return max;
  1067. return value;
  1068. }
  1069. static void SetPitchFormants()
  1070. {
  1071. int ix;
  1072. int factor = 256;
  1073. int pitch_value;
  1074. // adjust formants to give better results for a different voice pitch
  1075. if ((pitch_value = embedded_value[EMBED_P]) > MAX_PITCH_VALUE)
  1076. pitch_value = MAX_PITCH_VALUE;
  1077. if (pitch_value > 50) {
  1078. // only adjust if the pitch is higher than normal
  1079. factor = 256 + (25 * (pitch_value - 50))/50;
  1080. }
  1081. for (ix = 0; ix <= 5; ix++)
  1082. wvoice->freq[ix] = (wvoice->freq2[ix] * factor)/256;
  1083. factor = embedded_value[EMBED_T]*3;
  1084. wvoice->height[0] = (wvoice->height2[0] * (256 - factor*2))/256;
  1085. wvoice->height[1] = (wvoice->height2[1] * (256 - factor))/256;
  1086. }
  1087. void SetEmbedded(int control, int value)
  1088. {
  1089. // there was an embedded command in the text at this point
  1090. int sign = 0;
  1091. int command;
  1092. command = control & 0x1f;
  1093. if ((control & 0x60) == 0x60)
  1094. sign = -1;
  1095. else if ((control & 0x60) == 0x40)
  1096. sign = 1;
  1097. if (command < N_EMBEDDED_VALUES) {
  1098. if (sign == 0)
  1099. embedded_value[command] = value;
  1100. else
  1101. embedded_value[command] += (value * sign);
  1102. embedded_value[command] = SetWithRange0(embedded_value[command], embedded_max[command]);
  1103. }
  1104. switch (command)
  1105. {
  1106. case EMBED_T:
  1107. WavegenSetEcho(); // and drop through to case P
  1108. case EMBED_P:
  1109. SetPitchFormants();
  1110. break;
  1111. case EMBED_A: // amplitude
  1112. general_amplitude = GetAmplitude();
  1113. break;
  1114. case EMBED_F: // emphasis
  1115. general_amplitude = GetAmplitude();
  1116. break;
  1117. case EMBED_H:
  1118. WavegenSetEcho();
  1119. break;
  1120. }
  1121. }
  1122. void WavegenSetVoice(voice_t *v)
  1123. {
  1124. static voice_t v2;
  1125. memcpy(&v2, v, sizeof(v2));
  1126. wvoice = &v2;
  1127. if (v->peak_shape == 0)
  1128. pk_shape = pk_shape1;
  1129. else
  1130. pk_shape = pk_shape2;
  1131. consonant_amp = (v->consonant_amp * 26) /100;
  1132. if (samplerate <= 11000) {
  1133. consonant_amp = consonant_amp*2; // emphasize consonants at low sample rates
  1134. option_harmonic1 = 6;
  1135. }
  1136. WavegenSetEcho();
  1137. SetPitchFormants();
  1138. MarkerEvent(espeakEVENT_SAMPLERATE, 0, wvoice->samplerate, 0, out_ptr);
  1139. }
  1140. static void SetAmplitude(int length, unsigned char *amp_env, int value)
  1141. {
  1142. amp_ix = 0;
  1143. if (length == 0)
  1144. amp_inc = 0;
  1145. else
  1146. amp_inc = (256 * ENV_LEN * STEPSIZE)/length;
  1147. wdata.amplitude = (value * general_amplitude)/16;
  1148. wdata.amplitude_v = (wdata.amplitude * wvoice->consonant_ampv * 15)/100; // for wave mixed with voiced sounds
  1149. amplitude_env = amp_env;
  1150. }
  1151. void SetPitch2(voice_t *voice, int pitch1, int pitch2, int *pitch_base, int *pitch_range)
  1152. {
  1153. int x;
  1154. int base;
  1155. int range;
  1156. int pitch_value;
  1157. if (pitch1 > pitch2) {
  1158. x = pitch1; // swap values
  1159. pitch1 = pitch2;
  1160. pitch2 = x;
  1161. }
  1162. if ((pitch_value = embedded_value[EMBED_P]) > MAX_PITCH_VALUE)
  1163. pitch_value = MAX_PITCH_VALUE;
  1164. pitch_value -= embedded_value[EMBED_T]; // adjust tone for announcing punctuation
  1165. if (pitch_value < 0)
  1166. pitch_value = 0;
  1167. base = (voice->pitch_base * pitch_adjust_tab[pitch_value])/128;
  1168. range = (voice->pitch_range * embedded_value[EMBED_R])/50;
  1169. // compensate for change in pitch when the range is narrowed or widened
  1170. base -= (range - voice->pitch_range)*18;
  1171. *pitch_base = base + (pitch1 * range)/2;
  1172. *pitch_range = base + (pitch2 * range)/2 - *pitch_base;
  1173. }
  1174. void SetPitch(int length, unsigned char *env, int pitch1, int pitch2)
  1175. {
  1176. // length in samples
  1177. if ((wdata.pitch_env = env) == NULL)
  1178. wdata.pitch_env = env_fall; // default
  1179. wdata.pitch_ix = 0;
  1180. if (length == 0)
  1181. wdata.pitch_inc = 0;
  1182. else
  1183. wdata.pitch_inc = (256 * ENV_LEN * STEPSIZE)/length;
  1184. SetPitch2(wvoice, pitch1, pitch2, &wdata.pitch_base, &wdata.pitch_range);
  1185. // set initial pitch
  1186. wdata.pitch = ((wdata.pitch_env[0] * wdata.pitch_range) >>8) + wdata.pitch_base; // Hz << 12
  1187. flutter_amp = wvoice->flutter;
  1188. }
  1189. void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v)
  1190. {
  1191. int ix;
  1192. DOUBLEX next;
  1193. int length2;
  1194. int length4;
  1195. int qix;
  1196. int cmd;
  1197. static int glottal_reduce_tab1[4] = { 0x30, 0x30, 0x40, 0x50 }; // vowel before [?], amp * 1/256
  1198. static int glottal_reduce_tab2[4] = { 0x90, 0xa0, 0xb0, 0xc0 }; // vowel after [?], amp * 1/256
  1199. harm_sqrt_n = 0;
  1200. end_wave = 1;
  1201. // any additional information in the param1 ?
  1202. modulation_type = modn & 0xff;
  1203. glottal_flag = 0;
  1204. if (modn & 0x400) {
  1205. glottal_flag = 3; // before a glottal stop
  1206. glottal_reduce = glottal_reduce_tab1[(modn >> 8) & 3];
  1207. }
  1208. if (modn & 0x800) {
  1209. glottal_flag = 4; // after a glottal stop
  1210. glottal_reduce = glottal_reduce_tab2[(modn >> 8) & 3];
  1211. }
  1212. for (qix = wcmdq_head+1;; qix++) {
  1213. if (qix >= N_WCMDQ) qix = 0;
  1214. if (qix == wcmdq_tail) break;
  1215. cmd = wcmdq[qix][0];
  1216. if (cmd == WCMD_SPECT) {
  1217. end_wave = 0; // next wave generation is from another spectrum
  1218. break;
  1219. }
  1220. if ((cmd == WCMD_WAVE) || (cmd == WCMD_PAUSE))
  1221. break; // next is not from spectrum, so continue until end of wave cycle
  1222. }
  1223. // round the length to a multiple of the stepsize
  1224. length2 = (length + STEPSIZE/2) & ~0x3f;
  1225. if (length2 == 0)
  1226. length2 = STEPSIZE;
  1227. // add this length to any left over from the previous synth
  1228. samplecount_start = samplecount;
  1229. nsamples += length2;
  1230. length4 = length2/4;
  1231. peaks[7].freq = (7800 * v->freq[7] + v->freqadd[7]*256) << 8;
  1232. peaks[8].freq = (9000 * v->freq[8] + v->freqadd[8]*256) << 8;
  1233. for (ix = 0; ix < 8; ix++) {
  1234. if (ix < 7) {
  1235. peaks[ix].freq1 = (fr1->ffreq[ix] * v->freq[ix] + v->freqadd[ix]*256) << 8;
  1236. peaks[ix].freq = (int)peaks[ix].freq1;
  1237. next = (fr2->ffreq[ix] * v->freq[ix] + v->freqadd[ix]*256) << 8;
  1238. peaks[ix].freq_inc = ((next - peaks[ix].freq1) * (STEPSIZE/4)) / length4; // lower headroom for fixed point math
  1239. }
  1240. peaks[ix].height1 = (fr1->fheight[ix] * v->height[ix]) << 6;
  1241. peaks[ix].height = (int)peaks[ix].height1;
  1242. next = (fr2->fheight[ix] * v->height[ix]) << 6;
  1243. peaks[ix].height_inc = ((next - peaks[ix].height1) * STEPSIZE) / length2;
  1244. if ((ix <= 5) && (ix <= wvoice->n_harmonic_peaks)) {
  1245. peaks[ix].left1 = (fr1->fwidth[ix] * v->width[ix]) << 10;
  1246. peaks[ix].left = (int)peaks[ix].left1;
  1247. next = (fr2->fwidth[ix] * v->width[ix]) << 10;
  1248. peaks[ix].left_inc = ((next - peaks[ix].left1) * STEPSIZE) / length2;
  1249. if (ix < 3) {
  1250. peaks[ix].right1 = (fr1->fright[ix] * v->width[ix]) << 10;
  1251. peaks[ix].right = (int)peaks[ix].right1;
  1252. next = (fr2->fright[ix] * v->width[ix]) << 10;
  1253. peaks[ix].right_inc = ((next - peaks[ix].right1) * STEPSIZE) / length2;
  1254. } else
  1255. peaks[ix].right = peaks[ix].left;
  1256. }
  1257. }
  1258. }
  1259. static int Wavegen2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2)
  1260. {
  1261. if (resume == 0)
  1262. SetSynth(length, modulation, fr1, fr2, wvoice);
  1263. return Wavegen();
  1264. }
  1265. void Write4Bytes(FILE *f, int value)
  1266. {
  1267. // Write 4 bytes to a file, least significant first
  1268. int ix;
  1269. for (ix = 0; ix < 4; ix++) {
  1270. fputc(value & 0xff, f);
  1271. value = value >> 8;
  1272. }
  1273. }
  1274. int WavegenFill2()
  1275. {
  1276. // Pick up next wavegen commands from the queue
  1277. // return: 0 output buffer has been filled
  1278. // return: 1 input command queue is now empty
  1279. intptr_t *q;
  1280. int length;
  1281. int result;
  1282. int marker_type;
  1283. static int resume = 0;
  1284. static int echo_complete = 0;
  1285. while (out_ptr < out_end) {
  1286. if (WcmdqUsed() <= 0) {
  1287. if (echo_complete > 0) {
  1288. // continue to play silence until echo is completed
  1289. resume = PlaySilence(echo_complete, resume);
  1290. if (resume == 1)
  1291. return 0; // not yet finished
  1292. }
  1293. return 1; // queue empty, close sound channel
  1294. }
  1295. result = 0;
  1296. q = wcmdq[wcmdq_head];
  1297. length = q[1];
  1298. switch (q[0] & 0xff)
  1299. {
  1300. case WCMD_PITCH:
  1301. SetPitch(length, (unsigned char *)q[2], q[3] >> 16, q[3] & 0xffff);
  1302. break;
  1303. case WCMD_PAUSE:
  1304. if (resume == 0)
  1305. echo_complete -= length;
  1306. wdata.n_mix_wavefile = 0;
  1307. wdata.amplitude_fmt = 100;
  1308. #ifdef INCLUDE_KLATT
  1309. KlattReset(1);
  1310. #endif
  1311. result = PlaySilence(length, resume);
  1312. break;
  1313. case WCMD_WAVE:
  1314. echo_complete = echo_length;
  1315. wdata.n_mix_wavefile = 0;
  1316. #ifdef INCLUDE_KLATT
  1317. KlattReset(1);
  1318. #endif
  1319. result = PlayWave(length, resume, (unsigned char *)q[2], q[3] & 0xff, q[3] >> 8);
  1320. break;
  1321. case WCMD_WAVE2:
  1322. // wave file to be played at the same time as synthesis
  1323. wdata.mix_wave_amp = q[3] >> 8;
  1324. wdata.mix_wave_scale = q[3] & 0xff;
  1325. wdata.n_mix_wavefile = (length & 0xffff);
  1326. wdata.mix_wavefile_max = (length >> 16) & 0xffff;
  1327. if (wdata.mix_wave_scale == 0) {
  1328. wdata.n_mix_wavefile *= 2;
  1329. wdata.mix_wavefile_max *= 2;
  1330. }
  1331. wdata.mix_wavefile_ix = 0;
  1332. wdata.mix_wavefile_offset = 0;
  1333. wdata.mix_wavefile = (unsigned char *)q[2];
  1334. break;
  1335. case WCMD_SPECT2: // as WCMD_SPECT but stop any concurrent wave file
  1336. wdata.n_mix_wavefile = 0; // ... and drop through to WCMD_SPECT case
  1337. case WCMD_SPECT:
  1338. echo_complete = echo_length;
  1339. result = Wavegen2(length & 0xffff, q[1] >> 16, resume, (frame_t *)q[2], (frame_t *)q[3]);
  1340. break;
  1341. #ifdef INCLUDE_KLATT
  1342. case WCMD_KLATT2: // as WCMD_SPECT but stop any concurrent wave file
  1343. wdata.n_mix_wavefile = 0; // ... and drop through to WCMD_SPECT case
  1344. case WCMD_KLATT:
  1345. echo_complete = echo_length;
  1346. result = Wavegen_Klatt2(length & 0xffff, resume, (frame_t *)q[2], (frame_t *)q[3]);
  1347. break;
  1348. #endif
  1349. case WCMD_MARKER:
  1350. marker_type = q[0] >> 8;
  1351. MarkerEvent(marker_type, q[1], q[2], q[3], out_ptr);
  1352. if (marker_type == 1) // word marker
  1353. current_source_index = q[1] & 0xffffff;
  1354. break;
  1355. case WCMD_AMPLITUDE:
  1356. SetAmplitude(length, (unsigned char *)q[2], q[3]);
  1357. break;
  1358. case WCMD_VOICE:
  1359. WavegenSetVoice((voice_t *)q[2]);
  1360. free((voice_t *)q[2]);
  1361. break;
  1362. case WCMD_EMBEDDED:
  1363. SetEmbedded(q[1], q[2]);
  1364. break;
  1365. case WCMD_MBROLA_DATA:
  1366. result = MbrolaFill(length, resume, (general_amplitude * wvoice->voicing)/64);
  1367. break;
  1368. case WCMD_FMT_AMPLITUDE:
  1369. if ((wdata.amplitude_fmt = q[1]) == 0)
  1370. wdata.amplitude_fmt = 100; // percentage, but value=0 means 100%
  1371. break;
  1372. #if HAVE_SONIC_H
  1373. case WCMD_SONIC_SPEED:
  1374. sonicSpeed = (double)q[1] / 1024;
  1375. break;
  1376. #endif
  1377. }
  1378. if (result == 0) {
  1379. WcmdqIncHead();
  1380. resume = 0;
  1381. } else
  1382. resume = 1;
  1383. }
  1384. return 0;
  1385. }
  1386. #if HAVE_SONIC_H
  1387. // Speed up the audio samples with libsonic.
  1388. static int SpeedUp(short *outbuf, int length_in, int length_out, int end_of_text)
  1389. {
  1390. if (length_in > 0) {
  1391. if (sonicSpeedupStream == NULL)
  1392. sonicSpeedupStream = sonicCreateStream(22050, 1);
  1393. if (sonicGetSpeed(sonicSpeedupStream) != sonicSpeed)
  1394. sonicSetSpeed(sonicSpeedupStream, sonicSpeed);
  1395. sonicWriteShortToStream(sonicSpeedupStream, outbuf, length_in);
  1396. }
  1397. if (sonicSpeedupStream == NULL)
  1398. return 0;
  1399. if (end_of_text)
  1400. sonicFlushStream(sonicSpeedupStream);
  1401. return sonicReadShortFromStream(sonicSpeedupStream, outbuf, length_out);
  1402. }
  1403. #endif
  1404. // Call WavegenFill2, and then speed up the output samples.
  1405. int WavegenFill()
  1406. {
  1407. int finished;
  1408. unsigned char *p_start;
  1409. p_start = out_ptr;
  1410. finished = WavegenFill2();
  1411. #if HAVE_SONIC_H
  1412. if (sonicSpeed > 1.0) {
  1413. int length;
  1414. int max_length;
  1415. max_length = (out_end - p_start);
  1416. length = 2*SpeedUp((short *)p_start, (out_ptr-p_start)/2, max_length/2, finished);
  1417. out_ptr = p_start + length;
  1418. if (length >= max_length)
  1419. finished = 0; // there may be more data to flush
  1420. }
  1421. #endif
  1422. return finished;
  1423. }