131 #include <propeller.h>
135 #define INLINE__ static inline
136 #define PostEffect__(X, Y) __extension__({ int32_t tmp__ = (X); (X) = (Y); tmp__; })
138 #define INLINE__ static
139 static int32_t tmp__;
140 #define PostEffect__(X, Y) (tmp__ = (X), (X) = (Y), tmp__)
141 #define waitcnt(n) _waitcnt(n)
142 #define coginit(id, code, par) _coginit((unsigned)(par)>>2, (unsigned)(code)>>2, id)
143 #define cognew(code, par) coginit(0x8, (code), (par))
144 #define cogstop(i) _cogstop(i)
147 INLINE__ int32_t Min__(int32_t a, int32_t b) {
return a < b ? a : b; }
148 INLINE__ int32_t Max__(int32_t a, int32_t b) {
return a > b ? a : b; }
153 INLINE__ int32_t Shr__(uint32_t a, uint32_t b) {
return (a>>b); }
154 INLINE__ int32_t Between__(int32_t
x, int32_t a, int32_t b){
if (a <= b)
return x >= a && x <= b; return x >= b &&
x <= a; }
156 static int32_t talk_formant(
talk *
self, int32_t sf1, int32_t sf2, int32_t sf3, int32_t sf4);
157 static int32_t talk_set(
talk *
self, int32_t fmt, int32_t ptr, int32_t pre, int32_t time, int32_t post);
159 static uint8_t dat[] = {
160 0x80, 0x00, 0x8c, 0x00, 0x98, 0x00, 0xa6, 0x00, 0xb5, 0x00, 0xc5, 0x00, 0xd7, 0x00, 0xeb, 0x00,
161 0x00, 0x01, 0x17, 0x01, 0x30, 0x01, 0x4c, 0x01, 0x6a, 0x01, 0x8b, 0x01, 0xaf, 0x01, 0xd6, 0x01,
168 self->vocal_cog = VocalTract_start(&self->v, (int32_t)(&self->vt[0]), pin, npin, (-1));
169 memset( (
void *)&self->speaker[0], 100, 1*(10));
170 self->base_freq = 100;
176 if (self->vocal_cog) {
177 cogstop((self->vocal_cog - 1));
187 self->speaker[(Min__((Max__(spkr, 0)), 9))] = base;
195 while ((Char = ((uint8_t *)(ptr++))[0])) {
196 if ((Char >=
'A') && (Char <=
'Z')) {
202 }
else if (Char ==
'a') {
204 }
else if (Char ==
'b') {
206 }
else if (Char ==
'c') {
208 }
else if (Char ==
'd') {
210 }
else if (Char ==
'e') {
212 }
else if (Char ==
'f') {
214 }
else if (Char ==
'g') {
216 }
else if (Char ==
'h') {
218 }
else if (Char ==
'i') {
220 }
else if (Char ==
'j') {
222 }
else if (Char ==
'k') {
224 }
else if (Char ==
'l') {
226 }
else if (Char ==
'm') {
228 }
else if (Char ==
'n') {
230 }
else if (Char ==
'o') {
232 }
else if (Char ==
'p') {
234 }
else if (Char ==
'q') {
236 }
else if (Char ==
'r') {
238 }
else if (Char ==
's') {
240 }
else if (Char ==
't') {
242 }
else if (Char ==
'u') {
244 }
else if (Char ==
'v') {
246 }
else if (Char ==
'w') {
248 }
else if (Char ==
'x') {
250 }
else if (Char ==
'y') {
252 }
else if (Char ==
'z') {
254 }
else if (Char ==
'0') {
256 }
else if (Char ==
'1') {
258 }
else if (Char ==
'2') {
260 }
else if (Char ==
'3') {
262 }
else if (Char ==
'4') {
264 }
else if (Char ==
'5') {
266 }
else if (Char ==
'6') {
268 }
else if (Char ==
'7') {
270 }
else if (Char ==
'8') {
272 }
else if (Char ==
'9') {
274 }
else if (Char ==
'.') {
276 }
else if (Char ==
',') {
278 }
else if (Char ==
':') {
280 }
else if (Char ==
'?') {
281 s =
"kw\'estshun mark~";
282 }
else if (Char ==
'!') {
283 s =
"\'eksklam\'ayshun point";
284 }
else if (Char ==
';') {
285 s =
"s\'emaekoalun~";
286 }
else if (Char ==
'\'') {
288 }
else if (Char ==
'@') {
290 }
else if (Char ==
'#') {
292 }
else if (Char ==
'$') {
294 }
else if (Char ==
'%') {
296 }
else if (Char ==
'^') {
298 }
else if (Char ==
'&') {
300 }
else if (Char ==
'*') {
302 }
else if (Char ==
'(') {
303 s =
"left pur\'enthesis";
304 }
else if (Char ==
')') {
305 s =
"raet pur\'enthesis";
306 }
else if (Char ==
'-') {
308 }
else if (Char ==
'_') {
310 }
else if (Char ==
'+') {
312 }
else if (Char ==
'=') {
313 s =
"\'eekwol saen~";
315 s =
"\'unoan k\'a racter";
325 int32_t This, nxt, octave;
327 if (self->vocal_cog == 0) {
330 self->vt[GP] = (
self->vt[GPS] =
self->base_freq);
331 self->initial_k = (
self->initial_g = (
self->aspirate = (
self->whisper = 0)));
334 talk_set(
self, talk_formant(
self, 650, 990, 2530, 3480), (int32_t)
"\022", 0, 10, 0);
335 while ((This = ((uint8_t *)(ptr++))[0])) {
337 self->vt[GP] = (
self->vt[GPS] =
self->base_freq);
338 }
else if (This ==
'/') {
339 self->vt[GPS] =
self->vt[GPS] + 4;
340 }
else if (This ==
'\\') {
341 self->vt[GPS] =
self->vt[GPS] - 4;
342 }
else if (This ==
'[') {
343 self->vt[GPS] = (
self->vt[GP] =
self->vt[GP] + 4);
344 }
else if (This ==
']') {
345 self->vt[GPS] = (
self->vt[GP] =
self->vt[GP] - 4);
346 }
else if (This ==
'\'') {
347 self->vt[GP] =
self->vt[GP] + 4;
348 }
else if (This ==
',') {
349 talk_set(
self, 0, (int32_t)
"\022", 100, 200, 0);
350 }
else if (This ==
';') {
351 talk_set(
self, 0, (int32_t)
"\022", 100, 450, 0);
352 }
else if (This ==
'.') {
353 talk_set(
self, 0, (int32_t)
"\022", 100, 750, 0);
354 }
else if (This ==
'|') {
356 }
else if (This ==
'(') {
358 }
else if (This ==
')') {
360 }
else if (This ==
'%') {
362 while (((nxt = ((uint8_t *)(ptr++))[0]) >=
'0') && (nxt <=
'9')) {
363 self->dilate = ((
self->dilate * 10) + nxt) -
'0';
367 self->dilate = Min__((Max__(self->dilate, 25)), 1600);
371 }
else if (This ==
'~') {
372 talk_set(
self, talk_formant(
self, 640, 1200, 2400, 3000), (int32_t)
"\016\017", 10, 15, 10);
373 }
else if (This ==
'#' || This ==
'_' || Between__(This,
'A',
'G') || This ==
'+' || This ==
'-' || This ==
'=' || This ==
'<' || This ==
'>' || This ==
'a' || This ==
'e' || This ==
'i' || This ==
'o' || This ==
'u' || This ==
'd' || This ==
't' || This ==
's' || This ==
'c' || This ==
'k' || This ==
'g' || This ==
'z' || This ==
'r') {
374 nxt = ((uint8_t *)(ptr++))[0];
376 if (Between__(nxt,
'0',
'9')) {
377 self->base_freq =
self->speaker[(nxt -
'0')];
380 self->base_freq =
self->speaker[0];
382 self->vt[GP] = (
self->vt[GPS] =
self->base_freq);
383 }
else if (Between__(This,
'A',
'G')) {
384 if (Between__(nxt,
'1',
'5')) {
388 octave = (
self->vt[GP] + 32) / 48;
390 self->vt[GP] = (
self->vt[GPS] = Min__((((octave - 1) * 48) + ((uint8_t *)(int32_t)
"4<\020\030 $,")[(This -
'A')]), 255));
391 }
else if (This ==
'+' || This ==
'-') {
392 if (Between__(nxt,
'1',
'9')) {
393 self->vt[GP] =
self->vt[GP] + (((
',' - This) * (nxt -
'0')) << 2);
396 self->vt[GP] =
self->vt[GP] + ((
',' - This) << 2);
398 self->vt[GPS] =
self->vt[GP];
399 }
else if (This ==
'=') {
400 if (Between__(nxt,
'0',
'9')) {
401 self->volume = nxt -
'0';
406 }
else if (This ==
'<' || This ==
'>') {
407 if (Between__(nxt,
'0',
'9')) {
408 self->volume = Max__((Min__((self->volume + ((
'=' - This) * (nxt -
'0'))), 9)), 0);
411 self->volume = Max__((Min__(((self->volume +
'=') - This), 9)), 0);
413 }
else if (This ==
'a') {
416 talk_set(
self, talk_formant(
self, 650, 990, 2530, 3480), 0, 10, 1, 300);
417 talk_set(
self, talk_formant(
self, 310, 2020, 2960, 3500), 0, 300, 50, 100);
418 }
else if (nxt ==
'l') {
420 talk_set(
self, talk_formant(
self, 660, 1700, 2400, 3900), 0, 200, 200, 100);
421 talk_set(
self, talk_formant(
self, 310, 1050, 2880, 3500), 0, 100, 200, 50);
422 }
else if (nxt ==
'i' || nxt ==
'y') {
424 talk_set(
self, talk_formant(
self, 660, 1700, 2400, 3900), 0, 200, 0, 150);
425 talk_set(
self, talk_formant(
self, 310, 2020, 2960, 3500), 0, 150, 200, 100);
426 }
else if (nxt ==
'r') {
428 talk_set(
self, talk_formant(
self, 650, 990, 2530, 3480), 0, 200, 100, 100);
429 talk_set(
self, talk_formant(
self, 470, 1120, 2430, 3400), 0, 100, 200, 100);
430 talk_set(
self, talk_formant(
self, 310, 1060, 1380, 3500), (int32_t)
"\022", 100, 200, 200);
431 }
else if (nxt ==
'h') {
433 talk_set(
self, talk_formant(
self, 650, 990, 2530, 3480), 0, 200, 200, 100);
437 talk_set(
self, talk_formant(
self, 660, 1700, 2400, 3900), 0, 200, 200, 100);
439 }
else if (This ==
'e') {
442 talk_set(
self, talk_formant(
self, 310, 2020, 2960, 3500), 0, 100, 200, 100);
443 }
else if (nxt ==
'w') {
445 talk_set(
self, talk_formant(
self, 310, 2020, 2960, 3500), 0, 100, 0, 150);
446 talk_set(
self, talk_formant(
self, 300, 870, 2250, 3900), 0, 200, 100, 100);
447 }
else if (nxt ==
'r') {
449 talk_set(
self, talk_formant(
self, 470, 1120, 2430, 3400), 0, 100, 200, 100);
450 talk_set(
self, talk_formant(
self, 310, 1060, 1380, 3500), (int32_t)
"\022", 100, 200, 200);
451 }
else if (nxt ==
'l') {
453 talk_set(
self, talk_formant(
self, 580, 1799, 2605, 3677), 0, 100, 100, 100);
454 talk_set(
self, talk_formant(
self, 310, 1050, 2880, 3500), 0, 100, 200, 50);
458 talk_set(
self, talk_formant(
self, 580, 1799, 2605, 3677), 0, 100, 100, 100);
460 }
else if (This ==
'i') {
463 talk_set(
self, talk_formant(
self, 470, 1120, 2430, 3400), 0, 100, 200, 100);
464 talk_set(
self, talk_formant(
self, 310, 1060, 1380, 3500), (int32_t)
"\022", 100, 200, 200);
468 talk_set(
self, talk_formant(
self, 400, 2000, 2550, 3900), 0, 100, 150, 100);
470 }
else if (This ==
'o') {
473 talk_set(
self, talk_formant(
self, 640, 1200, 2400, 3000), 0, 100, 0, 150);
474 talk_set(
self, talk_formant(
self, 300, 870, 2250, 3900), 0, 150, 100, 100);
475 }
else if (nxt ==
'r') {
477 talk_set(
self, talk_formant(
self, 640, 1200, 2400, 3000), 0, 100, 0, 100);
478 talk_set(
self, talk_formant(
self, 300, 870, 2250, 3900), 0, 100, 0, 100);
479 talk_set(
self, talk_formant(
self, 470, 1120, 2430, 3400), (int32_t)
"\016\024", 100, 0, 50);
480 talk_set(
self, talk_formant(
self, 310, 1060, 1380, 3500), (int32_t)
"\022", 50, 200, 200);
481 }
else if (nxt ==
'l') {
483 talk_set(
self, talk_formant(
self, 650, 990, 2530, 3480), 0, 200, 200, 100);
484 talk_set(
self, talk_formant(
self, 310, 1050, 2880, 3500), 0, 100, 200, 50);
485 }
else if (nxt ==
'u' || nxt ==
'w') {
487 talk_set(
self, talk_formant(
self, 660, 1700, 2400, 3900), 0, 100, 100, 300);
488 talk_set(
self, talk_formant(
self, 300, 870, 2250, 3900), 0, 300, 50, 100);
489 }
else if (nxt ==
'i' || nxt ==
'y') {
491 talk_set(
self, talk_formant(
self, 640, 1200, 2400, 3000), 0, 100, 0, 150);
492 talk_set(
self, talk_formant(
self, 300, 870, 2250, 3900), 0, 150, 0, 200);
493 talk_set(
self, talk_formant(
self, 310, 2020, 2960, 3500), 0, 200, 50, 100);
494 }
else if (nxt ==
'o') {
496 talk_set(
self, talk_formant(
self, 300, 870, 2250, 3900), 0, 100, 200, 100);
500 talk_set(
self, talk_formant(
self, 650, 990, 2530, 3480), 0, 200, 200, 100);
502 }
else if (This ==
'u') {
505 talk_set(
self, talk_formant(
self, 470, 1120, 2430, 3400), 0, 100, 200, 100);
509 talk_set(
self, talk_formant(
self, 640, 1200, 2400, 3000), 0, 100, 200, 100);
511 }
else if (This ==
'd') {
513 talk_set(
self, 0, (int32_t)
"\022", 0, 30, 0);
514 talk_set(
self, talk_formant(
self, 350, 1800, 2820, 3400), (int32_t)
"\022\016\005\020\005\014\372", 0, 100, 0);
518 talk_set(
self, talk_formant(
self, 400, 1600, 2600, 3500), (int32_t)
"\022", 0, 100, 0);
519 talk_set(
self, 0, (int32_t)
"\r\310", 0, 10, 10);
520 talk_set(
self, 0, (int32_t)
"\r\024\0172\n\024", 100, 100, 100);
522 }
else if (This ==
't') {
524 talk_set(
self, 0, (int32_t)
"\022", 0, 30, 0);
525 talk_set(
self, talk_formant(
self, 350, 1800, 2820, 3400), (int32_t)
"\022\020\n\014\372", 0, 200, 50);
529 talk_set(
self, talk_formant(
self, 400, 1600, 2600, 3500), (int32_t)
"\022", 0, 100, 0);
530 talk_set(
self, 0, (int32_t)
"\022\r\310", 0, 10, 10);
531 talk_set(
self, 0, (int32_t)
"\022\r\024\0172\n\024", 100, 100, 100);
533 }
else if (This ==
's') {
535 talk_set(
self, 0, (int32_t)
"\022", 0, 30, 0);
536 talk_set(
self, talk_formant(
self, 470, 1120, 2430, 3400), (int32_t)
"\022\r\n\020\005\0142", 0, 200, 0);
537 talk_set(
self, 0, (int32_t)
"\022", 0, 1, 50);
541 talk_set(
self, 0, (int32_t)
"\022", 0, 30, 0);
542 talk_set(
self, talk_formant(
self, 19, 38, 57, 57), (int32_t)
"\022\020\002\014d", 0, 200, 0);
543 talk_set(
self, talk_formant(
self, 470, 1120, 2430, 3400), (int32_t)
"\016\377", 0, 1, 50);
545 }
else if (This ==
'c' || This ==
'k') {
546 if ((This ==
'c') && (nxt ==
'h')) {
547 talk_set(
self, 0, (int32_t)
"\022", 0, 30, 0);
548 talk_set(
self, talk_formant(
self, 260, 2070, 3020, 3500), (int32_t)
"\022\014d\020\005", 0, 100, 200);
549 talk_set(
self, 0, (int32_t)
"\016\377", 0, 1, 50);
552 if (nxt ==
'a' || nxt ==
'e' || nxt ==
'i' || nxt ==
'o' || nxt ==
'u') {
554 self->initial_k = -1;
556 talk_set(
self, talk_formant(
self, 50, 1750, 1750, 3500), (int32_t)
"\022", 50, 1, 1);
557 talk_set(
self, 0, (int32_t)
"\022", 10, 1, 1);
558 talk_set(
self, 0, (int32_t)
"\022\020\036\014Z", 0, 15, 0);
559 talk_set(
self, 0, (int32_t)
"\022", 0, 40, 0);
562 }
else if (This ==
'g') {
564 if (nxt ==
'a' || nxt ==
'e' || nxt ==
'i' || nxt ==
'o' || nxt ==
'u') {
566 self->initial_g = -1;
568 talk_set(
self, talk_formant(
self, 300, 1990, 2850, 3500), (int32_t)
"\022\016\024\r\310", 0, 10, 10);
569 talk_set(
self, 0, (int32_t)
"\022\016\024\r\024\0172\n\024", 40, 40, 10);
571 }
else if (This ==
'z') {
573 talk_set(
self, talk_formant(
self, 470, 1120, 2430, 3400), (int32_t)
"\022\016\024\r\n\020\005\0142", 50, 300, 0);
577 talk_set(
self, talk_formant(
self, 150, 1400, 2300, 3180), (int32_t)
"\014\372\020\n\016\024", 200, 100, 200);
579 }
else if (This ==
'r') {
584 for(_idx__0000 = 0; _idx__0000 < 3; _idx__0000++) {
585 talk_set(
self, talk_formant(
self, 310, 1060, 1380, 3500), (int32_t)
"\022", 0, 50, 200);
586 talk_set(
self, talk_formant(
self, 640, 1200, 2400, 3000), (int32_t)
"\016\017", 10, 15, 10);
593 talk_set(
self, talk_formant(
self, 310, 1060, 1380, 3500), (int32_t)
"\022", 0, 50, 200);
598 talk_set(
self, talk_formant(
self, 310, 1050, 2880, 3500), 0, 0, 200, 50);
599 }
else if (This ==
'w') {
600 talk_set(
self, talk_formant(
self, 290, 610, 2150, 3500), (int32_t)
"\022", 0, 50, 200);
601 }
else if (This ==
'y') {
602 talk_set(
self, talk_formant(
self, 310, 2020, 2960, 3500), (int32_t)
"\022", 0, 100, 200);
603 }
else if (This ==
'm') {
604 talk_set(
self, talk_formant(
self, 480, 1270, 2130, 3500), (int32_t)
"\022\016\005\017\005\n\016", 10, 200, 30);
605 }
else if (This ==
'n') {
606 talk_set(
self, talk_formant(
self, 480, 1340, 2470, 3500), (int32_t)
"\022\016\005\017\005\n\016", 10, 200, 30);
607 }
else if (This ==
'p') {
608 talk_set(
self, talk_formant(
self, 400, 1100, 2150, 3500), (int32_t)
"\022", 0, 100, 0);
609 talk_set(
self, 0, (int32_t)
"\022\r<", 0, 10, 10);
610 talk_set(
self, 0, (int32_t)
"\022\r\024\0172\n\024", 100, 100, 100);
611 }
else if (This ==
'b') {
612 talk_set(
self, talk_formant(
self, 200, 1100, 2150, 3500), (int32_t)
"\022", 0, 100, 10);
613 talk_set(
self, 0, (int32_t)
"\022\016\n", 10, 40, 10);
614 }
else if (This ==
'f') {
615 talk_set(
self, 0, (int32_t)
"\022", 0, 30, 0);
616 talk_set(
self, talk_formant(
self, 19, 38, 57, 57), (int32_t)
"\022\020\002\014\372", 0, 200, 0);
617 talk_set(
self, talk_formant(
self, 470, 1120, 2430, 3400), (int32_t)
"\016\377", 0, 1, 50);
618 }
else if (This ==
'h') {
621 }
else if (This ==
'v') {
622 talk_set(
self, talk_formant(
self, 220, 1100, 2080, 3500), (int32_t)
"\022\014\372\020\002", 0, 100, 200);
623 }
else if (This ==
'j') {
624 talk_set(
self, talk_formant(
self, 260, 2070, 3020, 3500), (int32_t)
"\022\016\n\014d\020\n", 0, 150, 100);
628 talk_set(
self, 0, (int32_t)
"\022", 0, 1, 0);
632 static int32_t talk_formant(
talk *
self, int32_t sf1, int32_t sf2, int32_t sf3, int32_t sf4)
635 self->vt[F1] = sf1 / 19;
638 self->vt[F2] = sf2 / 19;
641 self->vt[F3] = sf3 / 19;
644 self->vt[F4] = sf4 / 19;
649 static int32_t talk_set(
talk *
self, int32_t fmt, int32_t ptr, int32_t pre, int32_t time, int32_t post)
651 int32_t This, nxt, vol;
653 while ((This = ((uint8_t *)(ptr++))[0])) {
658 self->vt[AA] = (
self->vt[GA] = (
self->vt[NA] = (
self->vt[FA] = 0)));
660 if ((nxt = ((uint8_t *)(ptr++))[0])) {
664 self->vt[This] = nxt;
666 if (!abortChain__) abort();
667 abortChain__->val = 0;
668 longjmp(abortChain__->jmp, 1);
673 if ((pre) || (time)) {
674 if (self->aspirate) {
675 self->vt[AAZ] = (
self->vt[GAZ] = 0);
676 VocalTract_go(&self->v, 1);
678 VocalTract_go(&self->v, (Max__(((200 * self->dilate) / 100), 1)));
682 if ((self->initial_k) || (self->initial_g)) {
683 memcpy( (
void *)&self->vtp[0], (
void *)&self->vt[0], 1*(18));
684 if (self->initial_g) {
685 self->vt[F1] = Shr__(self->vtp[F1], 2);
686 self->vt[F2] = (
self->vt[F3] = Shr__((self->vtp[F2] + self->vtp[F3]), 1));
688 self->vt[F1] = Shr__((self->vt[F1] * 3), 2);
689 self->vt[F2] = Shr__(((self->vtp[F2] * 3) + self->vtp[F3]), 2);
690 self->vt[F3] = Shr__(((self->vtp[F3] * 3) + self->vtp[F2]), 2);
694 talk_set(
self, 0, (int32_t)
"\022", 10, 1, 1);
695 talk_set(
self, 0, (int32_t)
"\022\020\036\014Z", 0, 15, 0);
696 talk_set(
self, 0, (int32_t)
"\022", 0, 40, 0);
697 talk_set(
self, 0, (int32_t)
"\016\002", 0, 10, 100);
698 memcpy( (
void *)&self->vt[0], (
void *)&self->vtp[0], 1*(18));
702 self->vt[AA] = Max__(self->vt[AA], self->vt[GA]);
705 vol = ((uint8_t *)(int32_t)
" %,3;EP^m\200")[self->volume];
706 self->vt[GAZ] = Shr__((self->vt[GA] * vol), 7);
707 self->vt[AAZ] = Shr__((self->vt[AA] * vol), 7);
708 self->vt[FAZ] = Shr__((self->vt[FA] * vol), 7);
709 self->vt[NAZ] = Shr__((self->vt[NA] * vol), 7);
710 VocalTract_go(&self->v, (Max__((((Min__(pre, self->glide)) * self->dilate) / 100), 1)));
711 self->vt[GP] =
self->vt[GPS];
712 VocalTract_go(&self->v, (Max__(((time * self->dilate) / 100), 1)));
722 if(level < 0) level = 0;
723 if(level > 7) level = 7;
724 VocalTract_set_attenuation(&self->v, 7 - level);