11 #include "Vocab_Special.h"
12 #include "Vocab_US_Large.h"
16 #define LENGT_OF_FLOAT_STRING 14
29 Talkie(Print& out,
int channelCount = 1) {
31 channels = channelCount;
38 void say(
const uint8_t* address) {
45 int samples = 8000 * ms / 1000;
46 for (
int j = 0; j < samples; j++) {
51 void sayPause() {
say(spPAUSE1); }
53 void sayDigit(
char aDigit) {
return sayNumber(aDigit -
'0'); }
55 void sayVoltageMilliVolts(
long aMilliVolt) {
61 void sayVoltageVolts(
float aVolt) {
62 sayFloat(aVolt, 2,
true,
true);
76 }
else if (aNumber == 0) {
79 if (aNumber >= 1000) {
80 int thousands = aNumber / 1000;
84 if ((aNumber > 0) && (aNumber < 100))
say(sp2_AND);
87 int hundreds = aNumber / 100;
91 if (aNumber > 0)
say(sp2_AND);
94 int tens = aNumber / 10;
199 void sayFloat(
float aFloat,
int aDecimalPlaces,
bool aSuppressLeadingZero,
200 bool aSuppressTrailingZero) {
202 long tIntegerPart = aFloat;
203 if (tIntegerPart != 0 || !aSuppressLeadingZero) {
206 if (aDecimalPlaces > 0) {
209 char tFloatString[LENGT_OF_FLOAT_STRING];
210 dtostrf(aFloat, 8, aDecimalPlaces, tFloatString);
213 for (i = 0; i < (LENGT_OF_FLOAT_STRING - 1); ++i) {
214 if (tFloatString[i] ==
'.') {
220 if (i < LENGT_OF_FLOAT_STRING - 2) {
222 for (
int j = 0; j < aDecimalPlaces; ++j) {
224 if (!(tFloatString[i] ==
'0' && aSuppressTrailingZero &&
225 j == aDecimalPlaces - 1)) {
229 if (tFloatString[i] ==
'\0') {
257 Print* p_print =
nullptr;
259 uint16_t channels = 1;
261 bool isOutputText =
true;
262 const uint8_t* ptrAddr =
nullptr;
265 uint16_t synthEnergy;
266 int16_t synthK1, synthK2;
267 int8_t synthK3, synthK4, synthK5, synthK6, synthK7, synthK8, synthK9,
269 void (*data_callback)(int16_t* data,
int len) =
nullptr;
271 uint8_t tmsEnergy[0x10] = {0x00, 0x02, 0x03, 0x04, 0x05, 0x07, 0x0a, 0x0f,
272 0x14, 0x20, 0x29, 0x39, 0x51, 0x72, 0xa1, 0xff};
273 uint8_t tmsPeriod[0x40] = {
274 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
275 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
276 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2D, 0x2F, 0x31, 0x33,
277 0x35, 0x36, 0x39, 0x3B, 0x3D, 0x3F, 0x42, 0x45, 0x47, 0x49, 0x4D,
278 0x4F, 0x51, 0x55, 0x57, 0x5C, 0x5F, 0x63, 0x66, 0x6A, 0x6E, 0x73,
279 0x77, 0x7B, 0x80, 0x85, 0x8A, 0x8F, 0x95, 0x9A, 0xA0};
280 uint16_t tmsK1[0x20] = {
281 0x82C0, 0x8380, 0x83C0, 0x8440, 0x84C0, 0x8540, 0x8600, 0x8780,
282 0x8880, 0x8980, 0x8AC0, 0x8C00, 0x8D40, 0x8F00, 0x90C0, 0x92C0,
283 0x9900, 0xA140, 0xAB80, 0xB840, 0xC740, 0xD8C0, 0xEBC0, 0x0000,
284 0x1440, 0x2740, 0x38C0, 0x47C0, 0x5480, 0x5EC0, 0x6700, 0x6D40};
285 uint16_t tmsK2[0x20] = {
286 0xAE00, 0xB480, 0xBB80, 0xC340, 0xCB80, 0xD440, 0xDDC0, 0xE780,
287 0xF180, 0xFBC0, 0x0600, 0x1040, 0x1A40, 0x2400, 0x2D40, 0x3600,
288 0x3E40, 0x45C0, 0x4CC0, 0x5300, 0x5880, 0x5DC0, 0x6240, 0x6640,
289 0x69C0, 0x6CC0, 0x6F80, 0x71C0, 0x73C0, 0x7580, 0x7700, 0x7E80};
290 uint8_t tmsK3[0x10] = {0x92, 0x9F, 0xAD, 0xBA, 0xC8, 0xD5, 0xE3, 0xF0,
291 0xFE, 0x0B, 0x19, 0x26, 0x34, 0x41, 0x4F, 0x5C};
292 uint8_t tmsK4[0x10] = {0xAE, 0xBC, 0xCA, 0xD8, 0xE6, 0xF4, 0x01, 0x0F,
293 0x1D, 0x2B, 0x39, 0x47, 0x55, 0x63, 0x71, 0x7E};
294 uint8_t tmsK5[0x10] = {0xAE, 0xBA, 0xC5, 0xD1, 0xDD, 0xE8, 0xF4, 0xFF,
295 0x0B, 0x17, 0x22, 0x2E, 0x39, 0x45, 0x51, 0x5C};
296 uint8_t tmsK6[0x10] = {0xC0, 0xCB, 0xD6, 0xE1, 0xEC, 0xF7, 0x03, 0x0E,
297 0x19, 0x24, 0x2F, 0x3A, 0x45, 0x50, 0x5B, 0x66};
298 uint8_t tmsK7[0x10] = {0xB3, 0xBF, 0xCB, 0xD7, 0xE3, 0xEF, 0xFB, 0x07,
299 0x13, 0x1F, 0x2B, 0x37, 0x43, 0x4F, 0x5A, 0x66};
300 uint8_t tmsK8[0x08] = {0xC0, 0xD8, 0xF0, 0x07, 0x1F, 0x37, 0x4F, 0x66};
301 uint8_t tmsK9[0x08] = {0xC0, 0xD4, 0xE8, 0xFC, 0x10, 0x25, 0x39, 0x4D};
302 uint8_t tmsK10[0x08] = {0xCD, 0xDF, 0xF1, 0x04, 0x16, 0x20, 0x3B, 0x4D};
303 uint8_t chirp[CHIRP_SIZE] = {
304 0x00, 0x2a, 0xd4, 0x32, 0xb2, 0x12, 0x25, 0x14, 0x02, 0xe1, 0xc5,
305 0x02, 0x5f, 0x5a, 0x05, 0x0f, 0x26, 0xfc, 0xa5, 0xa5, 0xd6, 0xdd,
306 0xdc, 0xfc, 0x25, 0x2b, 0x22, 0x21, 0x0f, 0xff, 0xf8, 0xee, 0xed,
307 0xef, 0xf7, 0xf6, 0xfa, 0x00, 0x03, 0x02, 0x01};
308 int16_t nextSample = 0;
309 uint8_t periodCounter = 0;
312 void wait() {
while (process()); }
314 void setPtr(
const uint8_t* addr) {
321 uint8_t rev(uint8_t a) {
323 a = (a >> 4) | (a << 4);
325 a = ((a & 0xcc) >> 2) | ((a & 0x33) << 2);
327 a = ((a & 0xaa) >> 1) | ((a & 0x55) << 1);
332 uint8_t getBits(uint8_t bits) {
335 data = rev(*(ptrAddr)) << 8;
336 if (ptrBit + bits > 8) {
337 data |= rev(*(ptrAddr + 1));
340 value = data >> (16 - bits);
349 void say1(
const uint8_t* addr) {
352 for (
int j = 0; j < 100; j++) wait();
359 int clip(
int value,
int min,
int max) {
360 if (value < min)
return min;
361 if (value > max)
return max;
365 void writeSample(int16_t sample) {
367 int16_t outSample = clip(
static_cast<int>(sample), -32768, 32767);
371 int16_t out[channels] = {outSample};
372 data_callback(out, channels);
379 for (
int j = 0; j < channels; j++) {
380 if (j > 0) p_print->print(
", ");
381 p_print->print(outSample);
385 int16_t out[channels] = {outSample};
386 p_print->write((uint8_t*)out,
sizeof(out));
395 bool isActive = calculateSample();
397 writeSample(nextSample);
401 if (periodCounter < synthPeriod) {
406 if (periodCounter < CHIRP_SIZE) {
407 u[10] = ((chirp[periodCounter]) * (uint32_t)synthEnergy) >> 8;
413 static uint16_t synthRand = 1;
414 synthRand = (synthRand >> 1) ^ ((synthRand & 1) ? 0xB800 : 0);
415 u[10] = (synthRand & 1) ? synthEnergy : -synthEnergy;
418 u[9] = u[10] - (((int16_t)synthK10 * x[9]) >> 7);
419 u[8] = u[9] - (((int16_t)synthK9 * x[8]) >> 7);
420 u[7] = u[8] - (((int16_t)synthK8 * x[7]) >> 7);
421 u[6] = u[7] - (((int16_t)synthK7 * x[6]) >> 7);
422 u[5] = u[6] - (((int16_t)synthK6 * x[5]) >> 7);
423 u[4] = u[5] - (((int16_t)synthK5 * x[4]) >> 7);
424 u[3] = u[4] - (((int16_t)synthK4 * x[3]) >> 7);
425 u[2] = u[3] - (((int16_t)synthK3 * x[2]) >> 7);
426 u[1] = u[2] - (((int32_t)synthK2 * x[1]) >> 15);
427 u[0] = u[1] - (((int32_t)synthK1 * x[0]) >> 15);
430 u[0] = clip(u[0], -512, 511);
433 x[9] = x[8] + (((int16_t)synthK9 * u[8]) >> 7);
434 x[8] = x[7] + (((int16_t)synthK8 * u[7]) >> 7);
435 x[7] = x[6] + (((int16_t)synthK7 * u[6]) >> 7);
436 x[6] = x[5] + (((int16_t)synthK6 * u[5]) >> 7);
437 x[5] = x[4] + (((int16_t)synthK5 * u[4]) >> 7);
438 x[4] = x[3] + (((int16_t)synthK4 * u[3]) >> 7);
439 x[3] = x[2] + (((int16_t)synthK3 * u[2]) >> 7);
440 x[2] = x[1] + (((int32_t)synthK2 * u[1]) >> 15);
441 x[1] = x[0] + (((int32_t)synthK1 * u[0]) >> 15);
450 bool calculateSample() {
459 }
else if (energy == 0xf) {
473 synthEnergy = tmsEnergy[energy];
475 synthPeriod = tmsPeriod[getBits(6)];
479 synthK1 = tmsK1[getBits(5)];
480 synthK2 = tmsK2[getBits(5)];
481 synthK3 = tmsK3[getBits(4)];
482 synthK4 = tmsK4[getBits(4)];
485 synthK5 = tmsK5[getBits(4)];
486 synthK6 = tmsK6[getBits(4)];
487 synthK7 = tmsK7[getBits(4)];
488 synthK8 = tmsK8[getBits(3)];
489 synthK9 = tmsK9[getBits(3)];
490 synthK10 = tmsK10[getBits(3)];
494 return energy != 0xf;
Talkie is a software implementation of the Texas Instruments speech synthesis architecture (Linear Pr...
Definition: Talkie.h:25
void setDataCallback(void(*cb)(int16_t *data, int len))
Defines the data callback that receives the generated samples.
Definition: Talkie.h:246
void say(const uint8_t *address)
converts the provided word into samples
Definition: Talkie.h:38
void setChannels(uint16_t ch)
Defines the number of generated output channels (2=stereo). Default is 1 = mono.
Definition: Talkie.h:251
void setOutput(Print &out)
Defines the Arduino data target.
Definition: Talkie.h:240
void setOutputAsText(bool flag)
converts samples to csv string format
Definition: Talkie.h:35
void sayNumber(long aNumber)
say any number between -999,999 and 999,999
Definition: Talkie.h:72
void silence(uint16_t ms)
outputs silence for the indicated milliseconds
Definition: Talkie.h:44