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. */
buffer.cpp@0:bbf6cf0eab95, 2014-03-27 (annotated)
- Committer:
- bw
- Date:
- Thu Mar 27 21:27:04 2014 +0000
- Revision:
- 0:bbf6cf0eab95
Initial.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bw | 0:bbf6cf0eab95 | 1 | /******************************************************************************* |
bw | 0:bbf6cf0eab95 | 2 | * Implements FIFO buffer for glitch-free audio playback. |
bw | 0:bbf6cf0eab95 | 3 | * Bryan Wade |
bw | 0:bbf6cf0eab95 | 4 | * 27 MAR 2014 |
bw | 0:bbf6cf0eab95 | 5 | ******************************************************************************/ |
bw | 0:bbf6cf0eab95 | 6 | #include "buffer.h" |
bw | 0:bbf6cf0eab95 | 7 | #include "string.h" |
bw | 0:bbf6cf0eab95 | 8 | |
bw | 0:bbf6cf0eab95 | 9 | struct buffer_t { // Implementation of opaque type. |
bw | 0:bbf6cf0eab95 | 10 | int16_t *base; |
bw | 0:bbf6cf0eab95 | 11 | int16_t *head; |
bw | 0:bbf6cf0eab95 | 12 | int16_t *tail; |
bw | 0:bbf6cf0eab95 | 13 | size_t len; |
bw | 0:bbf6cf0eab95 | 14 | }; |
bw | 0:bbf6cf0eab95 | 15 | |
bw | 0:bbf6cf0eab95 | 16 | /* |
bw | 0:bbf6cf0eab95 | 17 | * Create a buffer object given a ptr and size of available RAM. |
bw | 0:bbf6cf0eab95 | 18 | * @return Ptr to the new buffer. |
bw | 0:bbf6cf0eab95 | 19 | */ |
bw | 0:bbf6cf0eab95 | 20 | buffer_t *Buffer_Create(void *ram, size_t size) |
bw | 0:bbf6cf0eab95 | 21 | { |
bw | 0:bbf6cf0eab95 | 22 | buffer_t *buffer = (buffer_t *)malloc(sizeof(buffer_t)); |
bw | 0:bbf6cf0eab95 | 23 | if (buffer) { |
bw | 0:bbf6cf0eab95 | 24 | buffer->base = (int16_t *)ram; |
bw | 0:bbf6cf0eab95 | 25 | buffer->len = size / sizeof(int16_t); |
bw | 0:bbf6cf0eab95 | 26 | memset(ram, 0, size); |
bw | 0:bbf6cf0eab95 | 27 | buffer->head = buffer->tail = buffer->base; |
bw | 0:bbf6cf0eab95 | 28 | } |
bw | 0:bbf6cf0eab95 | 29 | return buffer; |
bw | 0:bbf6cf0eab95 | 30 | } |
bw | 0:bbf6cf0eab95 | 31 | |
bw | 0:bbf6cf0eab95 | 32 | /* |
bw | 0:bbf6cf0eab95 | 33 | * Read a single sample from the buffer. |
bw | 0:bbf6cf0eab95 | 34 | * @return True if successful (no underflow). |
bw | 0:bbf6cf0eab95 | 35 | */ |
bw | 0:bbf6cf0eab95 | 36 | bool Buffer_Read(buffer_t *buffer, int16_t *pDataOut) |
bw | 0:bbf6cf0eab95 | 37 | { |
bw | 0:bbf6cf0eab95 | 38 | if (buffer->head == buffer->tail) |
bw | 0:bbf6cf0eab95 | 39 | return false; |
bw | 0:bbf6cf0eab95 | 40 | |
bw | 0:bbf6cf0eab95 | 41 | *pDataOut = *buffer->tail; |
bw | 0:bbf6cf0eab95 | 42 | |
bw | 0:bbf6cf0eab95 | 43 | if (++buffer->tail >= buffer->base + buffer->len) { |
bw | 0:bbf6cf0eab95 | 44 | buffer->tail = buffer->base; |
bw | 0:bbf6cf0eab95 | 45 | } |
bw | 0:bbf6cf0eab95 | 46 | |
bw | 0:bbf6cf0eab95 | 47 | return true; |
bw | 0:bbf6cf0eab95 | 48 | } |
bw | 0:bbf6cf0eab95 | 49 | |
bw | 0:bbf6cf0eab95 | 50 | /* |
bw | 0:bbf6cf0eab95 | 51 | * Write a single sample to the buffer. |
bw | 0:bbf6cf0eab95 | 52 | */ |
bw | 0:bbf6cf0eab95 | 53 | void Buffer_Write(buffer_t *buffer, int16_t dataIn) |
bw | 0:bbf6cf0eab95 | 54 | { |
bw | 0:bbf6cf0eab95 | 55 | if (Buffer_GetLevel(buffer) >= buffer->len - 1) |
bw | 0:bbf6cf0eab95 | 56 | return; |
bw | 0:bbf6cf0eab95 | 57 | |
bw | 0:bbf6cf0eab95 | 58 | *buffer->head = dataIn; |
bw | 0:bbf6cf0eab95 | 59 | |
bw | 0:bbf6cf0eab95 | 60 | if (++buffer->head >= buffer->base + buffer->len) |
bw | 0:bbf6cf0eab95 | 61 | buffer->head = buffer->base; |
bw | 0:bbf6cf0eab95 | 62 | } |
bw | 0:bbf6cf0eab95 | 63 | |
bw | 0:bbf6cf0eab95 | 64 | /* |
bw | 0:bbf6cf0eab95 | 65 | * Write a block of data to the buffer. |
bw | 0:bbf6cf0eab95 | 66 | */ |
bw | 0:bbf6cf0eab95 | 67 | void Buffer_WriteBlock(buffer_t *buffer, const int16_t *pDataIn, uint32_t length) |
bw | 0:bbf6cf0eab95 | 68 | { |
bw | 0:bbf6cf0eab95 | 69 | int i; |
bw | 0:bbf6cf0eab95 | 70 | for (i = 0; i < length; i++) { |
bw | 0:bbf6cf0eab95 | 71 | Buffer_Write(buffer, pDataIn[i]); |
bw | 0:bbf6cf0eab95 | 72 | } |
bw | 0:bbf6cf0eab95 | 73 | } |
bw | 0:bbf6cf0eab95 | 74 | |
bw | 0:bbf6cf0eab95 | 75 | /* |
bw | 0:bbf6cf0eab95 | 76 | * Get buffer level |
bw | 0:bbf6cf0eab95 | 77 | */ |
bw | 0:bbf6cf0eab95 | 78 | int32_t Buffer_GetLevel(buffer_t *buffer) |
bw | 0:bbf6cf0eab95 | 79 | { |
bw | 0:bbf6cf0eab95 | 80 | __disable_irq(); /* Begin critical section */ |
bw | 0:bbf6cf0eab95 | 81 | |
bw | 0:bbf6cf0eab95 | 82 | int32_t level = (buffer->head >= buffer->tail) ? |
bw | 0:bbf6cf0eab95 | 83 | buffer->head - buffer->tail : |
bw | 0:bbf6cf0eab95 | 84 | buffer->len + buffer->head - buffer->tail; |
bw | 0:bbf6cf0eab95 | 85 | |
bw | 0:bbf6cf0eab95 | 86 | __enable_irq(); /* End critical section */ |
bw | 0:bbf6cf0eab95 | 87 | |
bw | 0:bbf6cf0eab95 | 88 | return level; |
bw | 0:bbf6cf0eab95 | 89 | } |