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