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
audio.cpp
00001 /******************************************************************************* 00002 * Manages all aspects of audio playback with sound effects. 00003 * Bryan Wade 00004 * 27 MAR 2014 00005 ******************************************************************************/ 00006 #include "mbed.h" 00007 #include "USBAudio.h" 00008 #include "buffer.h" 00009 #include "effects.h" 00010 00011 static const int SAMPLE_FREQ = 50000; 00012 static const int NUM_CHANNELS = 1; 00013 static const int PACKET_FREQ = 1000; 00014 static const int PACKET_LENGTH = SAMPLE_FREQ / PACKET_FREQ; 00015 static const int PLAYBACK_BUFFER_SIZE = 8 * 1024; 00016 00017 static int16_t packetBuffer[PACKET_LENGTH]; 00018 static char playbackBufferRAM[PLAYBACK_BUFFER_SIZE]; 00019 static buffer_t *playbackBuffer; 00020 static bool playbackReady = false; 00021 00022 AnalogOut speaker(p18); 00023 USBAudio audio(SAMPLE_FREQ, NUM_CHANNELS, 8000, 1, 0x7180, 0x7500); 00024 Ticker playbackTic; 00025 DigitalOut bufferLED(LED1); // On when buffer is ready for playback. 00026 DigitalOut playbackLED(LED2); // On when playing audio. 00027 DigitalOut sampleLED(LED3); // Toggles on each audio sample played. 00028 DigitalOut packetLED(LED4); // Toggles on each audio packet received. 00029 00030 /* 00031 * Transfers packet to the playback buffer each time a packet is received. 00032 */ 00033 void handlePacket(void) { 00034 Buffer_WriteBlock(playbackBuffer, packetBuffer, PACKET_LENGTH); 00035 packetLED = !packetLED; 00036 } 00037 00038 /* 00039 * Pulls a sample from the playback buffer, adds effects and sends to speaker. 00040 */ 00041 void handlePlayback() 00042 { 00043 int16_t sample; 00044 00045 // Get a sample from playback buffer 00046 if (playbackReady) { 00047 if (Buffer_Read(playbackBuffer, &sample)) 00048 { 00049 playbackLED = 1; // Playing 00050 } else { 00051 sample = 0; // Shouldn't get hear if buffer limits set properly. 00052 playbackLED = 0; 00053 } 00054 } else { 00055 sample = 0; // Nothing to play 00056 playbackLED = 0; 00057 } 00058 00059 // Add sound effects 00060 int32_t out = Effects_ProcessSample(sample); 00061 00062 // Write the sample to the uni-polar A/D, which requires offseting the signed 16-bit sample. 00063 speaker.write_u16(out + 32767); 00064 00065 sampleLED = !sampleLED; 00066 } 00067 00068 /* 00069 * Initialize audio module. 00070 */ 00071 void Audio_Initialize(void) 00072 { 00073 Effects_Initialize(); 00074 00075 // Create a buffer that will incomming audio packets and provide a consistent supply 00076 // for playback at the desired sample rate. 00077 playbackBuffer = Buffer_Create(playbackBufferRAM, sizeof(playbackBufferRAM)); 00078 00079 // Start the playback timer interrupt that will call the playback handler at the desired 00080 // sample rate. 00081 playbackTic.attach_us(handlePlayback, 1000000.0/(float)(SAMPLE_FREQ)); 00082 00083 // Attach the handler that will buffer packets from incomming USB audio. 00084 // Perform the first read to set the buffer location, then all subsequent packets 00085 // will go to this buffer, and the handler pulls them from this small buffer 00086 // and places them in the large playback buffer. 00087 audio.attachReadCallback(handlePacket); 00088 audio.readNB((uint8_t *)packetBuffer); 00089 00090 // Reduce USB IRQ priority so that audio playback is not interrupted by USB activity. 00091 static const int LOW_PRIORITY = 255; // Larger number is lower priority. 00092 NVIC_SetPriority(USB_IRQn, LOW_PRIORITY); 00093 } 00094 00095 /* 00096 * Checks buffer level and updates playbackReady flag. 00097 * @return Buffer level. 00098 */ 00099 int32_t Audio_CheckPlaybackBufferLevel(void) 00100 { 00101 static int32_t PLAYBACK_START_LEVEL = 4 * PACKET_LENGTH; 00102 static int32_t PLAYBACK_STOP_LEVEL = 2 * PACKET_LENGTH; 00103 00104 int32_t level = Buffer_GetLevel(playbackBuffer); 00105 if (level > PLAYBACK_START_LEVEL) { 00106 playbackReady = true; 00107 } else if (level < PLAYBACK_STOP_LEVEL) { 00108 playbackReady = false; 00109 } 00110 00111 bufferLED = playbackReady; 00112 00113 return level; 00114 } 00115 00116
Generated on Thu Jul 14 2022 01:44:22 by 1.7.2