Program to record speech audio into RAM and then play it back, moving Billy Bass's mouth in sync with the speech.

Dependencies:   mbed

Remember Big Mouth Billy Bass?

I've made a simple demo program for him using the Freescale FRDM-KL25Z board. I've hooked up the digital I/O to his motor driver transistors and pushbutton switch.

This program records 1.8 seconds of speech audio from ADC input when the pushbutton is pressed, then plays the audio back with Billy Bass's mouth controlled so that it opens during vowel sounds.

The ADC input is driven from a microphone and preamplifier, via a capacitor and into a resistor divider connected to the +3.3V supply pin to provide mid-range biasing for the ADC signals.

The DAC output is connected to his audio amplifier input (to the trace that was connected to pin 10 of the controller IC). I had to provide a DC bias using the DAC to get the single transistor amplifier biased into proper operation.

For more on the method of vowel recognition, please see the paper: http://www.mirlab.org/conference_papers/International_Conference/ICASSP%201999/PDF/AUTHOR/IC991957.PDF

Y. Nishida, Y. Nakadai, Y. Suzuki, T. Sakurai, T. Kurokawa, and H. Sato. 1999.

Voice recognition focusing on vowel strings on a fixed-point 20-MIPS DSP board.

In Proceedings of the Acoustics, Speech, and Signal Processing, 1999. on 1999 IEEE International Conference - Volume 01 (ICASSP '99), Vol. 1. IEEE Computer Society, Washington, DC, USA, 137-140. DOI=10.1109/ICASSP.1999.758081 http://dx.doi.org/10.1109/ICASSP.1999.758081

Committer:
bikeNomad
Date:
Tue May 14 14:08:22 2013 +0000
Revision:
1:2fa375aacece
Parent:
0:1ddd40d843cb
Child:
2:5bcd2f55a294
trying to get continuous conversion going

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bikeNomad 0:1ddd40d843cb 1 #include "mbed.h"
bikeNomad 1:2fa375aacece 2 #include "FastAnalogIn.h"
bikeNomad 1:2fa375aacece 3 using namespace NK;
bikeNomad 1:2fa375aacece 4
bikeNomad 1:2fa375aacece 5 // Power:
bikeNomad 1:2fa375aacece 6 // Power GND J9/14
bikeNomad 1:2fa375aacece 7 // Vin (6V) J9/16
bikeNomad 0:1ddd40d843cb 8
bikeNomad 1:2fa375aacece 9 // Digital:
bikeNomad 1:2fa375aacece 10 DigitalOut tail(PTA13); // J3/2
bikeNomad 1:2fa375aacece 11 DigitalOut mouth(PTC12); // J3/1
bikeNomad 1:2fa375aacece 12 DigitalOut head(PTC13); // J3/3
bikeNomad 1:2fa375aacece 13 DigitalIn pushbutton(PTD5); // J3/4
bikeNomad 1:2fa375aacece 14
bikeNomad 1:2fa375aacece 15 PwmOut redLED(LED_RED);
bikeNomad 1:2fa375aacece 16 PwmOut greenLED(LED_GREEN);
bikeNomad 1:2fa375aacece 17 PwmOut blueLED(LED_BLUE);
bikeNomad 0:1ddd40d843cb 18
bikeNomad 1:2fa375aacece 19 // Analog:
bikeNomad 1:2fa375aacece 20 // GND J3/14
bikeNomad 1:2fa375aacece 21 // VrefH J3/16
bikeNomad 1:2fa375aacece 22 FastAnalogIn microphone(PTB0); // J10/2
bikeNomad 1:2fa375aacece 23 AnalogOut speaker(PTE30); // J10/11
bikeNomad 1:2fa375aacece 24
bikeNomad 1:2fa375aacece 25 // Communications:
bikeNomad 1:2fa375aacece 26 // Serial uart1(PTC4, PTC3);
bikeNomad 1:2fa375aacece 27 Serial pc(USBTX, USBRX);
bikeNomad 1:2fa375aacece 28
bikeNomad 1:2fa375aacece 29 const unsigned SAMPLE_RATE_HZ = 7812;
bikeNomad 1:2fa375aacece 30 const unsigned SAMPLE_PERIOD_US = (1000000U / SAMPLE_RATE_HZ);
bikeNomad 1:2fa375aacece 31
bikeNomad 1:2fa375aacece 32 Ticker sampleTicker;
bikeNomad 1:2fa375aacece 33
bikeNomad 1:2fa375aacece 34 uint8_t sampleBuffer[SAMPLE_RATE_HZ]; // 1 second buffer
bikeNomad 1:2fa375aacece 35 uint8_t * volatile nextSample;
bikeNomad 1:2fa375aacece 36 unsigned volatile samplesRemaining;
bikeNomad 1:2fa375aacece 37
bikeNomad 1:2fa375aacece 38 extern "C"
bikeNomad 1:2fa375aacece 39 void ADC0_IRQHandler(void)
bikeNomad 0:1ddd40d843cb 40 {
bikeNomad 1:2fa375aacece 41 pc.printf("irq\r\n");
bikeNomad 1:2fa375aacece 42 if (samplesRemaining) {
bikeNomad 1:2fa375aacece 43 *nextSample++ = microphone.read_u16() >> 8;
bikeNomad 1:2fa375aacece 44 samplesRemaining--;
bikeNomad 1:2fa375aacece 45 } else {
bikeNomad 1:2fa375aacece 46 microphone.disable_interrupt();
bikeNomad 0:1ddd40d843cb 47 }
bikeNomad 0:1ddd40d843cb 48 }
bikeNomad 0:1ddd40d843cb 49
bikeNomad 1:2fa375aacece 50 void playAudioSample()
bikeNomad 1:2fa375aacece 51 {
bikeNomad 1:2fa375aacece 52 if (samplesRemaining) {
bikeNomad 1:2fa375aacece 53 speaker.write_u16(*nextSample++ << 8);
bikeNomad 1:2fa375aacece 54 samplesRemaining--;
bikeNomad 1:2fa375aacece 55 } else {
bikeNomad 1:2fa375aacece 56 sampleTicker.detach();
bikeNomad 1:2fa375aacece 57 }
bikeNomad 1:2fa375aacece 58 }
bikeNomad 1:2fa375aacece 59
bikeNomad 1:2fa375aacece 60 void resetSampleBuffer()
bikeNomad 1:2fa375aacece 61 {
bikeNomad 1:2fa375aacece 62 nextSample = sampleBuffer;
bikeNomad 1:2fa375aacece 63 samplesRemaining = sizeof(sampleBuffer);
bikeNomad 1:2fa375aacece 64 }
bikeNomad 1:2fa375aacece 65
bikeNomad 1:2fa375aacece 66 void recordAudio()
bikeNomad 1:2fa375aacece 67 {
bikeNomad 1:2fa375aacece 68 pc.printf("Recording %d samples... ", sizeof(sampleBuffer));
bikeNomad 1:2fa375aacece 69 blueLED = 0.0;
bikeNomad 1:2fa375aacece 70
bikeNomad 1:2fa375aacece 71 resetSampleBuffer();
bikeNomad 1:2fa375aacece 72 microphone.enable_interrupt();
bikeNomad 1:2fa375aacece 73
bikeNomad 1:2fa375aacece 74 while (samplesRemaining) {
bikeNomad 1:2fa375aacece 75 wait(0.05);
bikeNomad 1:2fa375aacece 76 blueLED.write(1.0 - (1.0 * samplesRemaining / sizeof(sampleBuffer)));
bikeNomad 1:2fa375aacece 77 }
bikeNomad 1:2fa375aacece 78
bikeNomad 1:2fa375aacece 79 pc.printf("Done\r\n");
bikeNomad 1:2fa375aacece 80 }
bikeNomad 1:2fa375aacece 81
bikeNomad 1:2fa375aacece 82 void playAudio()
bikeNomad 1:2fa375aacece 83 {
bikeNomad 1:2fa375aacece 84 pc.printf("Playing %d samples... ", sizeof(sampleBuffer));
bikeNomad 1:2fa375aacece 85 greenLED = 0.0;
bikeNomad 1:2fa375aacece 86 resetSampleBuffer();
bikeNomad 1:2fa375aacece 87 sampleTicker.attach_us(&playAudioSample, SAMPLE_PERIOD_US);
bikeNomad 1:2fa375aacece 88 while (samplesRemaining) {
bikeNomad 1:2fa375aacece 89 wait(0.05);
bikeNomad 1:2fa375aacece 90 greenLED.write(1.0 - (1.0 * samplesRemaining / sizeof(sampleBuffer)));
bikeNomad 1:2fa375aacece 91 }
bikeNomad 1:2fa375aacece 92 pc.printf("Done\r\n");
bikeNomad 1:2fa375aacece 93
bikeNomad 1:2fa375aacece 94 }
bikeNomad 0:1ddd40d843cb 95 int main()
bikeNomad 0:1ddd40d843cb 96 {
bikeNomad 1:2fa375aacece 97 pc.baud(115200);
bikeNomad 1:2fa375aacece 98 pc.printf("Sample buffer = %u samples; rate = %u Hz; period = %u usec\r\n", sizeof(sampleBuffer), SAMPLE_RATE_HZ, SAMPLE_PERIOD_US);
bikeNomad 1:2fa375aacece 99 redLED = 1.0;
bikeNomad 1:2fa375aacece 100 greenLED = 1.0;
bikeNomad 1:2fa375aacece 101 blueLED = 1.0;
bikeNomad 1:2fa375aacece 102
bikeNomad 1:2fa375aacece 103 microphone.enable_interrupt();
bikeNomad 1:2fa375aacece 104 microphone.start_read();
bikeNomad 1:2fa375aacece 105
bikeNomad 1:2fa375aacece 106 recordAudio();
bikeNomad 1:2fa375aacece 107
bikeNomad 1:2fa375aacece 108 playAudio();
bikeNomad 0:1ddd40d843cb 109 }