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. */
main.cpp@0:bbf6cf0eab95, 2014-03-27 (annotated)
- Committer:
- bw
- Date:
- Thu Mar 27 21:27:04 2014 +0000
- Revision:
- 0:bbf6cf0eab95
- Child:
- 2:9429f84ea165
Initial.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bw | 0:bbf6cf0eab95 | 1 | /******************************************************************************* |
bw | 0:bbf6cf0eab95 | 2 | * Project: USB Sound Effects. |
bw | 0:bbf6cf0eab95 | 3 | * |
bw | 0:bbf6cf0eab95 | 4 | * Uses the mbed LPC1768 and mbed-application-board to create a USB audio device |
bw | 0:bbf6cf0eab95 | 5 | * that streams audio from a host computer to headphones or powered speakers. |
bw | 0:bbf6cf0eab95 | 6 | * A couple different sound effects can be applied to the stream in real-time, |
bw | 0:bbf6cf0eab95 | 7 | * tilting the mbed alters the effects. |
bw | 0:bbf6cf0eab95 | 8 | * |
bw | 0:bbf6cf0eab95 | 9 | * ECHO |
bw | 0:bbf6cf0eab95 | 10 | * The joystick selects ) | |
bw | 0:bbf6cf0eab95 | 11 | * one of three effect ) STRAIGHT - o - STRAIGHT |
bw | 0:bbf6cf0eab95 | 12 | * modes. ) | |
bw | 0:bbf6cf0eab95 | 13 | * REVERB |
bw | 0:bbf6cf0eab95 | 14 | * |
bw | 0:bbf6cf0eab95 | 15 | * |
bw | 0:bbf6cf0eab95 | 16 | * |
bw | 0:bbf6cf0eab95 | 17 | * \\ || |
bw | 0:bbf6cf0eab95 | 18 | * Tilting the mbed ) ====== \\ || |
bw | 0:bbf6cf0eab95 | 19 | * determines intensity ) \\ || |
bw | 0:bbf6cf0eab95 | 20 | * of the effect. ) |
bw | 0:bbf6cf0eab95 | 21 | * 0% 50% 100% |
bw | 0:bbf6cf0eab95 | 22 | * |
bw | 0:bbf6cf0eab95 | 23 | * The LCD display shows the current effect mode, intesity and buffer level. |
bw | 0:bbf6cf0eab95 | 24 | * |
bw | 0:bbf6cf0eab95 | 25 | * For better audio quality, packets are buffered before playbeck. Playback is |
bw | 0:bbf6cf0eab95 | 26 | * halted when the buffer drops below two packets and resumes when it is greater |
bw | 0:bbf6cf0eab95 | 27 | * than four packets. This creates a lag of a few milliseconds, which is not |
bw | 0:bbf6cf0eab95 | 28 | * detectable by a listener using straight playback mode. |
bw | 0:bbf6cf0eab95 | 29 | * |
bw | 0:bbf6cf0eab95 | 30 | * The echo effect produces echos with a delay of about 250 milliseconds. Tilting |
bw | 0:bbf6cf0eab95 | 31 | * the mbed alters the persistence of echo. |
bw | 0:bbf6cf0eab95 | 32 | * |
bw | 0:bbf6cf0eab95 | 33 | * The reverb effect utilizes multiple delay lines of length varying from |
bw | 0:bbf6cf0eab95 | 34 | * about 25 to 200 milliseconds. Again, tilting the mbed alters the |
bw | 0:bbf6cf0eab95 | 35 | * persistence. |
bw | 0:bbf6cf0eab95 | 36 | * |
bw | 0:bbf6cf0eab95 | 37 | * Implemenation Notes: |
bw | 0:bbf6cf0eab95 | 38 | * Audio playback is implement with an mbed ticker, and it is critical that this interrupt |
bw | 0:bbf6cf0eab95 | 39 | * is not delayed to acheive decent audio quality. USB audio packet handling also uses |
bw | 0:bbf6cf0eab95 | 40 | * interrupts, but the priority is set lower to ensure proper playback. The USBAudio class |
bw | 0:bbf6cf0eab95 | 41 | * was modified to use a callback to transfer the received packet from the packet buffer to |
bw | 0:bbf6cf0eab95 | 42 | * the larger playback buffer. The user interface is handled entirely in the user-context |
bw | 0:bbf6cf0eab95 | 43 | * since it has only soft timing requirements. |
bw | 0:bbf6cf0eab95 | 44 | * |
bw | 0:bbf6cf0eab95 | 45 | * Future work: |
bw | 0:bbf6cf0eab95 | 46 | * 1. Clocks within the host computer and mbed will differ slightly, so the |
bw | 0:bbf6cf0eab95 | 47 | * average sample rate from the computer will not exactly match the average mbed |
bw | 0:bbf6cf0eab95 | 48 | * playback rate. Over time the playback buffer level with creep until it becomes |
bw | 0:bbf6cf0eab95 | 49 | * totaly empty or full. The current implementation addresses this by simply |
bw | 0:bbf6cf0eab95 | 50 | * increasing the buffer size and selecting a sample rate that the mbed |
bw | 0:bbf6cf0eab95 | 51 | * can replicate most accurately (mulitple of 1 us to use mbed Ticker). A better |
bw | 0:bbf6cf0eab95 | 52 | * solution may be to slightly alter the playback rate in response to the buffer level. |
bw | 0:bbf6cf0eab95 | 53 | * For example use 20us rate when the buffer level is high and 19us when the buffer |
bw | 0:bbf6cf0eab95 | 54 | * level is low. Of course this would distort the playback frequecy by 5%, so it would |
bw | 0:bbf6cf0eab95 | 55 | * be even better to make a custom timer interrupt with better resolution than the |
bw | 0:bbf6cf0eab95 | 56 | * mbed ticker. |
bw | 0:bbf6cf0eab95 | 57 | * |
bw | 0:bbf6cf0eab95 | 58 | * 2. It would be interesting to add stereo audio, but the mbed-application-board |
bw | 0:bbf6cf0eab95 | 59 | * audio jack is mono so this would require hardware customization. |
bw | 0:bbf6cf0eab95 | 60 | * |
bw | 0:bbf6cf0eab95 | 61 | * Bryan Wade |
bw | 0:bbf6cf0eab95 | 62 | * 27 MAR 2014 |
bw | 0:bbf6cf0eab95 | 63 | ******************************************************************************/ |
bw | 0:bbf6cf0eab95 | 64 | |
bw | 0:bbf6cf0eab95 | 65 | #include "mbed.h" |
bw | 0:bbf6cf0eab95 | 66 | #include "audio.h" |
bw | 0:bbf6cf0eab95 | 67 | #include "effects.h" |
bw | 0:bbf6cf0eab95 | 68 | #include "user_interface.h" |
bw | 0:bbf6cf0eab95 | 69 | |
bw | 0:bbf6cf0eab95 | 70 | int main() |
bw | 0:bbf6cf0eab95 | 71 | { |
bw | 0:bbf6cf0eab95 | 72 | UI_Initialize(); |
bw | 0:bbf6cf0eab95 | 73 | Audio_Initialize(); // Start audio playback. |
bw | 0:bbf6cf0eab95 | 74 | |
bw | 0:bbf6cf0eab95 | 75 | while (true) |
bw | 0:bbf6cf0eab95 | 76 | { |
bw | 0:bbf6cf0eab95 | 77 | // |
bw | 0:bbf6cf0eab95 | 78 | int32_t level = Audio_CheckPlaybackBufferLevel(); |
bw | 0:bbf6cf0eab95 | 79 | UI_Update(level); |
bw | 0:bbf6cf0eab95 | 80 | |
bw | 0:bbf6cf0eab95 | 81 | Effects_SetGain(UI_GetEffectGain()); |
bw | 0:bbf6cf0eab95 | 82 | Effects_SetMode(UI_GetEffectMode()); |
bw | 0:bbf6cf0eab95 | 83 | |
bw | 0:bbf6cf0eab95 | 84 | // 50 milliseconds provides good UI responsivness |
bw | 0:bbf6cf0eab95 | 85 | wait(.05); |
bw | 0:bbf6cf0eab95 | 86 | } |
bw | 0:bbf6cf0eab95 | 87 | } |
bw | 0:bbf6cf0eab95 | 88 |