Streams USB audio with sound effects applied. Sound effect selected by joystick and intensity altered by tilting the mbed. Output to the mbed-application-board phono jack.
Dependencies: C12832_lcd MMA7660 USBDevice mbed
/* Uses the mbed LPC1768 and mbed-application-board to create a USB audio device * that streams audio from a host computer to headphones or powered speakers. * A couple different sound effects can be applied to the stream in real-time, * and tilting the mbed alters intensity of the effect. * * ECHO * The joystick selects ) | * one of three effect ) STRAIGHT - o - STRAIGHT * modes. ) | * REVERB * * * * \\ || * Tilting the mbed ) ====== \\ || * determines intensity ) \\ || * of the effect. ) * 0% 50% 100% * * The LCD display shows the current effect mode, intesity and buffer level. */
audio.cpp
- Committer:
- bw
- Date:
- 2014-03-27
- Revision:
- 0:bbf6cf0eab95
File content as of revision 0:bbf6cf0eab95:
/******************************************************************************* * Manages all aspects of audio playback with sound effects. * Bryan Wade * 27 MAR 2014 ******************************************************************************/ #include "mbed.h" #include "USBAudio.h" #include "buffer.h" #include "effects.h" static const int SAMPLE_FREQ = 50000; static const int NUM_CHANNELS = 1; static const int PACKET_FREQ = 1000; static const int PACKET_LENGTH = SAMPLE_FREQ / PACKET_FREQ; static const int PLAYBACK_BUFFER_SIZE = 8 * 1024; static int16_t packetBuffer[PACKET_LENGTH]; static char playbackBufferRAM[PLAYBACK_BUFFER_SIZE]; static buffer_t *playbackBuffer; static bool playbackReady = false; AnalogOut speaker(p18); USBAudio audio(SAMPLE_FREQ, NUM_CHANNELS, 8000, 1, 0x7180, 0x7500); Ticker playbackTic; DigitalOut bufferLED(LED1); // On when buffer is ready for playback. DigitalOut playbackLED(LED2); // On when playing audio. DigitalOut sampleLED(LED3); // Toggles on each audio sample played. DigitalOut packetLED(LED4); // Toggles on each audio packet received. /* * Transfers packet to the playback buffer each time a packet is received. */ void handlePacket(void) { Buffer_WriteBlock(playbackBuffer, packetBuffer, PACKET_LENGTH); packetLED = !packetLED; } /* * Pulls a sample from the playback buffer, adds effects and sends to speaker. */ void handlePlayback() { int16_t sample; // Get a sample from playback buffer if (playbackReady) { if (Buffer_Read(playbackBuffer, &sample)) { playbackLED = 1; // Playing } else { sample = 0; // Shouldn't get hear if buffer limits set properly. playbackLED = 0; } } else { sample = 0; // Nothing to play playbackLED = 0; } // Add sound effects int32_t out = Effects_ProcessSample(sample); // Write the sample to the uni-polar A/D, which requires offseting the signed 16-bit sample. speaker.write_u16(out + 32767); sampleLED = !sampleLED; } /* * Initialize audio module. */ void Audio_Initialize(void) { Effects_Initialize(); // Create a buffer that will incomming audio packets and provide a consistent supply // for playback at the desired sample rate. playbackBuffer = Buffer_Create(playbackBufferRAM, sizeof(playbackBufferRAM)); // Start the playback timer interrupt that will call the playback handler at the desired // sample rate. playbackTic.attach_us(handlePlayback, 1000000.0/(float)(SAMPLE_FREQ)); // Attach the handler that will buffer packets from incomming USB audio. // Perform the first read to set the buffer location, then all subsequent packets // will go to this buffer, and the handler pulls them from this small buffer // and places them in the large playback buffer. audio.attachReadCallback(handlePacket); audio.readNB((uint8_t *)packetBuffer); // Reduce USB IRQ priority so that audio playback is not interrupted by USB activity. static const int LOW_PRIORITY = 255; // Larger number is lower priority. NVIC_SetPriority(USB_IRQn, LOW_PRIORITY); } /* * Checks buffer level and updates playbackReady flag. * @return Buffer level. */ int32_t Audio_CheckPlaybackBufferLevel(void) { static int32_t PLAYBACK_START_LEVEL = 4 * PACKET_LENGTH; static int32_t PLAYBACK_STOP_LEVEL = 2 * PACKET_LENGTH; int32_t level = Buffer_GetLevel(playbackBuffer); if (level > PLAYBACK_START_LEVEL) { playbackReady = true; } else if (level < PLAYBACK_STOP_LEVEL) { playbackReady = false; } bufferLED = playbackReady; return level; }