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