1 /* Automatically generated from Squeak on 30 July 2012 4:52:45 pm
2    by VMMaker 4.9.8
3  */
4 
5 #include <math.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <time.h>
10 
11 /* Default EXPORT macro that does nothing (see comment in sq.h): */
12 #define EXPORT(returnType) returnType
13 
14 /* Do not include the entire sq.h file but just those parts needed. */
15 /*  The virtual machine proxy definition */
16 #include "sqVirtualMachine.h"
17 /* Configuration options */
18 #include "sqConfig.h"
19 /* Platform specific definitions */
20 #include "sqPlatformSpecific.h"
21 
22 #define true 1
23 #define false 0
24 #define null 0  /* using 'null' because nil is predefined in Think C */
25 #ifdef SQUEAK_BUILTIN_PLUGIN
26 #undef EXPORT
27 // was #undef EXPORT(returnType) but screws NorCroft cc
28 #define EXPORT(returnType) static returnType
29 #endif
30 
31 #include "sqMemoryAccess.h"
32 
33 
34 /*** Constants ***/
35 #define A1v 46
36 #define A2f 34
37 #define A2v 47
38 #define A3f 35
39 #define A3v 48
40 #define A4f 36
41 #define A4v 49
42 #define A5f 37
43 #define A6f 38
44 #define Anv 45
45 #define Aspiration 9
46 #define Atv 50
47 #define B1 13
48 #define B2 17
49 #define B2f 40
50 #define B3 19
51 #define B3f 41
52 #define B4 21
53 #define B4f 42
54 #define B5 23
55 #define B5f 43
56 #define B6 25
57 #define B6f 44
58 #define Bnp 27
59 #define Bnz 29
60 #define Btp 31
61 #define Btz 33
62 #define Bypass 39
63 #define Diplophonia 4
64 #define Epsilon 0.0001
65 #define F0 0
66 #define F1 12
67 #define F2 16
68 #define F3 18
69 #define F4 20
70 #define F5 22
71 #define F6 24
72 #define Flutter 1
73 #define Fnp 26
74 #define Fnz 28
75 #define Friction 10
76 #define Ftp 30
77 #define Ftz 32
78 #define Gain 51
79 #define Jitter 2
80 #define PI 3.141592653589793
81 #define R1c 12
82 #define R1vp 3
83 #define R2c 13
84 #define R2fp 7
85 #define R2vp 4
86 #define R3c 14
87 #define R3fp 8
88 #define R3vp 5
89 #define R4c 15
90 #define R4fp 9
91 #define R4vp 6
92 #define R5c 16
93 #define R5fp 10
94 #define R6c 17
95 #define R6fp 11
96 #define R7c 18
97 #define R8c 19
98 #define Ra 7
99 #define Rk 8
100 #define Rnpc 20
101 #define Rnpp 1
102 #define Rnz 21
103 #define Ro 6
104 #define Rout 24
105 #define Rtpc 22
106 #define Rtpp 2
107 #define Rtz 23
108 #define Shimmer 3
109 #define Turbulence 11
110 #define Voicing 5
111 
112 /*** Function Prototypes ***/
113 static void addFlutter(void);
114 static void antiResonatorfrequencybandwidth(sqInt index, float  freq, float  bw);
115 #pragma export on
116 EXPORT(const char*) getModuleName(void);
117 #pragma export off
118 static sqInt halt(void);
119 static sqInt loadFrom(sqInt klattOop);
120 static sqInt nextRandom(void);
121 #pragma export on
122 EXPORT(sqInt) primitiveSynthesizeFrameIntoStartingAt(void);
123 #pragma export off
124 static float quphicosphisinphirphid(float  u, float  phi, float  cosphi, float  sinphi, float  rphid);
125 static void resonatorfrequencybandwidth(sqInt index, float  freq, float  bw);
126 static void resonatorfrequencybandwidthgain(sqInt index, float  freq, float  bw, float  gain);
127 static float resonatorvalue(sqInt index, float  aFloat);
128 static void rorark(float  roNumber, float  raNumber, float  rkNumber);
129 static sqInt saveTo(sqInt origKlattOop);
130 static void setCurrentFrame(float *aKlattFrame);
131 #pragma export on
132 EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
133 #pragma export off
134 static void synthesizeFrameintostartingAt(float *aKlattFrame, short *buffer, sqInt startIndex);
135 static float zeroQphicosphisinphirphid(float  phi, float  cosphi, float  sinphi, float  rphid);
136 /*** Variables ***/
137 static float a1;
138 static float a2;
139 static float b1;
140 static float c1;
141 static sqInt cascade;
142 static float * frame;
143 static float glast;
144 
145 #ifdef SQUEAK_BUILTIN_PLUGIN
146 extern
147 #endif
148 struct VirtualMachine* interpreterProxy;
149 static const char *moduleName =
150 #ifdef SQUEAK_BUILTIN_PLUGIN
151 	"Klatt 30 July 2012 (i)"
152 #else
153 	"Klatt 30 July 2012 (e)"
154 #endif
155 ;
156 static float nlast;
157 static sqInt nmod;
158 static sqInt nopen;
159 static sqInt nper;
160 static sqInt periodCount;
161 static float pitch;
162 static float * resonators;
163 static sqInt samplesCount;
164 static sqInt samplesPerFrame;
165 static sqInt samplingRate;
166 static sqInt seed;
167 static sqInt t0;
168 static float vlast;
169 static float x1;
170 static float x2;
171 
172 
173 
174 /*	Add F0 flutter, as specified in:
175 		'Analysis, synthesis and perception of voice quality variations among
176 		female and male talkers' D.H. Klatt and L.C. Klatt JASA 87(2) February 1990.
177 	Flutter is added by applying a quasi-random element constructed from three
178 	slowly varying sine waves. */
179 
addFlutter(void)180 static void addFlutter(void) {
181     float  asin;
182     float  bsin;
183     float  csin;
184     double  deltaF0;
185     float  timeCount;
186 
187 	timeCount = (((float) samplesCount)) / (((float) samplingRate));
188 	asin = sin(((2.0 * PI) * 12.7) * timeCount);
189 	bsin = sin(((2.0 * PI) * 7.1) * timeCount);
190 	csin = sin(((2.0 * PI) * 4.7) * timeCount);
191 	deltaF0 = ((((frame[Flutter]) * 2.0) * (frame[F0])) / 100.0) * ((asin + bsin) + csin);
192 	pitch += deltaF0;
193 }
194 
195 
196 /*	Set up an anti-resonator */
197 
antiResonatorfrequencybandwidth(sqInt index,float freq,float bw)198 static void antiResonatorfrequencybandwidth(sqInt index, float  freq, float  bw) {
199     float  a;
200     double  arg;
201     float  b;
202     float  c;
203     float  r;
204 
205 	arg = ((0.0 - PI) / samplingRate) * bw;
206 	r = exp(arg);
207 	c = 0.0 - (r * r);
208 	arg = ((PI * 2.0) / samplingRate) * freq;
209 	b = (r * (cos(arg))) * 2.0;
210 	a = (1.0 - b) - c;
211 	a = 1.0 / a;
212 	b = (0.0 - b) * a;
213 	c = (0.0 - c) * a;
214 	/* begin resonatorA:put: */
215 	resonators[(index * 5) - 5] = a;
216 	/* begin resonatorB:put: */
217 	resonators[(index * 5) - 4] = b;
218 	/* begin resonatorC:put: */
219 	resonators[(index * 5) - 3] = c;
220 }
221 
222 
223 /*	Note: This is hardcoded so it can be run from Squeak.
224 	The module name is used for validating a module *after*
225 	it is loaded to check if it does really contain the module
226 	we're thinking it contains. This is important! */
227 
getModuleName(void)228 EXPORT(const char*) getModuleName(void) {
229 	return moduleName;
230 }
231 
halt(void)232 static sqInt halt(void) {
233 	;
234 }
235 
loadFrom(sqInt klattOop)236 static sqInt loadFrom(sqInt klattOop) {
237     sqInt oop;
238 
239 	interpreterProxy->success((interpreterProxy->slotSizeOf(klattOop)) == 22);
240 	if (interpreterProxy->failed()) {
241 		return 0;
242 	}
243 	oop = interpreterProxy->fetchPointerofObject(0, klattOop);
244 	/* begin checkedFloatPtrOf: */
245 	interpreterProxy->success(interpreterProxy->isWords(oop));
246 	if (interpreterProxy->failed()) {
247 		resonators = 0;
248 		goto l1;
249 	}
250 	resonators = ((float *) (interpreterProxy->firstIndexableField(oop)));
251 l1:	/* end checkedFloatPtrOf: */;
252 	pitch = interpreterProxy->fetchFloatofObject(2, klattOop);
253 	t0 = interpreterProxy->fetchIntegerofObject(3, klattOop);
254 	nper = interpreterProxy->fetchIntegerofObject(4, klattOop);
255 	nopen = interpreterProxy->fetchIntegerofObject(5, klattOop);
256 	nmod = interpreterProxy->fetchIntegerofObject(6, klattOop);
257 	a1 = interpreterProxy->fetchFloatofObject(7, klattOop);
258 	a2 = interpreterProxy->fetchFloatofObject(8, klattOop);
259 	x1 = interpreterProxy->fetchFloatofObject(9, klattOop);
260 	x2 = interpreterProxy->fetchFloatofObject(10, klattOop);
261 	b1 = interpreterProxy->fetchFloatofObject(11, klattOop);
262 	c1 = interpreterProxy->fetchFloatofObject(12, klattOop);
263 	glast = interpreterProxy->fetchFloatofObject(13, klattOop);
264 	vlast = interpreterProxy->fetchFloatofObject(14, klattOop);
265 	nlast = interpreterProxy->fetchFloatofObject(15, klattOop);
266 	periodCount = interpreterProxy->fetchIntegerofObject(16, klattOop);
267 	samplesCount = interpreterProxy->fetchIntegerofObject(17, klattOop);
268 	seed = interpreterProxy->fetchIntegerofObject(18, klattOop);
269 	cascade = interpreterProxy->fetchIntegerofObject(19, klattOop);
270 	samplesPerFrame = interpreterProxy->fetchIntegerofObject(20, klattOop);
271 	samplingRate = interpreterProxy->fetchIntegerofObject(21, klattOop);
272 	return (interpreterProxy->failed()) == 0;
273 }
274 
275 
276 /*	Answer a random number between 0 and 65535. */
277 
nextRandom(void)278 static sqInt nextRandom(void) {
279 	seed = ((seed * 1309) + 13849) & 65535;
280 	return seed;
281 }
282 
primitiveSynthesizeFrameIntoStartingAt(void)283 EXPORT(sqInt) primitiveSynthesizeFrameIntoStartingAt(void) {
284     float * aKlattFrame;
285     short * buffer;
286     sqInt bufferOop;
287     sqInt rcvr;
288     sqInt startIndex;
289     sqInt oop;
290     sqInt oop1;
291 
292 	/* begin checkedFloatPtrOf: */
293 	oop = interpreterProxy->stackValue(2);
294 	interpreterProxy->success(interpreterProxy->isWords(oop));
295 	if (interpreterProxy->failed()) {
296 		aKlattFrame = 0;
297 		goto l1;
298 	}
299 	aKlattFrame = ((float *) (interpreterProxy->firstIndexableField(oop)));
300 l1:	/* end checkedFloatPtrOf: */;
301 	/* begin checkedShortPtrOf: */
302 	oop1 = (bufferOop = interpreterProxy->stackValue(1));
303 	interpreterProxy->success(interpreterProxy->isWords(oop1));
304 	if (interpreterProxy->failed()) {
305 		buffer = 0;
306 		goto l2;
307 	}
308 	buffer = ((short *) (interpreterProxy->firstIndexableField(oop1)));
309 l2:	/* end checkedShortPtrOf: */;
310 	startIndex = interpreterProxy->stackIntegerValue(0);
311 	if (interpreterProxy->failed()) {
312 		return null;
313 	}
314 	rcvr = interpreterProxy->stackObjectValue(3);
315 	if (!(loadFrom(rcvr))) {
316 		return null;
317 	}
318 	interpreterProxy->success(((interpreterProxy->stSizeOf(bufferOop)) * 2) >= samplesPerFrame);
319 	if (interpreterProxy->failed()) {
320 		return null;
321 	}
322 	synthesizeFrameintostartingAt(aKlattFrame, buffer, startIndex);
323 	if (!(saveTo(rcvr))) {
324 		return null;
325 	}
326 	interpreterProxy->pop(3);
327 }
328 
quphicosphisinphirphid(float u,float phi,float cosphi,float sinphi,float rphid)329 static float quphicosphisinphirphid(float  u, float  phi, float  cosphi, float  sinphi, float  rphid) {
330     float  expuphi;
331 
332 	expuphi = exp(u * phi);
333 	return (expuphi * ((((rphid * ((u * u) + 1.0)) + u) * sinphi) - cosphi)) + 1.0;
334 }
335 
336 
337 /*	Convert formant frequencies and bandwidth into
338 	resonator difference equation coefficients. */
339 
resonatorfrequencybandwidth(sqInt index,float freq,float bw)340 static void resonatorfrequencybandwidth(sqInt index, float  freq, float  bw) {
341     float  a;
342     double  arg;
343     float  b;
344     float  c;
345     float  r;
346 
347 	arg = ((0.0 - PI) / samplingRate) * bw;
348 	r = exp(arg);
349 	c = 0.0 - (r * r);
350 	arg = ((PI * 2.0) / samplingRate) * freq;
351 	b = (r * (cos(arg))) * 2.0;
352 	a = (1.0 - b) - c;
353 	/* begin resonatorA:put: */
354 	resonators[(index * 5) - 5] = a;
355 	/* begin resonatorB:put: */
356 	resonators[(index * 5) - 4] = b;
357 	/* begin resonatorC:put: */
358 	resonators[(index * 5) - 3] = c;
359 }
360 
361 
362 /*	Convert formant frequencies and bandwidth into
363 	resonator difference equation coefficients. */
364 
resonatorfrequencybandwidthgain(sqInt index,float freq,float bw,float gain)365 static void resonatorfrequencybandwidthgain(sqInt index, float  freq, float  bw, float  gain) {
366 	resonatorfrequencybandwidth(index, freq, bw);
367 	/* begin resonatorA:put: */
368 	resonators[(index * 5) - 5] = ((resonators[(index * 5) - 5]) * gain);
369 }
370 
resonatorvalue(sqInt index,float aFloat)371 static float resonatorvalue(sqInt index, float  aFloat) {
372     float  answer;
373     float  p1;
374 
375 
376 	/* (p1 between: -100000 and: 100000) ifFalse: [self halt].
377 	(answer between: -100000 and: 100000) ifFalse: [self halt]. */
378 
379 	answer = (((resonators[(index * 5) - 5]) * aFloat) + ((resonators[(index * 5) - 4]) * ((p1 = resonators[(index * 5) - 2])))) + ((resonators[(index * 5) - 3]) * (resonators[(index * 5) - 1]));
380 	/* begin resonatorP2:put: */
381 	resonators[(index * 5) - 1] = p1;
382 	/* begin resonatorP1:put: */
383 	resonators[(index * 5) - 2] = answer;
384 	return answer;
385 }
386 
rorark(float roNumber,float raNumber,float rkNumber)387 static void rorark(float  roNumber, float  raNumber, float  rkNumber) {
388     float  cosphi;
389     float  d;
390     float  gamma;
391     float  gammapwr;
392     float  phi;
393     float  r;
394     float  ra;
395     float  rho;
396     float  rk;
397     float  ro;
398     float  rphid;
399     float  sinphi;
400     sqInt te;
401     float  theta;
402     float  u;
403     sqInt ingore;
404     float  s0;
405     float  s1;
406     float  s2;
407 
408 	te = ((sqInt)(t0 * roNumber));
409 	ro = (((double) te )) / (((double) t0 ));
410 	rk = rkNumber;
411 	ra = raNumber;
412 	if (ra <= 0.0) {
413 		d = 1.0;
414 	} else {
415 		r = (1.0 - ro) / ra;
416 		d = 1.0 - (r / ((exp(r)) - 1.0));
417 	}
418 	phi = PI * (rk + 1.0);
419 	cosphi = cos(phi);
420 	sinphi = sin(phi);
421 	rphid = ((ra / ro) * phi) * d;
422 	u = zeroQphicosphisinphirphid(phi, cosphi, sinphi, rphid);
423 	theta = phi / te;
424 	rho = exp(u * theta);
425 	a1 = (2.0 * (cos(theta))) * rho;
426 	a2 = 0.0 - (rho * rho);
427 	x2 = 0.0;
428 	x1 = rho * (sin(theta));
429 	gamma = exp(-1.0 / (ra * t0));
430 	gammapwr = pow(gamma,(t0 - te));
431 	b1 = gamma;
432 	c1 = ((1.0 - gamma) * gammapwr) / (1.0 - gammapwr);
433 	/* begin normalizeGlottalPulse */
434 	s0 = 0.0;
435 	s1 = x1;
436 	s2 = x2;
437 	for (ingore = 1; ingore <= nopen; ingore += 1) {
438 		s0 = (a1 * s1) + (a2 * s2);
439 		s2 = s1;
440 		s1 = s0;
441 	}
442 	if (!(s0 == 0.0)) {
443 		x1 = (x1 / s0) * 10000.0;
444 	}
445 }
446 
saveTo(sqInt origKlattOop)447 static sqInt saveTo(sqInt origKlattOop) {
448     sqInt a1Oop;
449     sqInt a2Oop;
450     sqInt b1Oop;
451     sqInt c1Oop;
452     sqInt glastOop;
453     sqInt klattOop;
454     sqInt nlastOop;
455     sqInt pitchOop;
456     sqInt vlastOop;
457     sqInt x1Oop;
458     sqInt x2Oop;
459 
460 	interpreterProxy->pushRemappableOop(origKlattOop);
461 	interpreterProxy->pushRemappableOop(interpreterProxy->floatObjectOf(pitch));
462 	interpreterProxy->pushRemappableOop(interpreterProxy->floatObjectOf(a1));
463 	interpreterProxy->pushRemappableOop(interpreterProxy->floatObjectOf(a2));
464 	interpreterProxy->pushRemappableOop(interpreterProxy->floatObjectOf(x1));
465 	interpreterProxy->pushRemappableOop(interpreterProxy->floatObjectOf(x2));
466 	interpreterProxy->pushRemappableOop(interpreterProxy->floatObjectOf(b1));
467 	interpreterProxy->pushRemappableOop(interpreterProxy->floatObjectOf(c1));
468 	interpreterProxy->pushRemappableOop(interpreterProxy->floatObjectOf(glast));
469 	interpreterProxy->pushRemappableOop(interpreterProxy->floatObjectOf(vlast));
470 	nlastOop = interpreterProxy->floatObjectOf(nlast);
471 	vlastOop = interpreterProxy->popRemappableOop();
472 	glastOop = interpreterProxy->popRemappableOop();
473 	c1Oop = interpreterProxy->popRemappableOop();
474 	b1Oop = interpreterProxy->popRemappableOop();
475 	x2Oop = interpreterProxy->popRemappableOop();
476 	x1Oop = interpreterProxy->popRemappableOop();
477 	a2Oop = interpreterProxy->popRemappableOop();
478 	a1Oop = interpreterProxy->popRemappableOop();
479 	pitchOop = interpreterProxy->popRemappableOop();
480 	klattOop = interpreterProxy->popRemappableOop();
481 	if (interpreterProxy->failed()) {
482 		return 0;
483 	}
484 	interpreterProxy->storePointerofObjectwithValue(2, klattOop, pitchOop);
485 	interpreterProxy->storeIntegerofObjectwithValue(3, klattOop, t0);
486 	interpreterProxy->storeIntegerofObjectwithValue(4, klattOop, nper);
487 	interpreterProxy->storeIntegerofObjectwithValue(5, klattOop, nopen);
488 	interpreterProxy->storeIntegerofObjectwithValue(6, klattOop, nmod);
489 	interpreterProxy->storePointerofObjectwithValue(7, klattOop, a1Oop);
490 	interpreterProxy->storePointerofObjectwithValue(8, klattOop, a2Oop);
491 	interpreterProxy->storePointerofObjectwithValue(9, klattOop, x1Oop);
492 	interpreterProxy->storePointerofObjectwithValue(10, klattOop, x2Oop);
493 	interpreterProxy->storePointerofObjectwithValue(11, klattOop, b1Oop);
494 	interpreterProxy->storePointerofObjectwithValue(12, klattOop, c1Oop);
495 	interpreterProxy->storePointerofObjectwithValue(13, klattOop, glastOop);
496 	interpreterProxy->storePointerofObjectwithValue(14, klattOop, vlastOop);
497 	interpreterProxy->storePointerofObjectwithValue(15, klattOop, nlastOop);
498 	interpreterProxy->storeIntegerofObjectwithValue(16, klattOop, periodCount);
499 	interpreterProxy->storeIntegerofObjectwithValue(17, klattOop, samplesCount);
500 	interpreterProxy->storeIntegerofObjectwithValue(18, klattOop, seed);
501 	return (interpreterProxy->failed()) == 0;
502 }
503 
setCurrentFrame(float * aKlattFrame)504 static void setCurrentFrame(float *aKlattFrame) {
505     float  ampF1V;
506     float  ampF2F;
507     float  ampF2V;
508     float  ampF3F;
509     float  ampF3V;
510     float  ampF4F;
511     float  ampF4V;
512     float  ampF5F;
513     float  ampF6F;
514     float  ampFNV;
515     float  ampFTV;
516 
517 
518 	/* Fudge factors... */
519 
520 	frame = aKlattFrame;
521 
522 	/* -4.44 dB */
523 
524 	ampFNV = ((pow(2.0,(((frame[Anv]) - 87.0) / 6.0))) * 32.767) * 0.6;
525 
526 	/* -4.44 dB */
527 
528 	ampFTV = ((pow(2.0,(((frame[Atv]) - 87.0) / 6.0))) * 32.767) * 0.6;
529 
530 	/* -7.96 dB */
531 
532 	ampF1V = ((pow(2.0,(((frame[A1v]) - 87.0) / 6.0))) * 32.767) * 0.4;
533 
534 	/* -16.5 dB */
535 
536 	ampF2V = ((pow(2.0,(((frame[A2v]) - 87.0) / 6.0))) * 32.767) * 0.15;
537 
538 	/* -24.4 dB */
539 
540 	ampF3V = ((pow(2.0,(((frame[A3v]) - 87.0) / 6.0))) * 32.767) * 0.06;
541 
542 	/* -28.0 dB */
543 
544 	ampF4V = ((pow(2.0,(((frame[A4v]) - 87.0) / 6.0))) * 32.767) * 0.04;
545 
546 	/* -16.5 dB */
547 
548 	ampF2F = ((pow(2.0,(((frame[A2f]) - 87.0) / 6.0))) * 32.767) * 0.15;
549 
550 	/* -24.4 dB */
551 
552 	ampF3F = ((pow(2.0,(((frame[A3f]) - 87.0) / 6.0))) * 32.767) * 0.06;
553 
554 	/* -28.0 dB */
555 
556 	ampF4F = ((pow(2.0,(((frame[A4f]) - 87.0) / 6.0))) * 32.767) * 0.04;
557 
558 	/* -33.2 dB */
559 
560 	ampF5F = ((pow(2.0,(((frame[A5f]) - 87.0) / 6.0))) * 32.767) * 0.022;
561 
562 	/* -30.5 dB */
563 	/* Set coefficients of variable cascade resonators */
564 
565 	ampF6F = ((pow(2.0,(((frame[A6f]) - 87.0) / 6.0))) * 32.767) * 0.03;
566 	if (cascade >= 8) {
567 		if (samplingRate >= 16000) {
568 			resonatorfrequencybandwidth(R8c, 7500, 600);
569 		} else {
570 			cascade = 6;
571 		}
572 	}
573 	if (cascade >= 7) {
574 		if (samplingRate >= 16000) {
575 			resonatorfrequencybandwidth(R7c, 6500, 500);
576 		} else {
577 			cascade = 6;
578 		}
579 	}
580 	if (cascade >= 6) {
581 		resonatorfrequencybandwidth(R6c, frame[F6], frame[B6]);
582 	}
583 	if (cascade >= 5) {
584 		resonatorfrequencybandwidth(R5c, frame[F5], frame[B5]);
585 	}
586 	resonatorfrequencybandwidth(R4c, frame[F4], frame[B4]);
587 	resonatorfrequencybandwidth(R3c, frame[F3], frame[B3]);
588 	resonatorfrequencybandwidth(R2c, frame[F2], frame[B2]);
589 	resonatorfrequencybandwidth(R1c, frame[F1], frame[B1]);
590 	resonatorfrequencybandwidth(Rnpc, frame[Fnp], frame[Bnp]);
591 	resonatorfrequencybandwidth(Rtpc, frame[Ftp], frame[Btp]);
592 	antiResonatorfrequencybandwidth(Rnz, frame[Fnz], frame[Bnz]);
593 	antiResonatorfrequencybandwidth(Rtz, frame[Ftz], frame[Btz]);
594 	resonatorfrequencybandwidthgain(Rnpp, frame[Fnp], frame[Bnp], ampFNV);
595 	resonatorfrequencybandwidthgain(Rtpp, frame[Ftp], frame[Btp], ampFTV);
596 	resonatorfrequencybandwidthgain(R1vp, frame[F1], frame[B1], ampF1V);
597 	resonatorfrequencybandwidthgain(R2vp, frame[F2], frame[B2], ampF2V);
598 	resonatorfrequencybandwidthgain(R3vp, frame[F3], frame[B3], ampF3V);
599 	resonatorfrequencybandwidthgain(R4vp, frame[F4], frame[B4], ampF4V);
600 	resonatorfrequencybandwidthgain(R2fp, frame[F2], frame[B2f], ampF2F);
601 	resonatorfrequencybandwidthgain(R3fp, frame[F3], frame[B3f], ampF3F);
602 	resonatorfrequencybandwidthgain(R4fp, frame[F4], frame[B4f], ampF4F);
603 	resonatorfrequencybandwidthgain(R5fp, frame[F5], frame[B5f], ampF5F);
604 	resonatorfrequencybandwidthgain(R6fp, frame[F6], frame[B6f], ampF6F);
605 }
606 
607 
608 /*	Note: This is coded so that is can be run from Squeak. */
609 
setInterpreter(struct VirtualMachine * anInterpreter)610 EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter) {
611     sqInt ok;
612 
613 	interpreterProxy = anInterpreter;
614 	ok = interpreterProxy->majorVersion() == VM_PROXY_MAJOR;
615 	if (ok == 0) {
616 		return 0;
617 	}
618 	ok = interpreterProxy->minorVersion() >= VM_PROXY_MINOR;
619 	return ok;
620 }
621 
synthesizeFrameintostartingAt(float * aKlattFrame,short * buffer,sqInt startIndex)622 static void synthesizeFrameintostartingAt(float *aKlattFrame, short *buffer, sqInt startIndex) {
623     float  ampGain;
624     float  aspiration;
625     float  aspirationNoise;
626     float  bypass;
627     float  friction;
628     float  frictionNoise;
629     float  gain;
630     float  glotout;
631     sqInt index;
632     float  noise;
633     float out;
634     float  parGlotout;
635     float  parVoicing;
636     float  source;
637     sqInt temp;
638     sqInt top;
639     float  turbulence;
640     float voice;
641     float  voicing;
642     float  x0;
643     float out1;
644     float  answer;
645     float  p1;
646     float  answer1;
647     float  p11;
648     float  answer2;
649     float  p12;
650     float  answer3;
651     float  p13;
652     float  answer4;
653     float  p14;
654     float  answer5;
655     float  p15;
656     float  answer6;
657     float  p16;
658     float  answer7;
659     float  p17;
660     double  answer8;
661     double  p18;
662     float  answer9;
663     float  p19;
664     double  answer10;
665     double  p110;
666     float  answer11;
667     float  p111;
668     float  answer12;
669     float  p112;
670 
671 	setCurrentFrame(aKlattFrame);
672 	if (pitch > 0) {
673 		voicing = (pow(2.0,((((frame[Voicing]) - 7) - 87.0) / 6.0))) * 32.767;
674 		parVoicing = (pow(2.0,(((frame[Voicing]) - 87.0) / 6.0))) * 32.767;
675 		turbulence = ((pow(2.0,(((frame[Turbulence]) - 87.0) / 6.0))) * 32.767) * 0.1;
676 	} else {
677 		voicing = (parVoicing = (turbulence = 0.0));
678 	}
679 	friction = ((pow(2.0,(((frame[Friction]) - 87.0) / 6.0))) * 32.767) * 0.25;
680 	aspiration = ((pow(2.0,(((frame[Aspiration]) - 87.0) / 6.0))) * 32.767) * 0.05;
681 
682 	/* -26.0 dB */
683 	/* Flod overall gain into output resonator (low-pass filter) */
684 
685 	bypass = ((pow(2.0,(((frame[Bypass]) - 87.0) / 6.0))) * 32.767) * 0.05;
686 	gain = (frame[Gain]) - 3;
687 	if (gain <= 0) {
688 		gain = 57;
689 	}
690 	ampGain = (pow(2.0,((gain - 87.0) / 6.0))) * 32.767;
691 	resonatorfrequencybandwidthgain(Rout, 0, samplingRate, ampGain);
692 	noise = nlast;
693 	index = startIndex;
694 	top = (samplesPerFrame + startIndex) - 1;
695 	while (index <= top) {
696 
697 		/* Get low-passed random number for aspiration and friction noise */
698 		/* radom number between -8196.0 and 8196.0 */
699 		/* Tilt down noise spectrum by soft low-pass filter having
700 		 a pole near the origin in the z-plane. */
701 
702 		noise = (((double) ((nextRandom()) - 32768) )) / 4.0;
703 		noise += 0.75 * nlast;
704 
705 		/* Amplitude modulate noise (reduce noise amplitude during second
706 		 half of glottal period) if voicing  simultaneously present. */
707 
708 		nlast = noise;
709 		if (nper > nmod) {
710 			noise = noise * 0.5;
711 		}
712 
713 		/* Compute voicing waveform. */
714 
715 		frictionNoise = friction * noise;
716 		/* begin glottalSource */
717 		if (t0 == 0) {
718 			voice = 0;
719 			goto l1;
720 		}
721 		if (nper < nopen) {
722 			x0 = (a1 * x1) + (a2 * x2);
723 			x2 = x1;
724 			x1 = x0;
725 		} else {
726 			x0 = (b1 * x1) - c1;
727 			x1 = x0;
728 		}
729 		if (nper >= t0) {
730 			nper = 0;
731 			/* begin pitchSynchronousReset */
732 			if ((frame[F0]) > 0) {
733 				/* begin voicedPitchSynchronousReset */
734 				pitch = frame[F0];
735 				addFlutter();
736 				/* begin addJitter */
737 				pitch += ((((nextRandom()) - 32767) * (frame[Jitter])) / 32768.0) * (frame[F0]);
738 				/* begin addFrequencyDiplophonia */
739 				if ((periodCount % 2) == 0) {
740 					pitch += ((frame[Diplophonia]) * (frame[F0])) * (1.0 - (frame[Ro]));
741 				} else {
742 					pitch -= ((frame[Diplophonia]) * (frame[F0])) * (1.0 - (frame[Ro]));
743 				}
744 				if (pitch < 0) {
745 					pitch = 0;
746 				}
747 				t0 = ((sqInt)(samplingRate / pitch));
748 				nmod = t0;
749 				if ((frame[Voicing]) > 0) {
750 					nmod = ((sqInt) nmod >> 1);
751 				}
752 				nopen = ((sqInt)(t0 * (frame[Ro])));
753 				rorark(frame[Ro], frame[Ra], frame[Rk]);
754 				/* begin addShimmer */
755 				x1 += ((((nextRandom()) - 32767) * (frame[Shimmer])) / 32768.0) * x1;
756 				if (x1 > 0) {
757 					x1 = 0;
758 				}
759 				/* begin addAmplitudeDiplophonia */
760 				if (!((periodCount % 2) == 0)) {
761 					x1 = x1 * (1.0 - (frame[Diplophonia]));
762 					if (x1 > 0) {
763 						x1 = 0;
764 					}
765 				}
766 				periodCount = (periodCount + 1) % 65535;
767 			} else {
768 				t0 = 1;
769 				nmod = t0;
770 			}
771 		}
772 		nper += 1;
773 		voice = x0;
774 	l1:	/* end glottalSource */;
775 
776 		/* Add turbulence during glottal open phase.
777 		 Use random rather than noise because noise is low-passed. */
778 
779 		vlast = voice;
780 		if (nper < nopen) {
781 			voice += (turbulence * (((double) ((nextRandom()) - 32768) ))) / 4.0;
782 		}
783 		glotout = voicing * voice;
784 
785 		/* Compute aspiration amplitude and add to voicing source. */
786 
787 		parGlotout = parVoicing * voice;
788 		aspirationNoise = aspiration * noise;
789 		glotout += aspirationNoise;
790 
791 		/* Cascade vocal tract, excited by laryngeal sources.
792 		 Nasal antiresonator, nasal resonator, trachearl antirresonator,
793 		 tracheal resonator, then formants F8, F7, F6, F5, F4, F3, F2, F1. */
794 
795 		parGlotout += aspirationNoise;
796 		/* begin cascadeBranch: */
797 		if (!(cascade > 0)) {
798 			out = 0.0;
799 			goto l2;
800 		}
801 		/* begin antiResonator:value: */
802 		answer8 = (((resonators[(Rnz * 5) - 5]) * glotout) + ((resonators[(Rnz * 5) - 4]) * ((p18 = resonators[(Rnz * 5) - 2])))) + ((resonators[(Rnz * 5) - 3]) * (resonators[(Rnz * 5) - 1]));
803 		/* begin resonatorP2:put: */
804 		resonators[(Rnz * 5) - 1] = p18;
805 		/* begin resonatorP1:put: */
806 		resonators[(Rnz * 5) - 2] = glotout;
807 		out1 = answer8;
808 		/* begin resonator:value: */
809 		answer9 = (((resonators[(Rnpc * 5) - 5]) * out1) + ((resonators[(Rnpc * 5) - 4]) * ((p19 = resonators[(Rnpc * 5) - 2])))) + ((resonators[(Rnpc * 5) - 3]) * (resonators[(Rnpc * 5) - 1]));
810 		/* begin resonatorP2:put: */
811 		resonators[(Rnpc * 5) - 1] = p19;
812 		/* begin resonatorP1:put: */
813 		resonators[(Rnpc * 5) - 2] = answer9;
814 		out1 = answer9;
815 		/* begin antiResonator:value: */
816 		answer10 = (((resonators[(Rtz * 5) - 5]) * out1) + ((resonators[(Rtz * 5) - 4]) * ((p110 = resonators[(Rtz * 5) - 2])))) + ((resonators[(Rtz * 5) - 3]) * (resonators[(Rtz * 5) - 1]));
817 		/* begin resonatorP2:put: */
818 		resonators[(Rtz * 5) - 1] = p110;
819 		/* begin resonatorP1:put: */
820 		resonators[(Rtz * 5) - 2] = out1;
821 		out1 = answer10;
822 		/* begin resonator:value: */
823 		answer11 = (((resonators[(Rtpc * 5) - 5]) * out1) + ((resonators[(Rtpc * 5) - 4]) * ((p111 = resonators[(Rtpc * 5) - 2])))) + ((resonators[(Rtpc * 5) - 3]) * (resonators[(Rtpc * 5) - 1]));
824 		/* begin resonatorP2:put: */
825 		resonators[(Rtpc * 5) - 1] = p111;
826 		/* begin resonatorP1:put: */
827 		resonators[(Rtpc * 5) - 2] = answer11;
828 		out1 = answer11;
829 		if (cascade >= 8) {
830 			/* begin resonator:value: */
831 			answer = (((resonators[(R8c * 5) - 5]) * out1) + ((resonators[(R8c * 5) - 4]) * ((p1 = resonators[(R8c * 5) - 2])))) + ((resonators[(R8c * 5) - 3]) * (resonators[(R8c * 5) - 1]));
832 			/* begin resonatorP2:put: */
833 			resonators[(R8c * 5) - 1] = p1;
834 			/* begin resonatorP1:put: */
835 			resonators[(R8c * 5) - 2] = answer;
836 			out1 = answer;
837 		}
838 		if (cascade >= 7) {
839 			/* begin resonator:value: */
840 			answer1 = (((resonators[(R7c * 5) - 5]) * out1) + ((resonators[(R7c * 5) - 4]) * ((p11 = resonators[(R7c * 5) - 2])))) + ((resonators[(R7c * 5) - 3]) * (resonators[(R7c * 5) - 1]));
841 			/* begin resonatorP2:put: */
842 			resonators[(R7c * 5) - 1] = p11;
843 			/* begin resonatorP1:put: */
844 			resonators[(R7c * 5) - 2] = answer1;
845 			out1 = answer1;
846 		}
847 		if (cascade >= 6) {
848 			/* begin resonator:value: */
849 			answer2 = (((resonators[(R6c * 5) - 5]) * out1) + ((resonators[(R6c * 5) - 4]) * ((p12 = resonators[(R6c * 5) - 2])))) + ((resonators[(R6c * 5) - 3]) * (resonators[(R6c * 5) - 1]));
850 			/* begin resonatorP2:put: */
851 			resonators[(R6c * 5) - 1] = p12;
852 			/* begin resonatorP1:put: */
853 			resonators[(R6c * 5) - 2] = answer2;
854 			out1 = answer2;
855 		}
856 		if (cascade >= 5) {
857 			/* begin resonator:value: */
858 			answer3 = (((resonators[(R5c * 5) - 5]) * out1) + ((resonators[(R5c * 5) - 4]) * ((p13 = resonators[(R5c * 5) - 2])))) + ((resonators[(R5c * 5) - 3]) * (resonators[(R5c * 5) - 1]));
859 			/* begin resonatorP2:put: */
860 			resonators[(R5c * 5) - 1] = p13;
861 			/* begin resonatorP1:put: */
862 			resonators[(R5c * 5) - 2] = answer3;
863 			out1 = answer3;
864 		}
865 		if (cascade >= 4) {
866 			/* begin resonator:value: */
867 			answer4 = (((resonators[(R4c * 5) - 5]) * out1) + ((resonators[(R4c * 5) - 4]) * ((p14 = resonators[(R4c * 5) - 2])))) + ((resonators[(R4c * 5) - 3]) * (resonators[(R4c * 5) - 1]));
868 			/* begin resonatorP2:put: */
869 			resonators[(R4c * 5) - 1] = p14;
870 			/* begin resonatorP1:put: */
871 			resonators[(R4c * 5) - 2] = answer4;
872 			out1 = answer4;
873 		}
874 		if (cascade >= 3) {
875 			/* begin resonator:value: */
876 			answer5 = (((resonators[(R3c * 5) - 5]) * out1) + ((resonators[(R3c * 5) - 4]) * ((p15 = resonators[(R3c * 5) - 2])))) + ((resonators[(R3c * 5) - 3]) * (resonators[(R3c * 5) - 1]));
877 			/* begin resonatorP2:put: */
878 			resonators[(R3c * 5) - 1] = p15;
879 			/* begin resonatorP1:put: */
880 			resonators[(R3c * 5) - 2] = answer5;
881 			out1 = answer5;
882 		}
883 		if (cascade >= 2) {
884 			/* begin resonator:value: */
885 			answer6 = (((resonators[(R2c * 5) - 5]) * out1) + ((resonators[(R2c * 5) - 4]) * ((p16 = resonators[(R2c * 5) - 2])))) + ((resonators[(R2c * 5) - 3]) * (resonators[(R2c * 5) - 1]));
886 			/* begin resonatorP2:put: */
887 			resonators[(R2c * 5) - 1] = p16;
888 			/* begin resonatorP1:put: */
889 			resonators[(R2c * 5) - 2] = answer6;
890 			out1 = answer6;
891 		}
892 		if (cascade >= 1) {
893 			/* begin resonator:value: */
894 			answer7 = (((resonators[(R1c * 5) - 5]) * out1) + ((resonators[(R1c * 5) - 4]) * ((p17 = resonators[(R1c * 5) - 2])))) + ((resonators[(R1c * 5) - 3]) * (resonators[(R1c * 5) - 1]));
895 			/* begin resonatorP2:put: */
896 			resonators[(R1c * 5) - 1] = p17;
897 			/* begin resonatorP1:put: */
898 			resonators[(R1c * 5) - 2] = answer7;
899 			out1 = answer7;
900 		}
901 		out = out1;
902 	l2:	/* end cascadeBranch: */;
903 
904 		/* Source is voicing plus aspiration. */
905 
906 		source = parGlotout;
907 
908 		/* Friction-excited parallel vocal tract formants F6, F5, F4, F3, F2,
909 		 outputs added with alternating sign. Sound source for other
910 		 parallel resonators is friction plus first difference of
911 		 voicing waveform. */
912 
913 		out += (((((resonatorvalue(R1vp, source)) + (resonatorvalue(R2vp, source))) + (resonatorvalue(R3vp, source))) + (resonatorvalue(R4vp, source))) + (resonatorvalue(Rnpp, source))) + (resonatorvalue(Rtpp, source));
914 		source = (frictionNoise + parGlotout) - glast;
915 		glast = parGlotout;
916 
917 		/* Apply bypas and output low-pass filter */
918 
919 		out = (((((resonatorvalue(R2fp, source)) - (resonatorvalue(R3fp, source))) + (resonatorvalue(R4fp, source))) - (resonatorvalue(R5fp, source))) + (resonatorvalue(R6fp, source))) - out;
920 		out = (bypass * source) - out;
921 		/* begin resonator:value: */
922 		answer12 = (((resonators[(Rout * 5) - 5]) * out) + ((resonators[(Rout * 5) - 4]) * ((p112 = resonators[(Rout * 5) - 2])))) + ((resonators[(Rout * 5) - 3]) * (resonators[(Rout * 5) - 1]));
923 		/* begin resonatorP2:put: */
924 		resonators[(Rout * 5) - 1] = p112;
925 		/* begin resonatorP1:put: */
926 		resonators[(Rout * 5) - 2] = answer12;
927 		out = answer12;
928 		temp = ((sqInt)(out * ampGain));
929 		if (temp < -32768) {
930 			temp = -32768;
931 		}
932 		if (temp > 32767) {
933 			temp = 32767;
934 		}
935 		buffer[index - 1] = temp;
936 		index += 1;
937 		samplesCount += 1;
938 	}
939 }
940 
zeroQphicosphisinphirphid(float phi,float cosphi,float sinphi,float rphid)941 static float zeroQphicosphisinphirphid(float  phi, float  cosphi, float  sinphi, float  rphid) {
942     float  qa;
943     float  qb;
944     float  qc;
945     float  qzero;
946     float  ua;
947     float  ub;
948     float  uc;
949 
950 	qzero = quphicosphisinphirphid(0, phi, cosphi, sinphi, rphid);
951 	if (qzero > 0) {
952 		ua = 0;
953 		ub = 1;
954 		qa = qzero;
955 		qb = quphicosphisinphirphid(ub, phi, cosphi, sinphi, rphid);
956 		while (qb > 0) {
957 			ua = ub;
958 			qa = qb;
959 			ub = ub * 2;
960 			qb = quphicosphisinphirphid(ub, phi, cosphi, sinphi, rphid);
961 		}
962 	} else {
963 		ua = -1;
964 		ub = 0;
965 		qa = quphicosphisinphirphid(ua, phi, cosphi, sinphi, rphid);
966 		qb = qzero;
967 		while (qa < 0) {
968 			ub = ua;
969 			qb = qa;
970 			ua = ua * 2;
971 			qa = quphicosphisinphirphid(ua, phi, cosphi, sinphi, rphid);
972 		}
973 	}
974 	while ((ub - ua) > Epsilon) {
975 		uc = (ub + ua) / 2.0;
976 		qc = quphicosphisinphirphid(uc, phi, cosphi, sinphi, rphid);
977 		if (qc > 0) {
978 			ua = uc;
979 			qa = qc;
980 		} else {
981 			ub = uc;
982 			qb = qc;
983 		}
984 	}
985 	return (ub + ua) / 2.0;
986 }
987 
988 
989 #ifdef SQUEAK_BUILTIN_PLUGIN
990 
991 
992 void* Klatt_exports[][3] = {
993 	{"Klatt", "getModuleName", (void*)getModuleName},
994 	{"Klatt", "primitiveSynthesizeFrameIntoStartingAt", (void*)primitiveSynthesizeFrameIntoStartingAt},
995 	{"Klatt", "setInterpreter", (void*)setInterpreter},
996 	{NULL, NULL, NULL}
997 };
998 
999 
1000 #endif /* ifdef SQ_BUILTIN_PLUGIN */
1001 
1002