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