PageRenderTime 51ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/native/external/espeak/src/wavegen.cpp

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