1
2 /***************************************************************************
3 * Copyright (C) 2008 by Jonathan Duddington *
4 * email: jonsd@users.sourceforge.net *
5 * *
6 * Based on a re-implementation by: *
7 * (c) 1993,94 Jon Iles and Nick Ing-Simmons *
8 * of the Klatt cascade-parallel formant synthesizer *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 3 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, see: *
22 * <http://www.gnu.org/licenses/>. *
23 ***************************************************************************/
24
25 // See URL: ftp://svr-ftp.eng.cam.ac.uk/pub/comp.speech/synthesis/klatt.3.04.tar.gz
26
27 #include "StdAfx.h"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <math.h>
32 #include <string.h>
33
34 #include "speak_lib.h"
35 #include "speech.h"
36 #include "klatt.h"
37 #include "phoneme.h"
38 #include "synthesize.h"
39 #include "voice.h"
40
41 #ifdef INCLUDE_KLATT // conditional compilation for the whole file
42
43 extern unsigned char *out_ptr; // **JSD
44 extern unsigned char *out_start;
45 extern unsigned char *out_end;
46 extern WGEN_DATA wdata;
47 static int nsamples;
48 static int sample_count;
49
50
51 #ifdef _MSC_VER
52 #define getrandom(min,max) ((rand()%(int)(((max)+1)-(min)))+(min))
53 #else
54 #define getrandom(min,max) ((rand()%(long)(((max)+1)-(min)))+(min))
55 #endif
56
57
58 /* function prototypes for functions private to this file */
59
60 static void flutter(klatt_frame_ptr);
61 static double sampled_source (int);
62 static double impulsive_source (void);
63 static double natural_source (void);
64 static void pitch_synch_par_reset (klatt_frame_ptr);
65 static double gen_noise (double);
66 static double DBtoLIN (long);
67 static void frame_init (klatt_frame_ptr);
68 static void setabc (long,long,resonator_ptr);
69 static void setzeroabc (long,long,resonator_ptr);
70
71 static klatt_frame_t kt_frame;
72 static klatt_global_t kt_globals;
73
74 #define NUMBER_OF_SAMPLES 100
75
76 static int scale_wav_tab[] = {45,38,45,45,55}; // scale output from different voicing sources
77
78 // For testing, this can be overwritten in KlattInit()
79 static short natural_samples2[256]= {
80 2583, 2516, 2450, 2384, 2319, 2254, 2191, 2127,
81 2067, 2005, 1946, 1890, 1832, 1779, 1726, 1675,
82 1626, 1579, 1533, 1491, 1449, 1409, 1372, 1336,
83 1302, 1271, 1239, 1211, 1184, 1158, 1134, 1111,
84 1089, 1069, 1049, 1031, 1013, 996, 980, 965,
85 950, 936, 921, 909, 895, 881, 869, 855,
86 843, 830, 818, 804, 792, 779, 766, 754,
87 740, 728, 715, 702, 689, 676, 663, 651,
88 637, 626, 612, 601, 588, 576, 564, 552,
89 540, 530, 517, 507, 496, 485, 475, 464,
90 454, 443, 434, 424, 414, 404, 394, 385,
91 375, 366, 355, 347, 336, 328, 317, 308,
92 299, 288, 280, 269, 260, 250, 240, 231,
93 220, 212, 200, 192, 181, 172, 161, 152,
94 142, 133, 123, 113, 105, 94, 86, 76,
95 67, 57, 49, 39, 30, 22, 11, 4,
96 -5, -14, -23, -32, -41, -50, -60, -69,
97 -78, -87, -96, -107, -115, -126, -134, -144,
98 -154, -164, -174, -183, -193, -203, -213, -222,
99 -233, -242, -252, -262, -271, -281, -291, -301,
100 -310, -320, -330, -339, -349, -357, -368, -377,
101 -387, -397, -406, -417, -426, -436, -446, -456,
102 -467, -477, -487, -499, -509, -521, -532, -543,
103 -555, -567, -579, -591, -603, -616, -628, -641,
104 -653, -666, -679, -692, -705, -717, -732, -743,
105 -758, -769, -783, -795, -808, -820, -834, -845,
106 -860, -872, -885, -898, -911, -926, -939, -955,
107 -968, -986, -999, -1018, -1034, -1054, -1072, -1094,
108 -1115, -1138, -1162, -1188, -1215, -1244, -1274, -1307,
109 -1340, -1377, -1415, -1453, -1496, -1538, -1584, -1631,
110 -1680, -1732, -1783, -1839, -1894, -1952, -2010, -2072,
111 -2133, -2196, -2260, -2325, -2390, -2456, -2522, -2589,
112 };
113 static short natural_samples[100]=
114 {
115 -310,-400,530,356,224,89,23,-10,-58,-16,461,599,536,701,770,
116 605,497,461,560,404,110,224,131,104,-97,155,278,-154,-1165,
117 -598,737,125,-592,41,11,-247,-10,65,92,80,-304,71,167,-1,122,
118 233,161,-43,278,479,485,407,266,650,134,80,236,68,260,269,179,
119 53,140,275,293,296,104,257,152,311,182,263,245,125,314,140,44,
120 203,230,-235,-286,23,107,92,-91,38,464,443,176,98,-784,-2449,
121 -1891,-1045,-1600,-1462,-1384,-1261,-949,-730
122 };
123
124 /*
125 function RESONATOR
126
127 This is a generic resonator function. Internal memory for the resonator
128 is stored in the globals structure.
129 */
130
resonator(resonator_ptr r,double input)131 static double resonator(resonator_ptr r, double input)
132 {
133 double x;
134
135 x = (double) ((double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2);
136 r->p2 = (double)r->p1;
137 r->p1 = (double)x;
138
139 return (double)x;
140 }
141
resonator2(resonator_ptr r,double input)142 static double resonator2(resonator_ptr r, double input)
143 {
144 double x;
145
146 x = (double) ((double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2);
147 r->p2 = (double)r->p1;
148 r->p1 = (double)x;
149
150 r->a += r->a_inc;
151 r->b += r->b_inc;
152 r->c += r->c_inc;
153 return (double)x;
154 }
155
156
157
158 /*
159 function ANTIRESONATOR
160
161 This is a generic anti-resonator function. The code is the same as resonator
162 except that a,b,c need to be set with setzeroabc() and we save inputs in
163 p1/p2 rather than outputs. There is currently only one of these - "rnz"
164 Output = (rnz.a * input) + (rnz.b * oldin1) + (rnz.c * oldin2)
165 */
166
167 #ifdef deleted
antiresonator(resonator_ptr r,double input)168 static double antiresonator(resonator_ptr r, double input)
169 {
170 register double x = (double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2;
171 r->p2 = (double)r->p1;
172 r->p1 = (double)input;
173 return (double)x;
174 }
175 #endif
176
antiresonator2(resonator_ptr r,double input)177 static double antiresonator2(resonator_ptr r, double input)
178 {
179 register double x = (double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2;
180 r->p2 = (double)r->p1;
181 r->p1 = (double)input;
182
183 r->a += r->a_inc;
184 r->b += r->b_inc;
185 r->c += r->c_inc;
186 return (double)x;
187 }
188
189
190
191 /*
192 function FLUTTER
193
194 This function adds F0 flutter, as specified in:
195
196 "Analysis, synthesis and perception of voice quality variations among
197 female and male talkers" D.H. Klatt and L.C. Klatt JASA 87(2) February 1990.
198
199 Flutter is added by applying a quasi-random element constructed from three
200 slowly varying sine waves.
201 */
202
flutter(klatt_frame_ptr frame)203 static void flutter(klatt_frame_ptr frame)
204 {
205 static int time_count;
206 double delta_f0;
207 double fla,flb,flc,fld,fle;
208
209 fla = (double) kt_globals.f0_flutter / 50;
210 flb = (double) kt_globals.original_f0 / 100;
211 // flc = sin(2*PI*12.7*time_count);
212 // fld = sin(2*PI*7.1*time_count);
213 // fle = sin(2*PI*4.7*time_count);
214 flc = sin(PI*12.7*time_count); // because we are calling flutter() more frequently, every 2.9mS
215 fld = sin(PI*7.1*time_count);
216 fle = sin(PI*4.7*time_count);
217 delta_f0 = fla * flb * (flc + fld + fle) * 10;
218 frame->F0hz10 = frame->F0hz10 + (long) delta_f0;
219 time_count++;
220 }
221
222
223
224 /*
225 function SAMPLED_SOURCE
226
227 Allows the use of a glottal excitation waveform sampled from a real
228 voice.
229 */
230
sampled_source(int source_num)231 static double sampled_source(int source_num)
232 {
233 int itemp;
234 double ftemp;
235 double result;
236 double diff_value;
237 int current_value;
238 int next_value;
239 double temp_diff;
240 short *samples;
241
242 if(source_num == 0)
243 {
244 samples = natural_samples;
245 kt_globals.num_samples = 100;
246 }
247 else
248 {
249 samples = natural_samples2;
250 kt_globals.num_samples = 256;
251 }
252
253 if(kt_globals.T0!=0)
254 {
255 ftemp = (double) kt_globals.nper;
256 ftemp = ftemp / kt_globals.T0;
257 ftemp = ftemp * kt_globals.num_samples;
258 itemp = (int) ftemp;
259
260 temp_diff = ftemp - (double) itemp;
261
262 current_value = samples[itemp];
263 next_value = samples[itemp+1];
264
265 diff_value = (double) next_value - (double) current_value;
266 diff_value = diff_value * temp_diff;
267
268 result = samples[itemp] + diff_value;
269 result = result * kt_globals.sample_factor;
270 }
271 else
272 {
273 result = 0;
274 }
275 return(result);
276 }
277
278
279
280
281 /*
282 function PARWAVE
283
284 Converts synthesis parameters to a waveform.
285 */
286
287
parwave(klatt_frame_ptr frame)288 static int parwave(klatt_frame_ptr frame)
289 {
290 double temp;
291 int value;
292 double outbypas;
293 double out;
294 long n4;
295 double frics;
296 double glotout;
297 double aspiration;
298 double casc_next_in;
299 double par_glotout;
300 static double noise;
301 static double voice;
302 static double vlast;
303 static double glotlast;
304 static double sourc;
305 int ix;
306
307 flutter(frame); /* add f0 flutter */
308
309 #ifdef LOG_FRAMES
310 if(option_log_frames)
311 {
312 FILE *f;
313 f=fopen("log-klatt","a");
314 fprintf(f,"%4dhz %2dAV %4d %3d, %4d %3d, %4d %3d, %4d %3d, %4d, %3d, FNZ=%3d TLT=%2d\n",frame->F0hz10,frame->AVdb,
315 frame->Fhz[1],frame->Bhz[1],frame->Fhz[2],frame->Bhz[2],frame->Fhz[3],frame->Bhz[3],frame->Fhz[4],frame->Bhz[4],frame->Fhz[5],frame->Bhz[5],frame->Fhz[0],frame->TLTdb);
316 fclose(f);
317 }
318 #endif
319
320 /* MAIN LOOP, for each output sample of current frame: */
321
322 for (kt_globals.ns=0; kt_globals.ns<kt_globals.nspfr; kt_globals.ns++)
323 {
324 /* Get low-passed random number for aspiration and frication noise */
325 noise = gen_noise(noise);
326
327 /*
328 Amplitude modulate noise (reduce noise amplitude during
329 second half of glottal period) if voicing simultaneously present.
330 */
331
332 if (kt_globals.nper > kt_globals.nmod)
333 {
334 noise *= (double) 0.5;
335 }
336
337 /* Compute frication noise */
338 frics = kt_globals.amp_frica * noise;
339
340 /*
341 Compute voicing waveform. Run glottal source simulation at 4
342 times normal sample rate to minimize quantization noise in
343 period of female voice.
344 */
345
346 for (n4=0; n4<4; n4++)
347 {
348 switch(kt_globals.glsource)
349 {
350 case IMPULSIVE:
351 voice = impulsive_source();
352 break;
353 case NATURAL:
354 voice = natural_source();
355 break;
356 case SAMPLED:
357 voice = sampled_source(0);
358 break;
359 case SAMPLED2:
360 voice = sampled_source(1);
361 break;
362 }
363
364 /* Reset period when counter 'nper' reaches T0 */
365 if (kt_globals.nper >= kt_globals.T0)
366 {
367 kt_globals.nper = 0;
368 pitch_synch_par_reset(frame);
369 }
370
371 /*
372 Low-pass filter voicing waveform before downsampling from 4*samrate
373 to samrate samples/sec. Resonator f=.09*samrate, bw=.06*samrate
374 */
375
376 voice = resonator(&(kt_globals.rsn[RLP]),voice);
377
378 /* Increment counter that keeps track of 4*samrate samples per sec */
379 kt_globals.nper++;
380 }
381
382 /*
383 Tilt spectrum of voicing source down by soft low-pass filtering, amount
384 of tilt determined by TLTdb
385 */
386
387 voice = (voice * kt_globals.onemd) + (vlast * kt_globals.decay);
388 vlast = voice;
389
390 /*
391 Add breathiness during glottal open phase. Amount of breathiness
392 determined by parameter Aturb Use nrand rather than noise because
393 noise is low-passed.
394 */
395
396
397 if (kt_globals.nper < kt_globals.nopen)
398 {
399 voice += kt_globals.amp_breth * kt_globals.nrand;
400 }
401
402 /* Set amplitude of voicing */
403 glotout = kt_globals.amp_voice * voice;
404 par_glotout = kt_globals.par_amp_voice * voice;
405
406 /* Compute aspiration amplitude and add to voicing source */
407 aspiration = kt_globals.amp_aspir * noise;
408 glotout += aspiration;
409
410 par_glotout += aspiration;
411
412 /*
413 Cascade vocal tract, excited by laryngeal sources.
414 Nasal antiresonator, then formants FNP, F5, F4, F3, F2, F1
415 */
416
417 out=0;
418 if(kt_globals.synthesis_model != ALL_PARALLEL)
419 {
420 casc_next_in = antiresonator2(&(kt_globals.rsn[Rnz]),glotout);
421 casc_next_in = resonator(&(kt_globals.rsn[Rnpc]),casc_next_in);
422 casc_next_in = resonator(&(kt_globals.rsn[R8c]),casc_next_in);
423 casc_next_in = resonator(&(kt_globals.rsn[R7c]),casc_next_in);
424 casc_next_in = resonator(&(kt_globals.rsn[R6c]),casc_next_in);
425 casc_next_in = resonator2(&(kt_globals.rsn[R5c]),casc_next_in);
426 casc_next_in = resonator2(&(kt_globals.rsn[R4c]),casc_next_in);
427 casc_next_in = resonator2(&(kt_globals.rsn[R3c]),casc_next_in);
428 casc_next_in = resonator2(&(kt_globals.rsn[R2c]),casc_next_in);
429 out = resonator2(&(kt_globals.rsn[R1c]),casc_next_in);
430 }
431
432 /* Excite parallel F1 and FNP by voicing waveform */
433 sourc = par_glotout; /* Source is voicing plus aspiration */
434
435 /*
436 Standard parallel vocal tract Formants F6,F5,F4,F3,F2,
437 outputs added with alternating sign. Sound source for other
438 parallel resonators is frication plus first difference of
439 voicing waveform.
440 */
441
442 out += resonator(&(kt_globals.rsn[R1p]),sourc);
443 out += resonator(&(kt_globals.rsn[Rnpp]),sourc);
444
445 sourc = frics + par_glotout - glotlast;
446 glotlast = par_glotout;
447
448 for(ix=R2p; ix<=R6p; ix++)
449 {
450 out = resonator(&(kt_globals.rsn[ix]),sourc) - out;
451 }
452
453 outbypas = kt_globals.amp_bypas * sourc;
454
455 out = outbypas - out;
456
457 #ifdef deleted
458 // for testing
459 if (kt_globals.outsl != 0)
460 {
461 switch(kt_globals.outsl)
462 {
463 case 1:
464 out = voice;
465 break;
466 case 2:
467 out = aspiration;
468 break;
469 case 3:
470 out = frics;
471 break;
472 case 4:
473 out = glotout;
474 break;
475 case 5:
476 out = par_glotout;
477 break;
478 case 6:
479 out = outbypas;
480 break;
481 case 7:
482 out = sourc;
483 break;
484 }
485 }
486 #endif
487
488 out = resonator(&(kt_globals.rsn[Rout]),out);
489 temp = (int)(out * wdata.amplitude * kt_globals.amp_gain0) ; /* Convert back to integer */
490
491
492 // mix with a recorded WAV if required for this phoneme
493 {
494 int z2;
495 signed char c;
496 int sample;
497
498 z2 = 0;
499 if(wdata.mix_wavefile_ix < wdata.n_mix_wavefile)
500 {
501 if(wdata.mix_wave_scale == 0)
502 {
503 // a 16 bit sample
504 c = wdata.mix_wavefile[wdata.mix_wavefile_ix+1];
505 sample = wdata.mix_wavefile[wdata.mix_wavefile_ix] + (c * 256);
506 wdata.mix_wavefile_ix += 2;
507 }
508 else
509 {
510 // a 8 bit sample, scaled
511 sample = (signed char)wdata.mix_wavefile[wdata.mix_wavefile_ix++] * wdata.mix_wave_scale;
512 }
513 z2 = sample * wdata.amplitude_v / 1024;
514 z2 = (z2 * wdata.mix_wave_amp)/40;
515 temp += z2;
516 }
517 }
518
519 // if fadeout is set, fade to zero over 64 samples, to avoid clicks at end of synthesis
520 if(kt_globals.fadeout > 0)
521 {
522 kt_globals.fadeout--;
523 temp = (temp * kt_globals.fadeout) / 64;
524 }
525
526 value = (int)temp + ((echo_buf[echo_tail++]*echo_amp) >> 8);
527 if(echo_tail >= N_ECHO_BUF)
528 echo_tail=0;
529
530 if (value < -32768)
531 {
532 value = -32768;
533 }
534
535 if (value > 32767)
536 {
537 value = 32767;
538 }
539
540 *out_ptr++ = value;
541 *out_ptr++ = value >> 8;
542
543 echo_buf[echo_head++] = value;
544 if(echo_head >= N_ECHO_BUF)
545 echo_head = 0;
546
547 sample_count++;
548 if(out_ptr >= out_end)
549 {
550 return(1);
551 }
552 }
553 return(0);
554 } // end of parwave
555
556
557
558
559
KlattReset(int control)560 void KlattReset(int control)
561 {
562 int r_ix;
563
564 if(control == 2)
565 {
566 //Full reset
567 kt_globals.FLPhz = (950 * kt_globals.samrate) / 10000;
568 kt_globals.BLPhz = (630 * kt_globals.samrate) / 10000;
569 kt_globals.minus_pi_t = -PI / kt_globals.samrate;
570 kt_globals.two_pi_t = -2.0 * kt_globals.minus_pi_t;
571 setabc(kt_globals.FLPhz,kt_globals.BLPhz,&(kt_globals.rsn[RLP]));
572
573 }
574
575 if(control > 0)
576 {
577 kt_globals.nper = 0;
578 kt_globals.T0 = 0;
579 kt_globals.nopen = 0;
580 kt_globals.nmod = 0;
581
582 for(r_ix=RGL; r_ix < N_RSN; r_ix++)
583 {
584 kt_globals.rsn[r_ix].p1 = 0;
585 kt_globals.rsn[r_ix].p2 = 0;
586 }
587
588 }
589
590 for(r_ix=0; r_ix <= R6p; r_ix++)
591 {
592 kt_globals.rsn[r_ix].p1 = 0;
593 kt_globals.rsn[r_ix].p2 = 0;
594 }
595 }
596
597
598 /*
599 function FRAME_INIT
600
601 Use parameters from the input frame to set up resonator coefficients.
602 */
603
frame_init(klatt_frame_ptr frame)604 static void frame_init(klatt_frame_ptr frame)
605 {
606 double amp_par[7];
607 static double amp_par_factor[7] = {0.6, 0.4, 0.15, 0.06, 0.04, 0.022, 0.03};
608 long Gain0_tmp;
609 int ix;
610
611 kt_globals.original_f0 = frame->F0hz10 / 10;
612
613 frame->AVdb_tmp = frame->AVdb - 7;
614 if (frame->AVdb_tmp < 0)
615 {
616 frame->AVdb_tmp = 0;
617 }
618
619 kt_globals.amp_aspir = DBtoLIN(frame->ASP) * 0.05;
620 kt_globals.amp_frica = DBtoLIN(frame->AF) * 0.25;
621 kt_globals.par_amp_voice = DBtoLIN(frame->AVpdb);
622 kt_globals.amp_bypas = DBtoLIN(frame->AB) * 0.05;
623
624 for(ix=0; ix <= 6; ix++)
625 {
626 // parallel amplitudes F1 to F6, and parallel nasal pole
627 amp_par[ix] = DBtoLIN(frame->Ap[ix]) * amp_par_factor[ix];
628 }
629
630 Gain0_tmp = frame->Gain0 - 3;
631 if (Gain0_tmp <= 0)
632 {
633 Gain0_tmp = 57;
634 }
635 kt_globals.amp_gain0 = DBtoLIN(Gain0_tmp) / kt_globals.scale_wav;
636
637 /* Set coefficients of variable cascade resonators */
638 for(ix=1; ix<=9; ix++)
639 {
640 // formants 1 to 8, plus nasal pole
641 setabc(frame->Fhz[ix],frame->Bhz[ix],&(kt_globals.rsn[ix]));
642
643 if(ix <= 5)
644 {
645 setabc(frame->Fhz_next[ix],frame->Bhz_next[ix],&(kt_globals.rsn_next[ix]));
646
647 kt_globals.rsn[ix].a_inc = (kt_globals.rsn_next[ix].a - kt_globals.rsn[ix].a) / 64.0;
648 kt_globals.rsn[ix].b_inc = (kt_globals.rsn_next[ix].b - kt_globals.rsn[ix].b) / 64.0;
649 kt_globals.rsn[ix].c_inc = (kt_globals.rsn_next[ix].c - kt_globals.rsn[ix].c) / 64.0;
650 }
651 }
652
653 // nasal zero anti-resonator
654 setzeroabc(frame->Fhz[F_NZ],frame->Bhz[F_NZ],&(kt_globals.rsn[Rnz]));
655 setzeroabc(frame->Fhz_next[F_NZ],frame->Bhz_next[F_NZ],&(kt_globals.rsn_next[Rnz]));
656 kt_globals.rsn[F_NZ].a_inc = (kt_globals.rsn_next[F_NZ].a - kt_globals.rsn[F_NZ].a) / 64.0;
657 kt_globals.rsn[F_NZ].b_inc = (kt_globals.rsn_next[F_NZ].b - kt_globals.rsn[F_NZ].b) / 64.0;
658 kt_globals.rsn[F_NZ].c_inc = (kt_globals.rsn_next[F_NZ].c - kt_globals.rsn[F_NZ].c) / 64.0;
659
660
661 /* Set coefficients of parallel resonators, and amplitude of outputs */
662
663 for(ix=0; ix<=6; ix++)
664 {
665 setabc(frame->Fhz[ix],frame->Bphz[ix],&(kt_globals.rsn[Rparallel+ix]));
666 kt_globals.rsn[Rparallel+ix].a *= amp_par[ix];
667 }
668
669 /* output low-pass filter */
670
671 setabc((long)0.0,(long)(kt_globals.samrate/2),&(kt_globals.rsn[Rout]));
672
673 }
674
675
676
677 /*
678 function IMPULSIVE_SOURCE
679
680 Generate a low pass filtered train of impulses as an approximation of
681 a natural excitation waveform. Low-pass filter the differentiated impulse
682 with a critically-damped second-order filter, time constant proportional
683 to Kopen.
684 */
685
686
impulsive_source()687 static double impulsive_source()
688 {
689 static double doublet[] = {0.0,13000000.0,-13000000.0};
690 static double vwave;
691
692 if (kt_globals.nper < 3)
693 {
694 vwave = doublet[kt_globals.nper];
695 }
696 else
697 {
698 vwave = 0.0;
699 }
700
701 return(resonator(&(kt_globals.rsn[RGL]),vwave));
702 }
703
704
705
706 /*
707 function NATURAL_SOURCE
708
709 Vwave is the differentiated glottal flow waveform, there is a weak
710 spectral zero around 800 Hz, magic constants a,b reset pitch synchronously.
711 */
712
natural_source()713 static double natural_source()
714 {
715 double lgtemp;
716 static double vwave;
717
718 if (kt_globals.nper < kt_globals.nopen)
719 {
720 kt_globals.pulse_shape_a -= kt_globals.pulse_shape_b;
721 vwave += kt_globals.pulse_shape_a;
722 lgtemp=vwave * 0.028;
723
724 return(lgtemp);
725 }
726 else
727 {
728 vwave = 0.0;
729 return(0.0);
730 }
731 }
732
733
734
735
736
737 /*
738 function PITCH_SYNC_PAR_RESET
739
740 Reset selected parameters pitch-synchronously.
741
742
743 Constant B0 controls shape of glottal pulse as a function
744 of desired duration of open phase N0
745 (Note that N0 is specified in terms of 40,000 samples/sec of speech)
746
747 Assume voicing waveform V(t) has form: k1 t**2 - k2 t**3
748
749 If the radiation characterivative, a temporal derivative
750 is folded in, and we go from continuous time to discrete
751 integers n: dV/dt = vwave[n]
752 = sum over i=1,2,...,n of { a - (i * b) }
753 = a n - b/2 n**2
754
755 where the constants a and b control the detailed shape
756 and amplitude of the voicing waveform over the open
757 potion of the voicing cycle "nopen".
758
759 Let integral of dV/dt have no net dc flow --> a = (b * nopen) / 3
760
761 Let maximum of dUg(n)/dn be constant --> b = gain / (nopen * nopen)
762 meaning as nopen gets bigger, V has bigger peak proportional to n
763
764 Thus, to generate the table below for 40 <= nopen <= 263:
765
766 B0[nopen - 40] = 1920000 / (nopen * nopen)
767 */
768
pitch_synch_par_reset(klatt_frame_ptr frame)769 static void pitch_synch_par_reset(klatt_frame_ptr frame)
770 {
771 long temp;
772 double temp1;
773 static long skew;
774 static short B0[224] =
775 {
776 1200,1142,1088,1038, 991, 948, 907, 869, 833, 799, 768, 738, 710, 683, 658,
777 634, 612, 590, 570, 551, 533, 515, 499, 483, 468, 454, 440, 427, 415, 403,
778 391, 380, 370, 360, 350, 341, 332, 323, 315, 307, 300, 292, 285, 278, 272,
779 265, 259, 253, 247, 242, 237, 231, 226, 221, 217, 212, 208, 204, 199, 195,
780 192, 188, 184, 180, 177, 174, 170, 167, 164, 161, 158, 155, 153, 150, 147,
781 145, 142, 140, 137, 135, 133, 131, 128, 126, 124, 122, 120, 119, 117, 115,
782 113,111, 110, 108, 106, 105, 103, 102, 100, 99, 97, 96, 95, 93, 92, 91, 90,
783 88, 87, 86, 85, 84, 83, 82, 80, 79, 78, 77, 76, 75, 75, 74, 73, 72, 71,
784 70, 69, 68, 68, 67, 66, 65, 64, 64, 63, 62, 61, 61, 60, 59, 59, 58, 57,
785 57, 56, 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, 48,
786 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 41, 41, 40, 40,
787 39, 39, 38, 38, 38, 38, 37, 37, 36, 36, 36, 36, 35, 35, 35, 35, 34, 34,33,
788 33, 33, 33, 32, 32, 32, 32, 31, 31, 31, 31, 30, 30, 30, 30, 29, 29, 29, 29,
789 28, 28, 28, 28, 27, 27
790 };
791
792 if (frame->F0hz10 > 0)
793 {
794 /* T0 is 4* the number of samples in one pitch period */
795
796 kt_globals.T0 = (40 * kt_globals.samrate) / frame->F0hz10;
797
798
799 kt_globals.amp_voice = DBtoLIN(frame->AVdb_tmp);
800
801 /* Duration of period before amplitude modulation */
802
803 kt_globals.nmod = kt_globals.T0;
804 if (frame->AVdb_tmp > 0)
805 {
806 kt_globals.nmod >>= 1;
807 }
808
809 /* Breathiness of voicing waveform */
810
811 kt_globals.amp_breth = DBtoLIN(frame->Aturb) * 0.1;
812
813 /* Set open phase of glottal period where 40 <= open phase <= 263 */
814
815 kt_globals.nopen = 4 * frame->Kopen;
816
817 if ((kt_globals.glsource == IMPULSIVE) && (kt_globals.nopen > 263))
818 {
819 kt_globals.nopen = 263;
820 }
821
822 if (kt_globals.nopen >= (kt_globals.T0-1))
823 {
824 // printf("Warning: glottal open period cannot exceed T0, truncated\n");
825 kt_globals.nopen = kt_globals.T0 - 2;
826 }
827
828 if (kt_globals.nopen < 40)
829 {
830 /* F0 max = 1000 Hz */
831 // printf("Warning: minimum glottal open period is 10 samples.\n");
832 // printf("truncated, nopen = %d\n",kt_globals.nopen);
833 kt_globals.nopen = 40;
834 }
835
836
837 /* Reset a & b, which determine shape of "natural" glottal waveform */
838
839 kt_globals.pulse_shape_b = B0[kt_globals.nopen-40];
840 kt_globals.pulse_shape_a = (kt_globals.pulse_shape_b * kt_globals.nopen) * 0.333;
841
842 /* Reset width of "impulsive" glottal pulse */
843
844 temp = kt_globals.samrate / kt_globals.nopen;
845
846 setabc((long)0,temp,&(kt_globals.rsn[RGL]));
847
848 /* Make gain at F1 about constant */
849
850 temp1 = kt_globals.nopen *.00833;
851 kt_globals.rsn[RGL].a *= temp1 * temp1;
852
853 /*
854 Truncate skewness so as not to exceed duration of closed phase
855 of glottal period.
856 */
857
858
859 temp = kt_globals.T0 - kt_globals.nopen;
860 if (frame->Kskew > temp)
861 {
862 // printf("Kskew duration=%d > glottal closed period=%d, truncate\n", frame->Kskew, kt_globals.T0 - kt_globals.nopen);
863 frame->Kskew = temp;
864 }
865 if (skew >= 0)
866 {
867 skew = frame->Kskew;
868 }
869 else
870 {
871 skew = - frame->Kskew;
872 }
873
874 /* Add skewness to closed portion of voicing period */
875 kt_globals.T0 = kt_globals.T0 + skew;
876 skew = - skew;
877 }
878 else
879 {
880 kt_globals.T0 = 4; /* Default for f0 undefined */
881 kt_globals.amp_voice = 0.0;
882 kt_globals.nmod = kt_globals.T0;
883 kt_globals.amp_breth = 0.0;
884 kt_globals.pulse_shape_a = 0.0;
885 kt_globals.pulse_shape_b = 0.0;
886 }
887
888 /* Reset these pars pitch synchronously or at update rate if f0=0 */
889
890 if ((kt_globals.T0 != 4) || (kt_globals.ns == 0))
891 {
892 /* Set one-pole low-pass filter that tilts glottal source */
893
894 kt_globals.decay = (0.033 * frame->TLTdb);
895
896 if (kt_globals.decay > 0.0)
897 {
898 kt_globals.onemd = 1.0 - kt_globals.decay;
899 }
900 else
901 {
902 kt_globals.onemd = 1.0;
903 }
904 }
905 }
906
907
908
909 /*
910 function SETABC
911
912 Convert formant freqencies and bandwidth into resonator difference
913 equation constants.
914 */
915
916
setabc(long int f,long int bw,resonator_ptr rp)917 static void setabc(long int f, long int bw, resonator_ptr rp)
918 {
919 double r;
920 double arg;
921
922 /* Let r = exp(-pi bw t) */
923 arg = kt_globals.minus_pi_t * bw;
924 r = exp(arg);
925
926 /* Let c = -r**2 */
927 rp->c = -(r * r);
928
929 /* Let b = r * 2*cos(2 pi f t) */
930 arg = kt_globals.two_pi_t * f;
931 rp->b = r * cos(arg) * 2.0;
932
933 /* Let a = 1.0 - b - c */
934 rp->a = 1.0 - rp->b - rp->c;
935 }
936
937
938 /*
939 function SETZEROABC
940
941 Convert formant freqencies and bandwidth into anti-resonator difference
942 equation constants.
943 */
944
setzeroabc(long int f,long int bw,resonator_ptr rp)945 static void setzeroabc(long int f, long int bw, resonator_ptr rp)
946 {
947 double r;
948 double arg;
949
950 f = -f;
951
952 //NOTE, changes made 30.09.2011 for Reece Dunn <msclrhd@googlemail.com>
953 // fix a sound spike when f=0
954
955 /* First compute ordinary resonator coefficients */
956 /* Let r = exp(-pi bw t) */
957 arg = kt_globals.minus_pi_t * bw;
958 r = exp(arg);
959
960 /* Let c = -r**2 */
961 rp->c = -(r * r);
962
963 /* Let b = r * 2*cos(2 pi f t) */
964 arg = kt_globals.two_pi_t * f;
965 rp->b = r * cos(arg) * 2.;
966
967 /* Let a = 1.0 - b - c */
968 rp->a = 1.0 - rp->b - rp->c;
969
970 /* Now convert to antiresonator coefficients (a'=1/a, b'=b/a, c'=c/a) */
971 /* If f == 0 then rp->a gets set to 0 which makes a'=1/a set a', b' and c' to
972 * INF, causing an audible sound spike when triggered (e.g. apiration with the
973 * nasal register set to f=0, bw=0).
974 */
975 if (rp->a != 0)
976 {
977 /* Now convert to antiresonator coefficients (a'=1/a, b'=b/a, c'=c/a) */
978 rp->a = 1.0 / rp->a;
979 rp->c *= -rp->a;
980 rp->b *= -rp->a;
981 }
982 }
983
984
985 /*
986 function GEN_NOISE
987
988 Random number generator (return a number between -8191 and +8191)
989 Noise spectrum is tilted down by soft low-pass filter having a pole near
990 the origin in the z-plane, i.e. output = input + (0.75 * lastoutput)
991 */
992
993
gen_noise(double noise)994 static double gen_noise(double noise)
995 {
996 long temp;
997 static double nlast;
998
999 temp = (long) getrandom(-8191,8191);
1000 kt_globals.nrand = (long) temp;
1001
1002 noise = kt_globals.nrand + (0.75 * nlast);
1003 nlast = noise;
1004
1005 return(noise);
1006 }
1007
1008
1009 /*
1010 function DBTOLIN
1011
1012 Convert from decibels to a linear scale factor
1013
1014
1015 Conversion table, db to linear, 87 dB --> 32767
1016 86 dB --> 29491 (1 dB down = 0.5**1/6)
1017 ...
1018 81 dB --> 16384 (6 dB down = 0.5)
1019 ...
1020 0 dB --> 0
1021
1022 The just noticeable difference for a change in intensity of a vowel
1023 is approximately 1 dB. Thus all amplitudes are quantized to 1 dB
1024 steps.
1025 */
1026
1027
DBtoLIN(long dB)1028 static double DBtoLIN(long dB)
1029 {
1030 static short amptable[88] =
1031 {
1032 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7,
1033 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 28, 32,
1034 35, 40, 45, 51, 57, 64, 71, 80, 90, 101, 114, 128,
1035 142, 159, 179, 202, 227, 256, 284, 318, 359, 405,
1036 455, 512, 568, 638, 719, 881, 911, 1024, 1137, 1276,
1037 1438, 1622, 1823, 2048, 2273, 2552, 2875, 3244, 3645,
1038 4096, 4547, 5104, 5751, 6488, 7291, 8192, 9093, 10207,
1039 11502, 12976, 14582, 16384, 18350, 20644, 23429,
1040 26214, 29491, 32767 };
1041
1042 if ((dB < 0) || (dB > 87))
1043 {
1044 return(0);
1045 }
1046
1047 return((double)(amptable[dB]) * 0.001);
1048 }
1049
1050
1051
1052
1053
1054 extern voice_t *wvoice;
1055 static klatt_peaks_t peaks[N_PEAKS];
1056 static int end_wave;
1057 static int klattp[N_KLATTP];
1058 static double klattp1[N_KLATTP];
1059 static double klattp_inc[N_KLATTP];
1060
1061
1062
1063
Wavegen_Klatt(int resume)1064 int Wavegen_Klatt(int resume)
1065 {//==========================
1066 int pk;
1067 int x;
1068 int ix;
1069 int fade;
1070
1071 if(resume==0)
1072 {
1073 sample_count = 0;
1074 }
1075
1076 while(sample_count < nsamples)
1077 {
1078 kt_frame.F0hz10 = (wdata.pitch * 10) / 4096;
1079
1080 // formants F6,F7,F8 are fixed values for cascade resonators, set in KlattInit()
1081 // but F6 is used for parallel resonator
1082 // F0 is used for the nasal zero
1083 for(ix=0; ix < 6; ix++)
1084 {
1085 kt_frame.Fhz[ix] = peaks[ix].freq;
1086 if(ix < 4)
1087 {
1088 kt_frame.Bhz[ix] = peaks[ix].bw;
1089 }
1090 }
1091 for(ix=1; ix < 7; ix++)
1092 {
1093 kt_frame.Ap[ix] = peaks[ix].ap;
1094 }
1095
1096 kt_frame.AVdb = klattp[KLATT_AV];
1097 kt_frame.AVpdb = klattp[KLATT_AVp];
1098 kt_frame.AF = klattp[KLATT_Fric];
1099 kt_frame.AB = klattp[KLATT_FricBP];
1100 kt_frame.ASP = klattp[KLATT_Aspr];
1101 kt_frame.Aturb = klattp[KLATT_Turb];
1102 kt_frame.Kskew = klattp[KLATT_Skew];
1103 kt_frame.TLTdb = klattp[KLATT_Tilt];
1104 kt_frame.Kopen = klattp[KLATT_Kopen];
1105
1106 // advance formants
1107 for(pk=0; pk<N_PEAKS; pk++)
1108 {
1109 peaks[pk].freq1 += peaks[pk].freq_inc;
1110 peaks[pk].freq = (int)peaks[pk].freq1;
1111 peaks[pk].bw1 += peaks[pk].bw_inc;
1112 peaks[pk].bw = (int)peaks[pk].bw1;
1113 peaks[pk].bp1 += peaks[pk].bp_inc;
1114 peaks[pk].bp = (int)peaks[pk].bp1;
1115 peaks[pk].ap1 += peaks[pk].ap_inc;
1116 peaks[pk].ap = (int)peaks[pk].ap1;
1117 }
1118
1119 // advance other parameters
1120 for(ix=0; ix < N_KLATTP; ix++)
1121 {
1122 klattp1[ix] += klattp_inc[ix];
1123 klattp[ix] = (int)klattp1[ix];
1124 }
1125
1126 for(ix=0; ix<=6; ix++)
1127 {
1128 kt_frame.Fhz_next[ix] = peaks[ix].freq;
1129 if(ix < 4)
1130 {
1131 kt_frame.Bhz_next[ix] = peaks[ix].bw;
1132 }
1133 }
1134
1135 // advance the pitch
1136 wdata.pitch_ix += wdata.pitch_inc;
1137 if((ix = wdata.pitch_ix>>8) > 127) ix = 127;
1138 x = wdata.pitch_env[ix] * wdata.pitch_range;
1139 wdata.pitch = (x>>8) + wdata.pitch_base;
1140
1141 kt_globals.nspfr = (nsamples - sample_count);
1142 if(kt_globals.nspfr > STEPSIZE)
1143 kt_globals.nspfr = STEPSIZE;
1144
1145 frame_init(&kt_frame); /* get parameters for next frame of speech */
1146
1147 if(parwave(&kt_frame) == 1)
1148 {
1149 return(1); // output buffer is full
1150 }
1151 }
1152
1153 if(end_wave > 0)
1154 {
1155 #ifdef deleted
1156 if(end_wave == 2)
1157 {
1158 fade = (kt_globals.T0 - kt_globals.nper)/4; // samples until end of current cycle
1159 if(fade < 64)
1160 fade = 64;
1161 }
1162 else
1163 #endif
1164 {
1165 fade = 64; // not followd by formant synthesis
1166 }
1167
1168 // fade out to avoid a click
1169 kt_globals.fadeout = fade;
1170 end_wave = 0;
1171 sample_count -= fade;
1172 kt_globals.nspfr = fade;
1173 if(parwave(&kt_frame) == 1)
1174 {
1175 return(1); // output buffer is full
1176 }
1177 }
1178
1179 return(0);
1180 }
1181
1182
SetSynth_Klatt(int length,int modn,frame_t * fr1,frame_t * fr2,voice_t * v,int control)1183 void SetSynth_Klatt(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v, int control)
1184 {//===========================================================================================
1185 int ix;
1186 DOUBLEX next;
1187 int qix;
1188 int cmd;
1189 frame_t *fr3;
1190 static frame_t prev_fr;
1191
1192 if(wvoice != NULL)
1193 {
1194 if((wvoice->klattv[0] > 0) && (wvoice->klattv[0] <=4 ))
1195 {
1196 kt_globals.glsource = wvoice->klattv[0];
1197 kt_globals.scale_wav = scale_wav_tab[kt_globals.glsource];
1198 }
1199 kt_globals.f0_flutter = wvoice->flutter/32;
1200 }
1201
1202 end_wave = 0;
1203 if(control & 2)
1204 {
1205 end_wave = 1; // fadeout at the end
1206 }
1207 if(control & 1)
1208 {
1209 end_wave = 1;
1210 for(qix=wcmdq_head+1;;qix++)
1211 {
1212 if(qix >= N_WCMDQ) qix = 0;
1213 if(qix == wcmdq_tail) break;
1214
1215 cmd = wcmdq[qix][0];
1216 if(cmd==WCMD_KLATT)
1217 {
1218 end_wave = 0; // next wave generation is from another spectrum
1219
1220 fr3 = (frame_t *)wcmdq[qix][2];
1221 for(ix=1; ix<6; ix++)
1222 {
1223 if(fr3->ffreq[ix] != fr2->ffreq[ix])
1224 {
1225 // there is a discontinuity in formants
1226 end_wave = 2;
1227 break;
1228 }
1229 }
1230 break;
1231 }
1232 if((cmd==WCMD_WAVE) || (cmd==WCMD_PAUSE))
1233 break; // next is not from spectrum, so continue until end of wave cycle
1234 }
1235 }
1236
1237 #ifdef LOG_FRAMES
1238 if(option_log_frames)
1239 {
1240 FILE *f_log;
1241 f_log=fopen("log-espeakedit","a");
1242 if(f_log != NULL)
1243 {
1244 fprintf(f_log,"K %3dmS %3d %3d %4d %4d %4d %4d (%2d) to %3d %3d %4d %4d %4d %4d (%2d)\n",length*1000/samplerate,
1245 fr1->klattp[KLATT_FNZ]*2,fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3],fr1->ffreq[4],fr1->ffreq[5], fr1->klattp[KLATT_AV],
1246 fr2->klattp[KLATT_FNZ]*2,fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3],fr1->ffreq[4],fr1->ffreq[5], fr2->klattp[KLATT_AV] );
1247 fclose(f_log);
1248 }
1249 f_log=fopen("log-klatt","a");
1250 if(f_log != NULL)
1251 {
1252 fprintf(f_log,"K %3dmS %3d %3d %4d %4d (%2d) to %3d %3d %4d %4d (%2d)\n",length*1000/samplerate,
1253 fr1->klattp[KLATT_FNZ]*2,fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3], fr1->klattp[KLATT_AV],
1254 fr2->klattp[KLATT_FNZ]*2,fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3], fr2->klattp[KLATT_AV] );
1255
1256 fclose(f_log);
1257 }
1258 }
1259 #endif
1260
1261 if(control & 1)
1262 {
1263 for(ix=1; ix<6; ix++)
1264 {
1265 if(prev_fr.ffreq[ix] != fr1->ffreq[ix])
1266 {
1267 // Discontinuity in formants.
1268 // end_wave was set in SetSynth_Klatt() to fade out the previous frame
1269 KlattReset(0);
1270 break;
1271 }
1272 }
1273 memcpy(&prev_fr,fr2,sizeof(prev_fr));
1274 }
1275
1276 for(ix=0; ix<N_KLATTP; ix++)
1277 {
1278 if((ix >= 5) && ((fr1->frflags & FRFLAG_KLATT) == 0))
1279 {
1280 klattp1[ix] = klattp[ix] = 0;
1281 klattp_inc[ix] = 0;
1282 }
1283 else
1284 {
1285 klattp1[ix] = klattp[ix] = fr1->klattp[ix];
1286 klattp_inc[ix] = (double)((fr2->klattp[ix] - klattp[ix]) * STEPSIZE)/length;
1287 }
1288
1289 // get klatt parameter adjustments for the voice
1290 // if((ix>0) && (ix < KLATT_AVp))
1291 // klattp1[ix] = klattp[ix] = (klattp[ix] + wvoice->klattv[ix]);
1292 }
1293
1294 nsamples = length;
1295
1296 for(ix=1; ix < 6; ix++)
1297 {
1298 peaks[ix].freq1 = (fr1->ffreq[ix] * v->freq[ix] / 256.0) + v->freqadd[ix];
1299 peaks[ix].freq = (int)peaks[ix].freq1;
1300 next = (fr2->ffreq[ix] * v->freq[ix] / 256.0) + v->freqadd[ix];
1301 peaks[ix].freq_inc = ((next - peaks[ix].freq1) * STEPSIZE) / length;
1302
1303 if(ix < 4)
1304 {
1305 // klatt bandwidth for f1, f2, f3 (others are fixed)
1306 peaks[ix].bw1 = fr1->bw[ix] * 2;
1307 peaks[ix].bw = (int)peaks[ix].bw1;
1308 next = fr2->bw[ix] * 2;
1309 peaks[ix].bw_inc = ((next - peaks[ix].bw1) * STEPSIZE) / length;
1310 }
1311 }
1312
1313 // nasal zero frequency
1314 peaks[0].freq1 = fr1->klattp[KLATT_FNZ] * 2;
1315 if(peaks[0].freq1 == 0)
1316 peaks[0].freq1 = kt_frame.Fhz[F_NP]; // if no nasal zero, set it to same freq as nasal pole
1317
1318 peaks[0].freq = (int)peaks[0].freq1;
1319 next = fr2->klattp[KLATT_FNZ] * 2;
1320 if(next == 0)
1321 next = kt_frame.Fhz[F_NP];
1322
1323 peaks[0].freq_inc = ((next - peaks[0].freq1) * STEPSIZE) / length;
1324
1325 peaks[0].bw1 = 89;
1326 peaks[0].bw = 89;
1327 peaks[0].bw_inc = 0;
1328
1329 if(fr1->frflags & FRFLAG_KLATT)
1330 {
1331 // the frame contains additional parameters for parallel resonators
1332 for(ix=1; ix < 7; ix++)
1333 {
1334 peaks[ix].bp1 = fr1->klatt_bp[ix] * 4; // parallel bandwidth
1335 peaks[ix].bp = (int)peaks[ix].bp1;
1336 next = fr2->klatt_bp[ix] * 4;
1337 peaks[ix].bp_inc = ((next - peaks[ix].bp1) * STEPSIZE) / length;
1338
1339 peaks[ix].ap1 = fr1->klatt_ap[ix]; // parallal amplitude
1340 peaks[ix].ap = (int)peaks[ix].ap1;
1341 next = fr2->klatt_ap[ix];
1342 peaks[ix].ap_inc = ((next - peaks[ix].ap1) * STEPSIZE) / length;
1343 }
1344 }
1345 } // end of SetSynth_Klatt
1346
1347
Wavegen_Klatt2(int length,int modulation,int resume,frame_t * fr1,frame_t * fr2)1348 int Wavegen_Klatt2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2)
1349 {//===================================================================================
1350 if(resume==0)
1351 SetSynth_Klatt(length, modulation, fr1, fr2, wvoice, 1);
1352
1353 return(Wavegen_Klatt(resume));
1354 }
1355
1356
1357
KlattInit()1358 void KlattInit()
1359 {
1360
1361 static short formant_hz[10] = {280,688,1064,2806,3260,3700,6500,7000,8000,280};
1362 static short bandwidth[10] = {89,160,70,160,200,200,500,500,500,89};
1363 static short parallel_amp[10] = { 0,59,59,59,59,59,59,0,0,0};
1364 static short parallel_bw[10] = {59,59,89,149,200,200,500,0,0,0};
1365
1366 int ix;
1367
1368 for(ix=0; ix<256; ix++)
1369 {
1370 // TEST: Overwrite natural_samples2
1371 // sawtooth wave
1372 // natural_samples2[ix] = (128-ix) * 20;
1373 }
1374 sample_count=0;
1375
1376 kt_globals.synthesis_model = CASCADE_PARALLEL;
1377 kt_globals.samrate = 22050;
1378
1379 kt_globals.glsource = IMPULSIVE; // IMPULSIVE, NATURAL, SAMPLED
1380 kt_globals.scale_wav = scale_wav_tab[kt_globals.glsource];
1381 kt_globals.natural_samples = natural_samples;
1382 kt_globals.num_samples = NUMBER_OF_SAMPLES;
1383 kt_globals.sample_factor = 3.0;
1384 kt_globals.nspfr = (kt_globals.samrate * 10) / 1000;
1385 kt_globals.outsl = 0;
1386 kt_globals.f0_flutter = 20;
1387
1388 KlattReset(2);
1389
1390 // set default values for frame parameters
1391 for(ix=0; ix<=9; ix++)
1392 {
1393 kt_frame.Fhz[ix] = formant_hz[ix];
1394 kt_frame.Bhz[ix] = bandwidth[ix];
1395 kt_frame.Ap[ix] = parallel_amp[ix];
1396 kt_frame.Bphz[ix] = parallel_bw[ix];
1397 }
1398 kt_frame.Bhz_next[F_NZ] = bandwidth[F_NZ];
1399
1400 kt_frame.F0hz10 = 1000;
1401 kt_frame.AVdb = 59; // 59
1402 kt_frame.ASP = 0;
1403 kt_frame.Kopen = 40; // 40
1404 kt_frame.Aturb = 0;
1405 kt_frame.TLTdb = 0;
1406 kt_frame.AF =50;
1407 kt_frame.Kskew = 0;
1408 kt_frame.AB = 0;
1409 kt_frame.AVpdb = 0;
1410 kt_frame.Gain0 = 62; // 60
1411 } // end of KlattInit
1412
1413 #endif // INCLUDE_KLATT
1414