Forum Rule: Always post complete source code & details to reproduce any issue!
Page 3 of 4 FirstFirst 1 2 3 4 LastLast
Results 51 to 75 of 79

Thread: Talkie speech library

  1. #51
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,419
    Quote Originally Posted by defragster View Post
    my qBlink()
    Wanna have a "Teensyier" qBlink(); ?
    Code:
    #define qBlink() {GPIOC_PTOR=32;}

  2. #52
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,807
    Quote Originally Posted by Frank B View Post
    Wanna have a "Teensyier" qBlink(); ?
    Code:
    #define qBlink() {GPIOC_PTOR=32;}
    You are my hero FrankB - does that work on LC as well?

    Update pending . . . changing the return of .active() from bool to count of number of sounds to play until silence, where ZERO means silent now.

  3. #53
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,807
    Updated the PULL requested - includes indicated change to .active() return value.

    Modified sample from Adrian (using Prop Shield) to demonstrate usage of .say() and all added methods of "Talkie voice":SayQAcornAdrian.ino Also uses FrankB faster qBlink()!

    Edits to Talkie.cpp and .h and keywords.txt :: Removed the delay(25) from .say using .sayQ

    Called it sayQ() because I added a 24 sound queue managed in the code so not one but 25 sounds can be pushed into a queue for playing sequentially without user attention or delay.

    .active() - is **false** on silence, else **returns count** of sounds yet to play
    .sayQ() - returns the space left in queue
    .sayQ(0) empties the que and stops audio out
    .say(0) empties the que and stops audio out
    .say() is otherwise 'unchanged' - it will block

    Added example of all methods: SayQAcorn.ino
    Core Talkie code unchanged, except for cascaded timer to update synthesis data

  4. #54
    Senior Member adrian's Avatar
    Join Date
    Oct 2015
    Location
    Wellington, NZ
    Posts
    504
    groovy...Thanks so much for doing this ....I guess you got a surprise when I left out the digital pin write for the prop board from my example (im using a usb interface and a high quality standalone headphone amp) ... I'm playing around with your voltmeter example. I like it a lot. I think I might index the acorn samples completely..... its fun using a string of numbers to make the lc talk. and it could be handy for receiving numbers from the serial input, counting them, putting them in an array and sending them to 'sendQ' .... I need to learn a bit more about buffers and things. thanks again.

  5. #55
    Senior Member adrian's Avatar
    Join Date
    Oct 2015
    Location
    Wellington, NZ
    Posts
    504
    I've modified your first voltmeter example ... I used indexing and a data array ... The way your example calls a function within a function is most instructive I would never have worked that out on my own in 999999 years ... very clever technique. Anyway, my rewrite seems to work without calling a blocking 'say' to stage the audio, and the indexing appears to save a bit of memory... its so much fun ... I'm going to get it to count beats "1 and 2 and 3 and 4" from my sequencer clock, just for giggles. I wrote one song in 19 / 8 time a couple of years ago ... might be more of a challenge.... Maybe it can tell me the current volume or pan setting... or maybe my current midi channel... oh joy.

    Code:
    #define VOLTMETER
    #include <Talkie.h>
    
    #ifdef VOLTMETER
    
    /*    0*/const uint8_t NOTHING[]    PROGMEM = {0};
    /*    1*/const uint8_t spONE[]      PROGMEM = {0x66, 0x4E, 0xA8, 0x7A, 0x8D, 0xED, 0xC4, 0xB5, 0xCD, 0x89, 0xD4, 0xBC, 0xA2, 0xDB, 0xD1, 0x27, 0xBE, 0x33, 0x4C, 0xD9, 0x4F, 0x9B, 0x4D, 0x57, 0x8A, 0x76, 0xBE, 0xF5, 0xA9, 0xAA, 0x2E, 0x4F, 0xD5, 0xCD, 0xB7, 0xD9, 0x43, 0x5B, 0x87, 0x13, 0x4C, 0x0D, 0xA7, 0x75, 0xAB, 0x7B, 0x3E, 0xE3, 0x19, 0x6F, 0x7F, 0xA7, 0xA7, 0xF9, 0xD0, 0x30, 0x5B, 0x1D, 0x9E, 0x9A, 0x34, 0x44, 0xBC, 0xB6, 0x7D, 0xFE, 0x1F};
    /*    2*/const uint8_t spTWO[]      PROGMEM = {0x06, 0xB8, 0x59, 0x34, 0x00, 0x27, 0xD6, 0x38, 0x60, 0x58, 0xD3, 0x91, 0x55, 0x2D, 0xAA, 0x65, 0x9D, 0x4F, 0xD1, 0xB8, 0x39, 0x17, 0x67, 0xBF, 0xC5, 0xAE, 0x5A, 0x1D, 0xB5, 0x7A, 0x06, 0xF6, 0xA9, 0x7D, 0x9D, 0xD2, 0x6C, 0x55, 0xA5, 0x26, 0x75, 0xC9, 0x9B, 0xDF, 0xFC, 0x6E, 0x0E, 0x63, 0x3A, 0x34, 0x70, 0xAF, 0x3E, 0xFF, 0x1F};
    /*    3*/const uint8_t spTHREE[]    PROGMEM = {0x0C, 0xE8, 0x2E, 0x94, 0x01, 0x4D, 0xBA, 0x4A, 0x40, 0x03, 0x16, 0x68, 0x69, 0x36, 0x1C, 0xE9, 0xBA, 0xB8, 0xE5, 0x39, 0x70, 0x72, 0x84, 0xDB, 0x51, 0xA4, 0xA8, 0x4E, 0xA3, 0xC9, 0x77, 0xB1, 0xCA, 0xD6, 0x52, 0xA8, 0x71, 0xED, 0x2A, 0x7B, 0x4B, 0xA6, 0xE0, 0x37, 0xB7, 0x5A, 0xDD, 0x48, 0x8E, 0x94, 0xF1, 0x64, 0xCE, 0x6D, 0x19, 0x55, 0x91, 0xBC, 0x6E, 0xD7, 0xAD, 0x1E, 0xF5, 0xAA, 0x77, 0x7A, 0xC6, 0x70, 0x22, 0xCD, 0xC7, 0xF9, 0x89, 0xCF, 0xFF, 0x03};
    /*    4*/const uint8_t spFOUR[]     PROGMEM = {0x08, 0x68, 0x21, 0x0D, 0x03, 0x04, 0x28, 0xCE, 0x92, 0x03, 0x23, 0x4A, 0xCA, 0xA6, 0x1C, 0xDA, 0xAD, 0xB4, 0x70, 0xED, 0x19, 0x64, 0xB7, 0xD3, 0x91, 0x45, 0x51, 0x35, 0x89, 0xEA, 0x66, 0xDE, 0xEA, 0xE0, 0xAB, 0xD3, 0x29, 0x4F, 0x1F, 0xFA, 0x52, 0xF6, 0x90, 0x52, 0x3B, 0x25, 0x7F, 0xDD, 0xCB, 0x9D, 0x72, 0x72, 0x8C, 0x79, 0xCB, 0x6F, 0xFA, 0xD2, 0x10, 0x9E, 0xB4, 0x2C, 0xE1, 0x4F, 0x25, 0x70, 0x3A, 0xDC, 0xBA, 0x2F, 0x6F, 0xC1, 0x75, 0xCB, 0xF2, 0xFF};
    /*    5*/const uint8_t spFIVE[]     PROGMEM = {0x08, 0x68, 0x4E, 0x9D, 0x02, 0x1C, 0x60, 0xC0, 0x8C, 0x69, 0x12, 0xB0, 0xC0, 0x28, 0xAB, 0x8C, 0x9C, 0xC0, 0x2D, 0xBB, 0x38, 0x79, 0x31, 0x15, 0xA3, 0xB6, 0xE4, 0x16, 0xB7, 0xDC, 0xF5, 0x6E, 0x57, 0xDF, 0x54, 0x5B, 0x85, 0xBE, 0xD9, 0xE3, 0x5C, 0xC6, 0xD6, 0x6D, 0xB1, 0xA5, 0xBF, 0x99, 0x5B, 0x3B, 0x5A, 0x30, 0x09, 0xAF, 0x2F, 0xED, 0xEC, 0x31, 0xC4, 0x5C, 0xBE, 0xD6, 0x33, 0xDD, 0xAD, 0x88, 0x87, 0xE2, 0xD2, 0xF2, 0xF4, 0xE0, 0x16, 0x2A, 0xB2, 0xE3, 0x63, 0x1F, 0xF9, 0xF0, 0xE7, 0xFF, 0x01};
    /*    6*/const uint8_t spSIX[]      PROGMEM = {0x04, 0xF8, 0xAD, 0x4C, 0x02, 0x16, 0xB0, 0x80, 0x06, 0x56, 0x35, 0x5D, 0xA8, 0x2A, 0x6D, 0xB9, 0xCD, 0x69, 0xBB, 0x2B, 0x55, 0xB5, 0x2D, 0xB7, 0xDB, 0xFD, 0x9C, 0x0D, 0xD8, 0x32, 0x8A, 0x7B, 0xBC, 0x02, 0x00, 0x03, 0x0C, 0xB1, 0x2E, 0x80, 0xDF, 0xD2, 0x35, 0x20, 0x01, 0x0E, 0x60, 0xE0, 0xFF, 0x01};
    /*    7*/const uint8_t spSEVEN[]    PROGMEM = {0x0C, 0xF8, 0x5E, 0x4C, 0x01, 0xBF, 0x95, 0x7B, 0xC0, 0x02, 0x16, 0xB0, 0xC0, 0xC8, 0xBA, 0x36, 0x4D, 0xB7, 0x27, 0x37, 0xBB, 0xC5, 0x29, 0xBA, 0x71, 0x6D, 0xB7, 0xB5, 0xAB, 0xA8, 0xCE, 0xBD, 0xD4, 0xDE, 0xA6, 0xB2, 0x5A, 0xB1, 0x34, 0x6A, 0x1D, 0xA7, 0x35, 0x37, 0xE5, 0x5A, 0xAE, 0x6B, 0xEE, 0xD2, 0xB6, 0x26, 0x4C, 0x37, 0xF5, 0x4D, 0xB9, 0x9A, 0x34, 0x39, 0xB7, 0xC6, 0xE1, 0x1E, 0x81, 0xD8, 0xA2, 0xEC, 0xE6, 0xC7, 0x7F, 0xFE, 0xFB, 0x7F};
    /*    8*/const uint8_t spEIGHT[]    PROGMEM = {0x65, 0x69, 0x89, 0xC5, 0x73, 0x66, 0xDF, 0xE9, 0x8C, 0x33, 0x0E, 0x41, 0xC6, 0xEA, 0x5B, 0xEF, 0x7A, 0xF5, 0x33, 0x25, 0x50, 0xE5, 0xEA, 0x39, 0xD7, 0xC5, 0x6E, 0x08, 0x14, 0xC1, 0xDD, 0x45, 0x64, 0x03, 0x00, 0x80, 0x00, 0xAE, 0x70, 0x33, 0xC0, 0x73, 0x33, 0x1A, 0x10, 0x40, 0x8F, 0x2B, 0x14, 0xF8, 0x7F};
    /*    9*/const uint8_t spNINE[]     PROGMEM = {0xE6, 0xA8, 0x1A, 0x35, 0x5D, 0xD6, 0x9A, 0x35, 0x4B, 0x8C, 0x4E, 0x6B, 0x1A, 0xD6, 0xA6, 0x51, 0xB2, 0xB5, 0xEE, 0x58, 0x9A, 0x13, 0x4F, 0xB5, 0x35, 0x67, 0x68, 0x26, 0x3D, 0x4D, 0x97, 0x9C, 0xBE, 0xC9, 0x75, 0x2F, 0x6D, 0x7B, 0xBB, 0x5B, 0xDF, 0xFA, 0x36, 0xA7, 0xEF, 0xBA, 0x25, 0xDA, 0x16, 0xDF, 0x69, 0xAC, 0x23, 0x05, 0x45, 0xF9, 0xAC, 0xB9, 0x8F, 0xA3, 0x97, 0x20, 0x73, 0x9F, 0x54, 0xCE, 0x1E, 0x45, 0xC2, 0xA2, 0x4E, 0x3E, 0xD3, 0xD5, 0x3D, 0xB1, 0x79, 0x24, 0x0D, 0xD7, 0x48, 0x4C, 0x6E, 0xE1, 0x2C, 0xDE, 0xFF, 0x0F};
    /*   10*/const uint8_t spTEN[]      PROGMEM = {0x0E, 0x38, 0x3C, 0x2D, 0x00, 0x5F, 0xB6, 0x19, 0x60, 0xA8, 0x90, 0x93, 0x36, 0x2B, 0xE2, 0x99, 0xB3, 0x4E, 0xD9, 0x7D, 0x89, 0x85, 0x2F, 0xBE, 0xD5, 0xAD, 0x4F, 0x3F, 0x64, 0xAB, 0xA4, 0x3E, 0xBA, 0xD3, 0x59, 0x9A, 0x2E, 0x75, 0xD5, 0x39, 0x6D, 0x6B, 0x0A, 0x2D, 0x3C, 0xEC, 0xE5, 0xDD, 0x1F, 0xFE, 0xB0, 0xE7, 0xFF, 0x03};
    /*   11*/const uint8_t spELEVEN[]   PROGMEM = {0xA5, 0xEF, 0xD6, 0x50, 0x3B, 0x67, 0x8F, 0xB9, 0x3B, 0x23, 0x49, 0x7F, 0x33, 0x87, 0x31, 0x0C, 0xE9, 0x22, 0x49, 0x7D, 0x56, 0xDF, 0x69, 0xAA, 0x39, 0x6D, 0x59, 0xDD, 0x82, 0x56, 0x92, 0xDA, 0xE5, 0x74, 0x9D, 0xA7, 0xA6, 0xD3, 0x9A, 0x53, 0x37, 0x99, 0x56, 0xA6, 0x6F, 0x4F, 0x59, 0x9D, 0x7B, 0x89, 0x2F, 0xDD, 0xC5, 0x28, 0xAA, 0x15, 0x4B, 0xA3, 0xD6, 0xAE, 0x8C, 0x8A, 0xAD, 0x54, 0x3B, 0xA7, 0xA9, 0x3B, 0xB3, 0x54, 0x5D, 0x33, 0xE6, 0xA6, 0x5C, 0xCB, 0x75, 0xCD, 0x5E, 0xC6, 0xDA, 0xA4, 0xCA, 0xB9, 0x35, 0xAE, 0x67, 0xB8, 0x46, 0x40, 0xB6, 0x28, 0xBB, 0xF1, 0xF6, 0xB7, 0xB9, 0x47, 0x20, 0xB6, 0x28, 0xBB, 0xFF, 0x0F};
    /*   12*/const uint8_t spTWELVE[]   PROGMEM = {0x09, 0x98, 0xDA, 0x22, 0x01, 0x37, 0x78, 0x1A, 0x20, 0x85, 0xD1, 0x50, 0x3A, 0x33, 0x11, 0x81, 0x5D, 0x5B, 0x95, 0xD4, 0x44, 0x04, 0x76, 0x9D, 0xD5, 0xA9, 0x3A, 0xAB, 0xF0, 0xA1, 0x3E, 0xB7, 0xBA, 0xD5, 0xA9, 0x2B, 0xEB, 0xCC, 0xA0, 0x3E, 0xB7, 0xBD, 0xC3, 0x5A, 0x3B, 0xC8, 0x69, 0x67, 0xBD, 0xFB, 0xE8, 0x67, 0xBF, 0xCA, 0x9D, 0xE9, 0x74, 0x08, 0xE7, 0xCE, 0x77, 0x78, 0x06, 0x89, 0x32, 0x57, 0xD6, 0xF1, 0xF1, 0x8F, 0x7D, 0xFE, 0x1F};
    /*   13*/const uint8_t spTHIR_[]    PROGMEM = {0x04, 0xA8, 0xBE, 0x5C, 0x00, 0xDD, 0xA5, 0x11, 0xA0, 0xFA, 0x72, 0x02, 0x74, 0x97, 0xC6, 0x01, 0x09, 0x9C, 0xA6, 0xAB, 0x30, 0x0D, 0xCE, 0x7A, 0xEA, 0x6A, 0x4A, 0x39, 0x35, 0xFB, 0xAA, 0x8B, 0x1B, 0xC6, 0x76, 0xF7, 0xAB, 0x2E, 0x79, 0x19, 0xCA, 0xD5, 0xEF, 0xCA, 0x57, 0x08, 0x14, 0xA1, 0xDC, 0x45, 0x64, 0x03, 0x00, 0xC0, 0xFF, 0x03};
    /*   14*/const uint8_t spFIF_[]     PROGMEM = {0x08, 0x98, 0x31, 0x93, 0x02, 0x1C, 0xE0, 0x80, 0x07, 0x5A, 0xD6, 0x1C, 0x6B, 0x78, 0x2E, 0xBD, 0xE5, 0x2D, 0x4F, 0xDD, 0xAD, 0xAB, 0xAA, 0x6D, 0xC9, 0x23, 0x02, 0x56, 0x4C, 0x93, 0x00, 0x05, 0x10, 0x90, 0x89, 0x31, 0xFC, 0x3F};
    /*   15*/const uint8_t sp_TEEN[]    PROGMEM = {0x09, 0x58, 0x2A, 0x25, 0x00, 0xCB, 0x9F, 0x95, 0x6C, 0x14, 0x21, 0x89, 0xA9, 0x78, 0xB3, 0x5B, 0xEC, 0xBA, 0xB5, 0x23, 0x13, 0x46, 0x97, 0x99, 0x3E, 0xD6, 0xB9, 0x2E, 0x79, 0xC9, 0x5B, 0xD8, 0x47, 0x41, 0x53, 0x1F, 0xC7, 0xE1, 0x9C, 0x85, 0x54, 0x22, 0xEC, 0xFA, 0xDB, 0xDD, 0x23, 0x93, 0x49, 0xB8, 0xE6, 0x78, 0xFF, 0x3F};
    /*   16*/const uint8_t spTWENTY[]   PROGMEM = {0x0A, 0xE8, 0x4A, 0xCD, 0x01, 0xDB, 0xB9, 0x33, 0xC0, 0xA6, 0x54, 0x0C, 0xA4, 0x34, 0xD9, 0xF2, 0x0A, 0x6C, 0xBB, 0xB3, 0x53, 0x0E, 0x5D, 0xA6, 0x25, 0x9B, 0x6F, 0x75, 0xCA, 0x61, 0x52, 0xDC, 0x74, 0x49, 0xA9, 0x8A, 0xC4, 0x76, 0x4D, 0xD7, 0xB1, 0x76, 0xC0, 0x55, 0xA6, 0x65, 0xD8, 0x26, 0x99, 0x5C, 0x56, 0xAD, 0xB9, 0x25, 0x23, 0xD5, 0x7C, 0x32, 0x96, 0xE9, 0x9B, 0x20, 0x7D, 0xCB, 0x3C, 0xFA, 0x55, 0xAE, 0x99, 0x1A, 0x30, 0xFC, 0x4B, 0x3C, 0xFF, 0x1F};
    /*   17*/const uint8_t spT[]        PROGMEM = {0x01, 0xD8, 0xB6, 0xDD, 0x01, 0x2F, 0xF4, 0x38, 0x60, 0xD5, 0xD1, 0x91, 0x4D, 0x97, 0x84, 0xE6, 0x4B, 0x4E, 0x36, 0xB2, 0x10, 0x67, 0xCD, 0x19, 0xD9, 0x2C, 0x01, 0x94, 0xF1, 0x78, 0x66, 0x33, 0xEB, 0x79, 0xAF, 0x7B, 0x57, 0x87, 0x36, 0xAF, 0x52, 0x08, 0x9E, 0x6B, 0xEA, 0x5A, 0xB7, 0x7A, 0x94, 0x73, 0x45, 0x47, 0xAC, 0x5A, 0x9C, 0xAF, 0xFF, 0x07};
    /*   18*/const uint8_t spHUNDRED[]  PROGMEM = {0x04, 0xC8, 0x7E, 0x5C, 0x02, 0x0A, 0xA8, 0x62, 0x43, 0x03, 0xA7, 0xA8, 0x62, 0x43, 0x4B, 0x97, 0xDC, 0xF2, 0x14, 0xC5, 0xA7, 0x9B, 0x7A, 0xD3, 0x95, 0x37, 0xC3, 0x1E, 0x16, 0x4A, 0x66, 0x36, 0xF3, 0x5A, 0x89, 0x6E, 0xD4, 0x30, 0x55, 0xB5, 0x32, 0xB7, 0x31, 0xB5, 0xC1, 0x69, 0x2C, 0xE9, 0xF7, 0xBC, 0x96, 0x12, 0x39, 0xD4, 0xB5, 0xFD, 0xDA, 0x9B, 0x0F, 0xD1, 0x90, 0xEE, 0xF5, 0xE4, 0x17, 0x02, 0x45, 0x28, 0x77, 0x11, 0xD9, 0x40, 0x9E, 0x45, 0xDD, 0x2B, 0x33, 0x71, 0x7A, 0xBA, 0x0B, 0x13, 0x95, 0x2D, 0xF9, 0xF9, 0x7F};
    /*   19*/const uint8_t spTHOUSAND[] PROGMEM = {0x0C, 0xE8, 0x2E, 0xD4, 0x02, 0x06, 0x98, 0xD2, 0x55, 0x03, 0x16, 0x68, 0x7D, 0x17, 0xE9, 0x6E, 0xBC, 0x65, 0x8C, 0x45, 0x6D, 0xA6, 0xE9, 0x96, 0xDD, 0xDE, 0xF6, 0xB6, 0xB7, 0x5E, 0x75, 0xD4, 0x93, 0xA5, 0x9C, 0x7B, 0x57, 0xB3, 0x6E, 0x7D, 0x12, 0x19, 0xAD, 0xDC, 0x29, 0x8D, 0x4F, 0x93, 0xB4, 0x87, 0xD2, 0xB6, 0xFC, 0xDD, 0xAC, 0x22, 0x56, 0x02, 0x70, 0x18, 0xCA, 0x18, 0x26, 0xB5, 0x90, 0xD4, 0xDE, 0x6B, 0x29, 0xDA, 0x2D, 0x25, 0x17, 0x8D, 0x79, 0x88, 0xD4, 0x48, 0x79, 0x5D, 0xF7, 0x74, 0x75, 0xA1, 0x94, 0xA9, 0xD1, 0xF2, 0xED, 0x9E, 0xAA, 0x51, 0xA6, 0xD4, 0x9E, 0x7F, 0xED, 0x6F, 0xFE, 0x2B, 0xD1, 0xC7, 0x3D, 0x89, 0xFA, 0xB7, 0x0D, 0x57, 0xD3, 0xB4, 0xF5, 0x37, 0x55, 0x37, 0x2E, 0xE6, 0xB2, 0xD7, 0x57, 0xFF, 0x0F};
    /*   20*/const uint8_t spAND[]      PROGMEM = {0xA9, 0x6B, 0x21, 0xB9, 0x22, 0x66, 0x9F, 0xAE, 0xC7, 0xE1, 0x70, 0x7B, 0x72, 0xBB, 0x5B, 0xDF, 0xEA, 0x56, 0xBB, 0x5C, 0x65, 0xCB, 0x66, 0xC5, 0x3D, 0x67, 0xD7, 0xAB, 0x6D, 0x2E, 0x64, 0x30, 0x93, 0xEE, 0xB1, 0xCD, 0x3D, 0x92, 0xB9, 0x9A, 0xDA, 0xB2, 0x8E, 0x40, 0x12, 0x9A, 0x6A, 0xEB, 0x96, 0x8F, 0x78, 0x98, 0xB3, 0x2A, 0xB4, 0xD3, 0x48, 0xAA, 0x2F, 0x7D, 0xA7, 0x7B, 0xFB, 0x0C, 0x73, 0x71, 0x5C, 0xCE, 0x6E, 0x5C, 0x52, 0x6C, 0x73, 0x79, 0x9A, 0x13, 0x4B, 0x89, 0x45, 0xE9, 0x6E, 0x49, 0x42, 0xA9, 0x57, 0xFF, 0x3F};
    /*   21*/const uint8_t spPAUSE1[]   PROGMEM = {0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F};
    /*   22*/const uint8_t spZERO[]     PROGMEM = {0x69, 0xFB, 0x59, 0xDD, 0x51, 0xD5, 0xD7, 0xB5, 0x6F, 0x0A, 0x78, 0xC0, 0x52, 0x01, 0x0F, 0x50, 0xAC, 0xF6, 0xA8, 0x16, 0x15, 0xF2, 0x7B, 0xEA, 0x19, 0x47, 0xD0, 0x64, 0xEB, 0xAD, 0x76, 0xB5, 0xEB, 0xD1, 0x96, 0x24, 0x6E, 0x62, 0x6D, 0x5B, 0x1F, 0x0A, 0xA7, 0xB9, 0xC5, 0xAB, 0xFD, 0x1A, 0x62, 0xF0, 0xF0, 0xE2, 0x6C, 0x73, 0x1C, 0x73, 0x52, 0x1D, 0x19, 0x94, 0x6F, 0xCE, 0x7D, 0xED, 0x6B, 0xD9, 0x82, 0xDC, 0x48, 0xC7, 0x2E, 0x71, 0x8B, 0xBB, 0xDF, 0xFF, 0x1F};
    /*   23*/const uint8_t spMINUS[]    PROGMEM = {0xE6, 0x28, 0xC4, 0xF8, 0x44, 0x9A, 0xFB, 0xCD, 0xAD, 0x8D, 0x2A, 0x4E, 0x4A, 0xBC, 0xB8, 0x8C, 0xB9, 0x8A, 0xA9, 0x48, 0xED, 0x72, 0x87, 0xD3, 0x74, 0x3B, 0x1A, 0xA9, 0x9D, 0x6F, 0xB3, 0xCA, 0x5E, 0x8C, 0xC3, 0x7B, 0xF2, 0xCE, 0x5A, 0x5E, 0x35, 0x66, 0x5A, 0x3A, 0xAE, 0x55, 0xEB, 0x9A, 0x57, 0x75, 0xA9, 0x29, 0x6B, 0xEE, 0xB6, 0xD5, 0x4D, 0x37, 0xEF, 0xB5, 0x5D, 0xC5, 0x95, 0x84, 0xE5, 0xA6, 0xFC, 0x30, 0xE0, 0x97, 0x0C, 0x0D, 0x58, 0x40, 0x03, 0x1C, 0xA0, 0xC0, 0xFF, 0x03};
    /*   24*/const uint8_t spMILLI[]    PROGMEM = {0x6E, 0xF0, 0x8A, 0xB3, 0x4B, 0xEB, 0xC6, 0xAE, 0x36, 0xA7, 0x1A, 0x3A, 0x54, 0x53, 0xD6, 0xDC, 0xEC, 0x66, 0x23, 0xDF, 0x58, 0x26, 0x43, 0xB4, 0xCD, 0xEA, 0x74, 0x5D, 0x94, 0x46, 0xF0, 0x96, 0x3B, 0x9D, 0x79, 0x98, 0x26, 0x75, 0xDB, 0xB3, 0xD7, 0xB6, 0xF5, 0x90, 0xA8, 0x91, 0x9F, 0xEA, 0x9E, 0xEE, 0xE9, 0x9B, 0x20, 0x7D, 0xCB, 0xFF, 0x03};
    /*   25*/const uint8_t spVOLTS[]    PROGMEM = {0xA0, 0xDA, 0xA2, 0xB2, 0x3A, 0x44, 0x55, 0x9C, 0xFA, 0xB0, 0xBA, 0x46, 0x72, 0xDA, 0xD1, 0xDB, 0xAE, 0x47, 0x59, 0x61, 0xED, 0x28, 0x79, 0xED, 0x45, 0xAF, 0x5A, 0xDF, 0x60, 0xF4, 0x39, 0x69, 0xAB, 0x63, 0xD9, 0x3B, 0xD2, 0xBC, 0x24, 0xA5, 0xF5, 0xB6, 0x0F, 0x80, 0x01, 0x3E, 0x63, 0x65, 0xC0, 0x5F, 0x63, 0x12, 0x90, 0x80, 0x06, 0x24, 0x20, 0x01, 0x0E, 0xFC, 0x3F};
    /*index*/const uint8_t * indexArray [] PROGMEM = {NOTHING,spONE,spTWO,spTHREE,spFOUR,spFIVE,spSIX,spSEVEN,spEIGHT,spNINE,spTEN,spELEVEN,spTWELVE,spTHIR_,spFIF_,sp_TEEN,spTWENTY,spT,spHUNDRED,spTHOUSAND,spAND,spPAUSE1,spZERO,spMINUS,spMILLI,spVOLTS};
    #endif
    
    uint8_t numberWords (int * array, int n, uint8_t & c) {
      if (n < 0) {
        array [c] = 23; //MINUS
        c += 1;
        n = 0-n;
      }
      byte pattern = 0;
      if (n >= 1000) {
        int thousands = n / 1000;
        numberWords (array, thousands, c); 
        array [c] = 19;
        c += 1;
        pattern |= 1 << 2;
        n %= 1000; if (n == 0) {
          return 1;
        }
      }
      if (n >= 100) {
        int hundreds = n / 100;
        numberWords (array, hundreds, c); 
        array [c] = 18;
        c += 1;
        pattern |= 1 << 1;
        n %= 100; if (n == 0) {
          return 1;
        }
      }
      if (n >= 10) {
      { if ( (pattern & (1 << 2)) || (pattern & (1 << 1)) ) {
            array [c] = 20; //AND
            c += 1;
          }
        }
      { if ( (n >= 60) ||  ( (n >= 40) && (n <= 49) ) ) {
            array [c]   = n / 10;
            array [c + 1] = 17; //T
            c += 2;
            pattern |= 1;
            n %= 10; if (n == 0) {
              return 1;
            }
          }
        }
        { if (n >= 50) {
            array [c]   = 14;
            array [c + 1] = 17; //T
            c += 2;
            pattern |= 1;
            n %= 10; if (n == 0) {
              return 1;
            }
          }
        }
        { if (n >= 30) {
            array [c]   = 13;
            array [c + 1] = 17; //T
            c += 2;
            pattern |= 1;
            n %= 10; if (n == 0) {
              return 1;
            }
          }
        }
      { if (n >= 20) {
            array [c]   = 16; //TWENTY
            c += 1;
            pattern |= 1;
            n %= 10; if (n == 0) {
              return 1;
            }
          }
        }
      { if ( (n == 14) || ( (n >= 16) && (n <= 19) ) ) {
            array [c]   = n % 10;
            array [c + 1] = 15; //TEEN
            c += 2;
            return 1;
          }
        }
      { if (n == 15) {
            array [c]   = 14;
            array [c + 1] = 15; //TEEN
            c += 2;
            return 1;
          }
        }{ if (n == 13) {
            array [c]   = 13;
            array [c + 1] = 15; //TEEN
            c += 2;
            return 1;
          }
        }
     { if (n == 12) {
            array [c]   = 12;
            c += 1;
            return 1;
          }
        }
      { if (n == 11) {
            array [c]   = 11;
            c += 1;
            return 1;
          }
        }
      { if (n == 10) {
            array [c]   = 10;
            c += 1;
            return 1;
          }
        }
      }
      if (    ( (pattern & (1 << 2)) || (pattern & (1 << 1))  ) &&  (!(pattern & 1))      )  {
        array [c] = 20; //AND
        c += 1;
      }
      array [c]   = n;
      c += 1;
      return 1;
    }
    
    Talkie voice;
    
    void setup() {
    Serial.begin(9600);
      pinMode(5, OUTPUT);
      digitalWrite(5, 1);//propshield amp enable code
    }
    
    void loop() {
      int wordarray [24];
      int number = 845911;
      //int number = analogRead(0) * 5.000 / 1.023; // voltage
      uint8_t counter = 0;
      if (number == 0) {wordarray[0] = 22; counter += 1;} //zero, say ZERO
      else {numberWords(wordarray, number, counter);} // fill number word array
      wordarray [counter] = 24; wordarray [counter + 1] = 25; counter +=2; //add in MILLIVOLTS ...
      arrayInterface (wordarray, counter); // "SAYQ"
      // delay (50);
    }
    
    void arrayInterface (int * wordArray, uint8_t wordArraySize) {
      for (uint8_t i = 0; i < wordArraySize; i++) {
        voice.sayQ (indexArray[wordArray[i]]);
      }
    }
    Last edited by adrian; 03-30-2016 at 08:26 AM.

  6. #56
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,807
    @Adrian - good fun. The voltmeter example was existing with the library and uses recursion to solve later parts of the problem in a cool way - without duplicating the effort as you go from higher order numbers down.

    Interesting how it saved much memory - you did in your code what the queue portion I wrote in .sayQ() does - good practice. It seemed like a common issue when assembling a group of text - as I saw in my early examples - so I decided it would best be built into the library itself so it wouldn't need to be re-created. Whenever you call sayQ() it returns how many empty spaces are in the queue - I settled on 24 as that made it take about a round 100 bytes of RAM - and 24 sounds can be a long wait - and is easily supplemented as needed - or it could be expanded in the library. The other thing I added at the last minute was having .active() return the number of active items in the queue yet to play.

    instead of writing two lines:: "array [c] = n; and c += 1;" you could replace that with "array [c++] = n;" to tell it to increment the variable c AFTER it is used each time since you always do that when adding an item. It'll make no difference to the compiler - but will shorten the text on your screen.

  7. #57
    Junior Member
    Join Date
    Mar 2016
    Posts
    1
    Quote Originally Posted by PaulStoffregen View Post
    I ported to Teensy, just now!

    https://github.com/PaulStoffregen/Talkie

    I tested on Teensy LC and 3.2. Both work great. The output is on the DAC pin, as a true analog signal, not PWM as on Arduino.
    Hi Paul,

    I have some of your older Teensy 2.0 boards. Should I use your ported code or the original Talkie library for this board?

    Regards,
    Eric

  8. #58
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,506
    I haven't tested, but I'm pretty sure Talkie can't work on Teensy 2.0. It uses AVR timer2.

    Might work on Teensy++ 2.0, which does have that timer.

  9. #59
    Senior Member adrian's Avatar
    Join Date
    Oct 2015
    Location
    Wellington, NZ
    Posts
    504
    @defragster thanks for the pointers, and thanks for your continued work! a 1 a 2 a 1 2 3 4 ...

  10. #60
    Senior Member adrian's Avatar
    Join Date
    Oct 2015
    Location
    Wellington, NZ
    Posts
    504
    @ebsebs ... i use a teensy LC for talkie ... works good... i suspect a higher quality DAC would be 'better'.... but the possible drawback is if you are going to utilise a large sample library ... the LC has less memory than a 3.x .... So I guess it will depend on what your intentions are (if you are thinking of 'upgrading') ....

  11. #61
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,807
    Quote Originally Posted by PaulStoffregen View Post
    I haven't tested, but I'm pretty sure Talkie can't work on Teensy 2.0. It uses AVR timer2.

    Might work on Teensy++ 2.0, which does have that timer.
    There is a pull request if you wanted to put it into 1.28b2. I ran my T_3.2 at 24MHz and it ran fine - not sure if the 16MHz AVR might stutter on the chaining data update I did to stop the blocking.

  12. #62
    Hi everyone. I've just read the above thread about the Talkie library on Teensy 3.2
    We have some Teensy 3.2's and a bunch of audio boards. Any ideas how I'd go about getting the talkie library to output through the Audio board's headphone socket?
    Thanks,
    Steve.

  13. #63
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,807
    Look in examples. The AMP pin has to be set HIGH.

    pjrc.com/store/prop_shield.html

    pinMode(5, OUTPUT);
    digitalWrite(5, HIGH); // turn on the amplifier
    <edit> : . . . I read 'audio' as the PROP board I linked.
    Last edited by defragster; 10-25-2016 at 08:43 AM.

  14. #64
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,506
    Quote Originally Posted by mubase View Post
    ideas how I'd go about getting the talkie library to output through the Audio board's headphone socket?
    Sorry, that's not supported. Talkie only outputs to the DAC/A14 pin. It doesn't have any code to send as I2S format to the chip on the audio shield.

  15. #65
    I just discovered this library while browsing the examples in the Arduino IDE.
    Great work! The demos are funny and put a huge smile on my face, hah!

    I ran talkie on a Teensy 3.6 and the examples work well. Also the code posted above worked.

    My Signal Path:
    DAC0 (A21) pin >> alligator clip wires >> RCA to 1/8" stereo jack >> line-in on laptop PC, >> Sony HDTV, audio is fine for what it is.

    This library and member enhancements above really catch the essence of the hacker spirit, great stuff and funny too.

    I used to design interactive voice response (IVR) or simply put, telephone voice mail and similiar platforms for commercial use.
    I wonder if anyone heard thought of using Teensy 3.x as a voice-over-IP end point, like for voice mail, IVR, etc, via some minimalist voice over IP stack?

    Talkie could be used to play numbers and other values that are decided on the fly, like "The current soil temperature is 75 degrees"

    A voice over IP telephony library would probably use an SIP stack for VOIP call control, and RTP protocol for
    the audio in and out.

    Maybe this was a bit much for Teensy 3.2, and as such not considered by anyone, but maybe Teensy 3.6 is fast enough to make it possible?

    Disclaimer: the following is merely a dream of possibilities and in no way reflects my expectations that someone built the monster described below,
    but to inspire and spark ideas in the minds of forum members who are good enough programmers to consider the idea.

    Uncompressed telephony audio streams are only 8 bits @ 8000 samples per second, ulaw PCM.
    (64,000 bits per second, that's only 8 kilobytes per second each direction).

    That's alot less than playing 4 hi-fi audio channels at 44.1K samples/sec 16 bits each, a favorite quoted Teensy capability.

    Maybe with Teensy 3.5/3.6 now available, someone could justify the effort to port an open source SIP call library over to Teensy, and mod talkie
    while they are at it, to stream such 8k audio out to either the audio library, as requested above, or to a telephony library.

    I would do it so far as interest and motivation is concerned, but I only know the general structure; I'm not that good a programmer yet to take on that beast.

    Non blocking talkie would be a great candidate for speech synthesis on VOIP role I suspect, assuming and I know it's a big job, that someone ports a telephony library to Teensy.

    A basic VOIP library should handle recording/playback on the line, play voice prompts, and handle touch tone detection / collection of digits, with the ability
    to interrupt the current playback or recording when a touch tone is detected.

    Finally, a user programmed API could wrap the complexity so users can make a call handling script equivalent to what voice XML does but much simpler.
    The end result is you could call your Teensy's phone number from any phone and interact with voice menus, leave voice messages on the card or change
    settings of remote sensor, etc, and receive spoken voice telemetry over the phone. Teensy could call your cell phone if something significant happens on a sensor,
    or any internet originated trigger, etc, and then speak about what event happened, etc.

    I will keep this idea in mind for when I get up to speed, but will support any effort in that direction as a former general user-level programmer of such beasts.

    Maybe an alternative is to wire a suitable voice over IP module to Teensy, let it handle the SIP calls, and pass audio in and out to teensy, and some control protocol. Hmm.
    I wonder about those cheap VOIP phone dongles or similiar little self contained modules as possible candidates. Audio and signaling need be considered to connect to Teensy.

    /End of wild idea.

    Now, off to make talkie say more funny things...
    Last edited by Mr Mayhem; 10-30-2016 at 07:20 PM.

  16. #66
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,419
    As far as i know, there are cheap GSM-Modules from china (aliexpr*ss) available - much easier to use than voice over ip.
    Or hack a analog phone...

  17. #67
    Yeah, that's something I want to play with too, saw some examples on Adafruit, probably cheaper on AliExpress, etc.
    Definitely the choice if it's outside and away from other networks, like a wildlife cam, etc.

    I like the idea of VoIP because of easy and cheap multi-channel capabilities built in to the protocol stack, and that even cell phones
    can run VoIP software apps for a self-made communication network riding on IP, bypassing the need in many cases to buy monthly
    services for connectivity.
    Such service fees easily outweigh the cost of the particular hardware in this case.

    Speaking of enabling Teensy 3.x with wireless data-
    I successfully got an ESP8266 to connect as an SPI slave to a Teensy 3.6 master recently,
    as part of a larger 256 pixel photo diode array sensor reading project.

    Bits flow fast like this:
    sensor >> Teensy 3.6 >> SPI >> ESP8266 >> WiFi UDP packets >> home router >> laptop >> Processing graphical plot of pixel data.

    I am seeing roughly about 150 frames (complete sensor reads, 256 samples, 2 bytes each sample) per second.
    I will post it soon after I clean it up.

    (edit)
    I posted my first version of the TSL1402R sensor reader, which simply has the Teensy 3.6 read the sendor and send the data via USB serial.
    Soon I will publish the more complex one described above, invoking SPI to WiFi module for Teensy 3.6.
    https://forum.pjrc.com/threads/39058...782#post121782
    (/edit)

    To avoid voice service gateway monthly fees, you just "dial" an IP address on most SIP VoIP apps, and the call(s) would be all IP voice
    to the Teensy.

    It would be cool to have a web based sip client enabled to "call my gadget for a live demo" kind of thing.

    If it could handle, say, 5 to 10 calls at the same time, heck, you have a platform that bridges Arduino to VoIP
    for doing call based embedded control/telemetry of all sorts with touch tone menus, etc:

    "Press 1 to run blinky test. Press 2 to make robot fetch beer. Press 3, to hear top news headlines and start coffee" etc.

    Maybe a vending machine app? Call to dispense your free drink, and marketing gets the phone number, heh.

    World's smallest VoIP PBX/office phone system/IVR platform on a Teensy 3.6? Linux Asterisk, eat your heart out!

    Probably better to run on a Raspberry PI for a more "serious" micro PBX, but being very small and super-inexpensive as a Teensy,
    captures the essence of internet of things, and can be stuffed into tiny places.

    Heh, call my drone direct to order a pizza delivered. Just kidding, sort of.
    You could pass VoIP calls through a drone for disaster communications, and use it as a tower repeater for range.
    Pretty strong option if it can handle a bunch of calls at the same time, and maybe tether-powered so it can stay up a long time.
    Or simply put it on a rooftop or tower as a self-contained low power solar makeshift relay station, etc.

    The boards like Teensy 3.5/3.6 and ESP8266 are so cheap and fast, these kind of applications historically reserved for bigger and badder
    boards are creeping into this super small embedded hobbyist realm, opening up possibilities.

    I love the idea of an Arduino telephony VoIP library...

    Funny what one cool talking voice library can trigger in one's head.
    Last edited by Mr Mayhem; 11-02-2016 at 05:07 PM.

  18. #68
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,860
    Re: ideas how I'd go about getting the talkie library to output through the Audio board's headphone socket?

    Quote Originally Posted by PaulStoffregen View Post
    Sorry, that's not supported. Talkie only outputs to the DAC/A14 pin. It doesn't have any code to send as I2S format to the chip on the audio shield.
    I think you could jumper the Teensy DAC to LineIn L of audio adaptor and play through headphones, see similar example with TTS
    https://forum.pjrc.com/threads/44587...l=1#post145790
    Last edited by manitou; 06-28-2017 at 05:13 PM.

  19. #69
    Junior Member
    Join Date
    Feb 2018
    Posts
    2
    hi there, new (potential) user.

    so i tried the original talkie library on an arduino uno, works great. then i started adding midi in and midi control which worked not so great because of the blockiness :-) (part of it can be solved by putting the MIDI.read(); calls also in the do while brackets... still it is far from ideal or clean.

    the non blocking version does not correctly work on an arduino uno. speech is output but at maximum rate, so a whole phrase is only a short noise of 150ms or so :-)

    so my questions are:

    -will midi control (old school serial din, and usb) work with the teensy and the non blocking library? (i guess so) i would like to choose phrases/words, alter pitch and speed and have different playmodes:
    -start and stop on note On, note Off. word repeated as long as no note off is received.
    -onesot mode: just play the word once you get a noteon don't repeat don't abort even when a note off is received before word is finished
    -maybe a random mode that just spits out "garbage" (random values for the synthK variables)

    -can i change the speed of the spoken words and also the pitch? (in the original library i just modified OCR1A to get different pitched vocals and i altered the delay(); to speedup or slowdown the speech) so i guess the question is, is it easy to alter the speed at which sayisr() is called?

    thanks

  20. #70
    Junior Member
    Join Date
    Feb 2018
    Posts
    2
    Quote Originally Posted by lokki View Post
    hi there, new (potential) user.

    so i tried the original talkie library on an arduino uno, works great. then i started adding midi in and midi control which worked not so great because of the blockiness :-) (part of it can be solved by putting the MIDI.read(); calls also in the do while brackets... still it is far from ideal or clean.

    the non blocking version does not correctly work on an arduino uno. speech is output but at maximum rate, so a whole phrase is only a short noise of 150ms or so :-)

    so my questions are:

    -will midi control (old school serial din, and usb) work with the teensy and the non blocking library? (i guess so) i would like to choose phrases/words, alter pitch and speed and have different playmodes:
    -start and stop on note On, note Off. word repeated as long as no note off is received.
    -onesot mode: just play the word once you get a noteon don't repeat don't abort even when a note off is received before word is finished
    -maybe a random mode that just spits out "garbage" (random values for the synthK variables)

    -can i change the speed of the spoken words and also the pitch? (in the original library i just modified OCR1A to get different pitched vocals and i altered the delay(); to speedup or slowdown the speech) so i guess the question is, is it easy to alter the speed at which sayisr() is called?

    thanks
    just a quick update...i put the MIDI.read(); into the ISR(TIMER1_COMPA_vect) {} and it works very well so far on the arduino uno with the original library. nice!
    still interested how feasible this is on the teensy :-)

  21. #71
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,807
    Paul did the Teensy ARM specific Timer part - I added the non blocking queue. The Teensy should be able to do both at the same time as long as they don't have any conflicting resources. If the rate of timer firing is altered - to change pitch? - it should work fine as the queueing I did counts timed events to load the next batch of data. If the events happen slower or faster - the non-blocking playback should follow along without issue - with the sound being 'skewed' { as desired }.

    But the data is just a stream - so repeating a word would have to be an isolated sample - that word could repeat over and over until note off is received. It isn't something that the queueing code would do programmatically. IIRC the queue can be filled and emptied and monitored for its state. Those features should allow much of what the sketch would want to do. Since it does not block - this could be done on the fly in the sketch.
    Last edited by defragster; 02-01-2018 at 09:21 PM.

  22. #72
    Junior Member
    Join Date
    Nov 2012
    Posts
    18
    Just found this library - and wow!. Thanks defragster and Paul. Any chance it could be written to NOT use analog out and instead one or two PWM pins? This way I could add voice to any of my existing Teensy projects by only soldering a speaker two one or two pins on the teensy, obviating the need for an amplifier purchase.

    --Rudy

  23. #73
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,419
    An integration into the audiolibrary would be best, as it lets you choose the output, and apply filters, mixers, effects...

  24. #74
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    2,663
    Actually we just implemented the Talkie Library so it will use any PWM pin: https://github.com/PaulStoffregen/Talkie. You can now initialize it to use the propshield or PWM using one of these two begins:
    Code:
    	void beginPWM(uint8_t pinPWM);
    	void beginPropShield();

  25. #75
    Junior Member
    Join Date
    Nov 2012
    Posts
    18
    Woo Hoo! Thank you Paul!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •