EMIC2 Text to Speech Demo in C for the propeller
twm47099
Posts: 867
I recently purchased an EMIC2 text to speech module. On the product download page there is a demo program for the propeller. It is a relatively simple demo written in Spin. It "says" a string defined in the DAT section and then runs one of the built in demo's (singing a song).
I spent some time learning how to use the module and expanding the demo to accept and say strings from keyboard input and to say a number of different strings that were in output statements. I had some difficulty getting timing of consecutive strings, but eventually learned how to make the module do what I wanted. I also learned a bit of Spin in the process.
One of the things I like to do is take a program written in one language and modify it to work in a different one. I also like to take different C tutorials and combine and modify them. In this case I'm thinking about adding the EMIC2 to my ActivityBot that uses Bluetooth or SIRC IR control. So the first step was to write an EMIC2 demo in C (I use simpleIDE).
I connected the EMIC2 to an Activity Board using prop pin 6 for EMIC Sin and prop pin 7 for EMIC Sout. Since Sout is a 5v signal, I put a 3.9k ohm resistor in series between Sout and Pin 7.
The C program listing is below. The program "says" a declared string (hello), Then says a string from a dprint format. It then verbally prompts for input for numbers, and says the result of a math calculation. Then it asks for a string from the keyboard and says it. Then it says a long string that is in 2 dprint statements, and says it's done a few times.
The program needs to be run with the terminal (F8).
I used both a veho speaker and simple headphones plugged into the jack on the module.
I've attached a file with the C program below.
Tom
I spent some time learning how to use the module and expanding the demo to accept and say strings from keyboard input and to say a number of different strings that were in output statements. I had some difficulty getting timing of consecutive strings, but eventually learned how to make the module do what I wanted. I also learned a bit of Spin in the process.
One of the things I like to do is take a program written in one language and modify it to work in a different one. I also like to take different C tutorials and combine and modify them. In this case I'm thinking about adding the EMIC2 to my ActivityBot that uses Bluetooth or SIRC IR control. So the first step was to write an EMIC2 demo in C (I use simpleIDE).
I connected the EMIC2 to an Activity Board using prop pin 6 for EMIC Sin and prop pin 7 for EMIC Sout. Since Sout is a 5v signal, I put a 3.9k ohm resistor in series between Sout and Pin 7.
The C program listing is below. The program "says" a declared string (hello), Then says a string from a dprint format. It then verbally prompts for input for numbers, and says the result of a math calculation. Then it asks for a string from the keyboard and says it. Then it says a long string that is in 2 dprint statements, and says it's done a few times.
The program needs to be run with the terminal (F8).
I used both a veho speaker and simple headphones plugged into the jack on the module.
I've attached a file with the C program below.
Tom
/* Basic EMIC2 C program to test control methods. Send "S" to start string to speak. A string terminator (new line)is needed to tell EMIC2 that the string has ended and to now speak. If the terminator is included in the dprint statement, e.g. dprinti(emic,"this is a test.\n"), a separate newline command is not needed to end the string and start the speaking. Otherwise the terminator must be sent in a separate command. See 3 options below. After the string and terminator are sent, it is necessary to pause the program until EMIC2 responds by sending a ":". Run with terminal (F8). */ #include "simpletools.h" #include "fdserial.h" #define emicRx 6 // Prop pin 6 #define emicTx 7 // Prop pin 7 fdserial *emic; char speak[] = {"hello"}; char mystring[81]; int a, b, c; int main() { printi("Emic2 start\n"); emic = fdserial_open(emicTx, emicRx, 0, 9600); // parameters (prop Rx pin, prop tx pin, mode, baud) printi("waiting for Emic2...\n"); printi("%s\n",&speak); // Just check to make sure the string is correct // ****** Clear EMIC2 ****** send terminator and wait until ready. // *** The following 3 options for sending the terminator work // dprinti(emic,"\n"); //fdserial_txChar(emic,13); writeChar(emic,NL); // note: NL is a library defined constant for newline // *** end of 3 options that work. Using the third option. // *** A couple of options that work for waiting until EMIC2 is ready //while(fdserial_rxChar(emic) != ':'); while(readChar(emic) != ':'); // wait for emic2 to send ready (:) use either ascii (58) or ':' // *** end of 2 options that work. Using second option // ****** end of initial clearing ****** // Set voice dprinti(emic,"N2"); // voices 0 through 8 see manual. writeChar(emic,NL); while(readChar(emic) != ':'); // ************** EMIC2 say the string "speak[]" ********************* // ** Send start-string command writeChar(emic,'S'); // Needs the 'S' to start string or put S before %s in dprinti statement // ** send the string dprinti(emic,"%s", &speak); // this statement does not have the terminator. Need following statement. // ** end the string and speak and wait until EMIC is ready writeChar(emic,NL); // send terminator // ** wait until EMIC is ready - this is needed after the new line is sent while(readChar(emic) != ':'); // check for ':' i.e. dec 58, use single quotes around : // ************** Finished with string "speak[] ******************" // ******* EMIC2 say the format string in a dprint statement ******* dprinti(emic, "S This is a test."); writeChar(emic,NL); // Since dprint statement did not have \n, this statement is needed while(readChar(emic) != ':'); // wait for emic2 to send ready // ******* EMIC2 Issues verbal prompts for user input ******* printi("enter a number: "); // print prompt to terminal dprinti(emic, "S Enter a number. "); // say prompt writeChar(emic,NL); getStr(&mystring, 24); // put terminal input statements before "EMIC ready" delay a = atoi(&mystring); while(readChar(emic) != ':'); dprinti(emic, "S Enter a second number. "); writeChar(emic,NL); printi("\nEnter a second number: "); getStr(&mystring, 24); // put terminal input statements before "EMIC ready" test b = atoi(&mystring); while(readChar(emic) != ':'); c = a + b; dprinti(emic, "S %d plus %d equals %d \n", a,b,c); //writeChar(emic,NL); // Since dprint statement DID HAVE \n, this statement is NOT needed while(readChar(emic) != ':'); printi("Enter some text: \n"); dprinti(emic,"S Enter some text: \n"); getStr(&mystring,81); // put terminal input statements before "EMIC ready" test while(readChar(emic) != ':'); printi("%s\n", &mystring); // print the string to terminal dprinti(emic, "S %s", &mystring); // say the string writeChar(emic,NL); while(readChar(emic) != ':'); // say a long string (1023 chars max) 2 sentences in 2 dprinti statements w/o a terminator in first dprinti dprinti(emic, "S We tested a declared string, text in a d print format, said a prompt,"); dprinti(emic, " said the result of a calculation. We are done.\n"); while(readChar(emic) != ':'); dprinti(emic, "S All done.\n"); while(readChar(emic) != ':'); dprinti(emic, "S finished.\n"); while(readChar(emic) != ':'); }