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