Making the computer speak

We can store a recording of our voice in our little computer, and make it say things. The little computer doesn't have a lot of room for storing audio (it has 16,384 bytes, and the program has to live in that space too), but we can store a few seconds of digitized sound.

In the program above, I have removed a huge section of code in the middle of the array called 'data', to allow the whole program to be seen in a small image. The data is huge because it is almost a second of speech, recorded at 16,000 samples per second. So there are about 10,000 bytes in the array, and it goes on for several pages.

We use the keyword 'const' in front of the declaration to tell the compiler that this data is not going to change. This allows the compiler to put the data into the same place it puts the code (which, of course, also does not change during program execution). Our little computer has 16,384 bytes of flash memory into which we can place programs and data. It also has 512 bytes of RAM (random access memory) where we store variables that will change, such as the variable 'x' in the setup() function.

So this program takes up almost all of the space available on the little chip (we use up almost 11,000 bytes out of our 16,384 available).

All of the work is done in the setup() function. We connect a speaker to pin P1.6 and ground. We set P1.6 to output, and we call the analogFrequency() function to set the PWM frequency to a very high value, in this case 62,500 times per second. Our computer runs at 16,000,000 times per second, and we want 256 levels (8 bits worth) for our PWM. Dividing 16,000,000 by 256 gives us 62,500.

As an example, suppose the value we want to send is halfway between silence and as loud as we can make the speaker go. Our PWM would then turn the P1.6 bit on for 128 cycles of the 16 megahertz computer clock, and then off for another 128 clock ticks. We can do 62,500 of those every second.

We have recorded the sound at a rate of 16,000 samples per second. In the 'for' loop in setup(), we go through the entire data array, calling analogWrite() to set up the PWM to the value in the array. To ensure that we send the samples at the 16,000 sample per second rate (so we don't talk like we are breathing helium), we delay for 8 microseconds after each data byte is sent.

In this way, almost 4 PWM cycles happen for each data byte (62,500 divided by 16,000 is about 3.9).

The loop() function just sleeps, to save battery power if we are running off of batteries. But first we have to turn off the PWM timer that would otherwise keep sending pulses to P1.6. We do that by using the digitalWrite() function, which has the side-effect of turning off the analogWrite() timer. If we didn't do this, the speaker would waste battery power trying to stay in some position other than at rest.

To hear my voice, just press the reset button on the Launchpad. Every time the Launchpad gets power, or resets, the setup() function gets called, and it sends out the data.

 

At this point you might be wondering where all that data came from.

I recorded my voice saying "Hello there!" on my laptop computer. I told the recording software to save the recording as a .WAV file, using 8 bit samples, at 16,000 samples per second. Then I uploaded the .WAV file into a program I wrote, that converts the sound into C++ source code. I then used copy and paste to copy the code from the web browser to the Energia program to compile and run.

You can find the program to convert speech recordings into Launchpad code here.

The program is very simple to use. Click on the "Choose File" button to select the .WAV file you want to upload from your computer. Then click on the "Submit" button. A new window will pop up with the source code for you to copy.

The connections are simple, and shown above.

Our little Launchpad computer can't drive the speaker as well as we might like. The sound coming from it might be hard to hear in a noisy room. But we can fairly easily amplify it, using a single NPN transistor, such as the 2N2222A, or the 2N4401, or even the big TIP31 power transistor.

We connect the P1.6 pin to the base lead of the transistor (the middle lead in this example). We connect the ground to the emitter lead (the leftmost lead). We connect the speaker to the collector (the rightmost lead), and the other speaker lead connects to the +3.3 volt power supply of the Launchpad (marked VCC on the board).

Below is a close-up of the transistor part of the circuit:

Now the sound comes out reasonably loud.

But we can make it even louder by using a second power supply, just for the amplifier. Here is how to use a nine volt battery:

We remove the connection to the +3.3 volts on the Launchpad board. We keep the connection to ground, so the amplifier and the Launchpad both agree on what zero volts is.

We connect the negative side of the nine volt battery to ground. The positive side goes to the speaker, in place of the wire that used to go to the +3.3 volts on the Launchpad.

Now when pin P1.6 turns on the transistor switch, the nine volt battery current goes through the speaker, instead of the previous 3.3 volts.

The result is substantially louder.

 

Some code examples of computer speech:

Hello There at 11025 hz

Hello There at 16000 hz

Count Out Loud

Ouch Don't Touch Me