The following code lets the EMIC-2 speak what you enter into the serial monitor:
#include <SoftwareSerial.h>
#define rxPin 10 // Serial input (connects to Emic 2's SOUT pin)
#define txPin 11 // Serial output (connects to Emic 2's SIN pin)
// Set up a new SoftwareSerial port
SoftwareSerial emicSerial = SoftwareSerial(rxPin, txPin);
void setup()
{
// Define pin modes
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
// Set the data rate for the SoftwareSerial port
emicSerial.begin(9600);
Serial.begin(9600);
/*
When the Emic 2 powers on, it takes about 3 seconds for it to successfully
initialize. It then sends a ":" character to indicate it's ready to accept
commands. If the Emic 2 is already initialized, a CR will also cause it
to send a ":"
*/
emicSerial.println("P1"); // Select parser, P0: DECtalk, P1: Epson
emicSerial.println("N4"); // Nx, select voice: x = 0 to 8
emicSerial.println("V5"); // Vx, set the audio output volume in dB from x = -48 (softest) to x = 18 (loudest).
emicSerial.println("W200"); // Wx, set the speaking rate in words per minute from x = 75 (slowest) to x = 600 (fastest).
emicSerial.print('\n'); // Send a CR in case the system is already up
while (emicSerial.read() != ':'); // When the Emic 2 has initialized and is ready, it will send a single ':' character, so wait here until we receive it
delay(10); // Short delay
emicSerial.flush(); // Flush the receive buffer
}
void loop()
{
while (Serial.available() == 0); // Wait for data available
String userInput = Serial.readString(); // Read until timeout
userInput.trim(); // Remove any whitespace at the end of the String
Serial.println(userInput);
emicSerial.print('S');
emicSerial.print(userInput);
emicSerial.print('\n');
/*
Wait here until the Emic 2 responds with a ":"
indicating it's ready to accept the next command
*/
while (emicSerial.read() != ':');
}
The problem with lip-synchronization is that there is no way on the software side to determine exactly when the EMIC-2 has finished the speech. The line
while (emicSerial.read() != ':');
is completely useless for that. It merely shows when the EMIC-2 is ready for new commands, which will come true long before the end of the speech. Others have already had this problem and I will solve it in the same way. I will use the audio output of the EMIC-2 to control the four servos that are responsible for the movement of the mouth. This requires a so-called envelop follower, which reproduces the volume envelope of an applied waveform.
Fig. 1 A signal and its envelope marked with red
Fig 2. shows such an envelope detector circuit.
Fig. 2
Apart from the operating voltage, it is only important that the opamp has a rail-to-rail output swing. The LMV358 can also be used, for example.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.