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. */
Revision 0:bbf6cf0eab95, committed 2014-03-27
- Comitter:
- bw
- Date:
- Thu Mar 27 21:27:04 2014 +0000
- Child:
- 1:d2250586c044
- Commit message:
- Initial.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/C12832_lcd.lib Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/dreschpe/code/C12832_lcd/#8f86576007d6
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MMA7660.lib Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/Sissors/code/MMA7660/#a8e20db7901e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice.lib Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/USBDevice/#8133879e4fb4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audio.cpp Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,116 @@ +/******************************************************************************* + * 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; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audio.h Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,19 @@ +/******************************************************************************* + * Manages all aspects of audio playback with sound effects. + * Bryan Wade + * 27 MAR 2014 + ******************************************************************************/ +#ifndef AUDIO_H +#define AUDIO_H + +#include <stdint.h> +#include <stdlib.h> + +// Initialize the module. +void Audio_Initialize(void); + +// Periodically call to stop/start playback according to the +// current buffer level. Return level for diagnostics. +int32_t Audio_CheckPlaybackBufferLevel(void); + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/buffer.cpp Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,89 @@ +/******************************************************************************* + * Implements FIFO buffer for glitch-free audio playback. + * Bryan Wade + * 27 MAR 2014 + ******************************************************************************/ +#include "buffer.h" +#include "string.h" + +struct buffer_t { // Implementation of opaque type. + int16_t *base; + int16_t *head; + int16_t *tail; + size_t len; +}; + +/* + * Create a buffer object given a ptr and size of available RAM. + * @return Ptr to the new buffer. + */ +buffer_t *Buffer_Create(void *ram, size_t size) +{ + buffer_t *buffer = (buffer_t *)malloc(sizeof(buffer_t)); + if (buffer) { + buffer->base = (int16_t *)ram; + buffer->len = size / sizeof(int16_t); + memset(ram, 0, size); + buffer->head = buffer->tail = buffer->base; + } + return buffer; +} + +/* + * Read a single sample from the buffer. + * @return True if successful (no underflow). + */ +bool Buffer_Read(buffer_t *buffer, int16_t *pDataOut) +{ + if (buffer->head == buffer->tail) + return false; + + *pDataOut = *buffer->tail; + + if (++buffer->tail >= buffer->base + buffer->len) { + buffer->tail = buffer->base; + } + + return true; +} + +/* + * Write a single sample to the buffer. + */ +void Buffer_Write(buffer_t *buffer, int16_t dataIn) +{ + if (Buffer_GetLevel(buffer) >= buffer->len - 1) + return; + + *buffer->head = dataIn; + + if (++buffer->head >= buffer->base + buffer->len) + buffer->head = buffer->base; +} + +/* + * Write a block of data to the buffer. + */ +void Buffer_WriteBlock(buffer_t *buffer, const int16_t *pDataIn, uint32_t length) +{ + int i; + for (i = 0; i < length; i++) { + Buffer_Write(buffer, pDataIn[i]); + } +} + +/* + * Get buffer level + */ +int32_t Buffer_GetLevel(buffer_t *buffer) +{ + __disable_irq(); /* Begin critical section */ + + int32_t level = (buffer->head >= buffer->tail) ? + buffer->head - buffer->tail : + buffer->len + buffer->head - buffer->tail; + + __enable_irq(); /* End critical section */ + + return level; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/buffer.h Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,29 @@ +/******************************************************************************* + * Implements FIFO buffer for glitch-free audio playback. + * Bryan Wade + * 27 MAR 2014 + ******************************************************************************/ +#ifndef BUFFER_H +#define BUFFER_H + +#include <stdint.h> +#include <stdlib.h> + +typedef struct buffer_t buffer_t; // Opaque type declaration. + +// Get a ptr to a new buffer. +buffer_t *Buffer_Create(void *ram, size_t size); + +// Read one sample from buffer. +bool Buffer_Read(buffer_t *buffer, int16_t *pDataOut); + +// Write one sample to buffer. +void Buffer_Write(buffer_t *buffer, int16_t DataIn); + +// Write a block of data to buffer. +void Buffer_WriteBlock(buffer_t *buffer, const int16_t *pDataIn, uint32_t length); + +// Get the current number of samples buffered. +int32_t Buffer_GetLevel(buffer_t *buffer); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/delay.cpp Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,58 @@ +/******************************************************************************* + * Implements delay lines for audio samples. + * Bryan Wade + * 27 MAR 2014 + ******************************************************************************/ +#include "delay.h" +#include "string.h" + +struct delay_t { // Implementation of opaque type. + int16_t *base; + int16_t *head; + size_t len; +}; + +/* + * Create a delay object given a ptr and size of available RAM. + * This is only allocating memory for the metadata. The location of + * the buffer memory is passed in. + * @return Ptr to the new delay. + */ +delay_t *Delay_Create(void) +{ + return (delay_t *)malloc(sizeof(delay_t)); +} + +/* + * Configure delay buffer location and size. + * @return True if successful. + */ +bool Delay_Configure(delay_t *delay, void *ram, size_t size) +{ + if (delay) { + delay->base = delay->head = (int16_t *)ram; + delay->len = size / sizeof(int16_t); + memset(ram, 0, size); + return true; + } + + return false; +} + +/* + * Push a new sample with feedback into the delay while simulateously retieving the output sample. + * @return Output data. + */ +int16_t Delay_WriteWithFeedback(delay_t *delay, int16_t dataIn, uint16_t gain) +{ + int16_t dataOut = *delay->head; + + // Feedback gain is fixed-point Q16 format. + *delay->head = dataIn + ((gain * dataOut ) >> 16); + + if (++delay->head >= delay->base + delay->len) + delay->head = delay->base; + + return dataOut; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/delay.h Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,23 @@ +/******************************************************************************* + * Implements delay lines for audio samples. + * Bryan Wade + * 27 MAR 2014 + ******************************************************************************/ +#ifndef DELAY_H +#define DELAY_H + +#include <stdint.h> +#include <stdlib.h> + +typedef struct delay_t delay_t; // Opaque type declaration. + +// Get a ptr to a new delay struct +delay_t *Delay_Create(void); + +// Configure the delay length and ram location +bool Delay_Configure(delay_t *delay, void *ram, size_t size); + +// Write one sample with feedback to the delay and get one sample out. +int16_t Delay_WriteWithFeedback(delay_t *delay, int16_t dataIn, uint16_t gain); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/effects.cpp Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,147 @@ +/******************************************************************************* + * Module processes 16-bit audio samples to produces delay-based sound effects. + * Bryan Wade + * 27 MAR 2014 + ******************************************************************************/ +#include "mbed.h" +#include "effects.h" +#include "delay.h" + +// Delay based effects require significant RAM, so we must +// scavange two banks of RAM that mbed has reserved for ethernet: +// AHBSRAM0: 0x2007C000 - 0x2007FFFF (16KB) +// AHBSRAM1: 0x20080000 - 0x20083FFF (16KB) +// To keep the linker happy we allocate the RAM with a 16KB array in each bank, +// but since they are contiguous, we can treat them as one 32KB block. +static const int RAM_BANK0_SIZE = 16 * 1024; +static const int RAM_BANK1_SIZE = 16 * 1024; +__attribute((section("AHBSRAM0"),aligned)) char ramBank0[RAM_BANK0_SIZE]; +__attribute((section("AHBSRAM1"),aligned)) char ramBank1[RAM_BANK1_SIZE]; + +static effect_mode_t effectMode; +static uint16_t effectGain; +static const int MAX_DELAYS = 7; +static delay_t *delay[MAX_DELAYS]; + +static void initializeEcho(void); +static void initializeReverb(void); + +/* + * Initialize module. + */ +void Effects_Initialize(void) +{ + effectGain = 0; + + // Create all the delay objects. They will be initialized and + // re-initialized as needed each time the mode changes, but the + // total number of delay objects is fixed. + for (int i = 0; i < MAX_DELAYS; i++) + { + delay[i] = Delay_Create(); + } + Effects_SetMode(EFFECT_STRAIGHT); +} + +/* + * Apply current effect to sample stream. + * @return Processed sample. + */ +int16_t Effects_ProcessSample(int16_t dataIn) +{ + int16_t dataOut; + + switch (effectMode) + { + case EFFECT_ECHO: + dataOut = Delay_WriteWithFeedback(delay[0], dataIn, effectGain); + break; + + case EFFECT_REVERB: + dataOut = (Delay_WriteWithFeedback(delay[0], dataIn, effectGain) + + Delay_WriteWithFeedback(delay[1], dataIn, effectGain) + + Delay_WriteWithFeedback(delay[2], dataIn, effectGain) + + Delay_WriteWithFeedback(delay[3], dataIn, effectGain) + + Delay_WriteWithFeedback(delay[4], dataIn, effectGain) + + Delay_WriteWithFeedback(delay[5], dataIn, effectGain) + + Delay_WriteWithFeedback(delay[6], dataIn, effectGain)) / 7; + break; + + case EFFECT_STRAIGHT: + default: + dataOut = dataIn; + } + + return dataOut; +} + +/* + * Getter/setters. + */ +void Effects_SetMode(effect_mode_t mode) +{ + // Ignore if already in desired mode. + if (effectMode == mode) return; + + // Effects_Process() will continue to be called by an ISR while + // changing modes, so first change to straight mode since this + // can safely play at any time. Then change to the desired mode + // once it is fully configured. + effectMode = EFFECT_STRAIGHT; + + switch (mode) + { + case EFFECT_ECHO: + initializeEcho(); + effectMode = mode; + break; + + case EFFECT_REVERB: + initializeReverb(); + effectMode = mode; + break; + + case EFFECT_STRAIGHT: + default: + effectMode = mode; + } +} + +void Effects_SetGain(uint16_t gain) { effectGain = gain; } + +/* + * Configure one large delay for echo. + */ +void initializeEcho(void) +{ + // The maximum echo delay is 16K samples since each sample is 2 bytes + // and we have 32KB available. + static const int ECHO_DELAY_SAMPLES = 12000; + Delay_Configure(delay[0], (void *)ramBank0, ECHO_DELAY_SAMPLES * sizeof(int16_t)); +} + +/* + * Configure all delays for reverb. + */ +void initializeReverb(void) +{ + // Delay lengths are chosen as a base length times prime numbers to prevent + // interfernce patterns. Total size of all delay lines must fit within 32KB. + static const int REVERB_BASE_DELAY_SAMPLES = 256; + static const int PRIMES[MAX_DELAYS] = {2, 3, 5, 7, 11, 13, 17}; + + char *ram = ramBank0; // Location for first buffer. + + for (int i = 0; i < MAX_DELAYS; i++) + { + // Configure each delay with proper buffer size and location + int size = PRIMES[i] * REVERB_BASE_DELAY_SAMPLES * sizeof(int16_t); + Delay_Configure(delay[i], (void *)ram, size); + + // The next buffer location immediately follows this one. + ram += size; + } +} + + + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/effects.h Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,32 @@ +/******************************************************************************* + * Module processes 16-bit audio samples to produces delay-based sound effects. + * Bryan Wade + * 27 MAR 2014 + ******************************************************************************/ +#ifndef EFFECTS_H +#define EFFECTS_H + +#include <stdint.h> + +// Practical gain limit for decent sound. +#define MAX_EFFECT_GAIN (58982) + +// Available sound effect modes +typedef enum effect_mode_t { + EFFECT_STRAIGHT, + EFFECT_ECHO, + EFFECT_REVERB +} effect_mode_t; + + +// Initialize module. +void Effects_Initialize(void); + +// Process one audio sample. +int16_t Effects_ProcessSample(int16_t dataIn); + +void Effects_SetMode(effect_mode_t mode); + +void Effects_SetGain(uint16_t gain); + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,88 @@ +/******************************************************************************* + * Project: USB Sound Effects. + * + * 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, + * tilting the mbed alters the effects. + * + * 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. + * + * For better audio quality, packets are buffered before playbeck. Playback is + * halted when the buffer drops below two packets and resumes when it is greater + * than four packets. This creates a lag of a few milliseconds, which is not + * detectable by a listener using straight playback mode. + * + * The echo effect produces echos with a delay of about 250 milliseconds. Tilting + * the mbed alters the persistence of echo. + * + * The reverb effect utilizes multiple delay lines of length varying from + * about 25 to 200 milliseconds. Again, tilting the mbed alters the + * persistence. + * + * Implemenation Notes: + * Audio playback is implement with an mbed ticker, and it is critical that this interrupt + * is not delayed to acheive decent audio quality. USB audio packet handling also uses + * interrupts, but the priority is set lower to ensure proper playback. The USBAudio class + * was modified to use a callback to transfer the received packet from the packet buffer to + * the larger playback buffer. The user interface is handled entirely in the user-context + * since it has only soft timing requirements. + * + * Future work: + * 1. Clocks within the host computer and mbed will differ slightly, so the + * average sample rate from the computer will not exactly match the average mbed + * playback rate. Over time the playback buffer level with creep until it becomes + * totaly empty or full. The current implementation addresses this by simply + * increasing the buffer size and selecting a sample rate that the mbed + * can replicate most accurately (mulitple of 1 us to use mbed Ticker). A better + * solution may be to slightly alter the playback rate in response to the buffer level. + * For example use 20us rate when the buffer level is high and 19us when the buffer + * level is low. Of course this would distort the playback frequecy by 5%, so it would + * be even better to make a custom timer interrupt with better resolution than the + * mbed ticker. + * + * 2. It would be interesting to add stereo audio, but the mbed-application-board + * audio jack is mono so this would require hardware customization. + * + * Bryan Wade + * 27 MAR 2014 + ******************************************************************************/ + +#include "mbed.h" +#include "audio.h" +#include "effects.h" +#include "user_interface.h" + +int main() +{ + UI_Initialize(); + Audio_Initialize(); // Start audio playback. + + while (true) + { + // + int32_t level = Audio_CheckPlaybackBufferLevel(); + UI_Update(level); + + Effects_SetGain(UI_GetEffectGain()); + Effects_SetMode(UI_GetEffectMode()); + + // 50 milliseconds provides good UI responsivness + wait(.05); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/3d0ef94e36ec \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/user_interface.cpp Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,122 @@ +/******************************************************************************* + * Mangages LCD display, joystick and accelerometer for user interface. + * Bryan Wade + * 27 MAR 2014 + ******************************************************************************/ +#include "mbed.h" +#include "C12832_lcd.h" +#include "MMA7660.h" +#include "user_interface.h" +#include "effects.h" + +C12832_LCD lcd; +MMA7660 accel(p28, p27, true); +BusIn joystick(p15, p12, p13, p16); +AnalogIn pot(p19); + +static const int STICK_IDLE = 0; +static const int STICK_UP = 1; +static const int STICK_DOWN = 2; +static const int STICK_LEFT = 4; +static const int STICK_RIGHT = 8; + +static uint8_t stickPrevious; +static effect_mode_t selectedMode; +static char *selectedModeName; +static uint16_t effectGain; + +/* + * Update the display with mode, gain and buffer level. + */ +void updateDisplay(int32_t level) +{ + lcd.locate(0,0); + lcd.printf("Effect: %s ", selectedModeName); + + lcd.locate(0,10); + lcd.printf("Intensity: %d ", effectGain / (MAX_EFFECT_GAIN / 100)); + + lcd.locate(0,20); + lcd.printf("Buffer: %d ", level); +} + +/* + * Get effects mode selected by joystick. + */ +void serviceJoystick(void) +{ + uint8_t stick = joystick; + + if (stick != stickPrevious) { + stickPrevious = stick; + + switch (stick) + { + case STICK_UP: + selectedMode = EFFECT_ECHO; + selectedModeName = "Echo"; + break; + + case STICK_DOWN: + selectedMode = EFFECT_REVERB; + selectedModeName = "Reverb"; + break; + + case STICK_LEFT: + case STICK_RIGHT: + selectedMode = EFFECT_STRAIGHT; + selectedModeName = "Straight"; + break; + } + } +} + +/* + * Get effects gain from accelerometer tilt. + */ + void serviceAccel(void) + { + // Tilt sensitivity selected to produce max effect gain + // at about 80 deg tilt. + static const int32_t TILT_SENSITIVITY = 2750; + int a[3]; + accel.readData(a); + //Convert x-axis raw accelerometer data to the effect gain. + int32_t x = a[0] * TILT_SENSITIVITY; + if (x < 0) x = -x; + if (x > MAX_EFFECT_GAIN) x = MAX_EFFECT_GAIN; + effectGain = (uint16_t)x; + } + +/* + * Initialize the joystick and display. + */ +void UI_Initialize(void) +{ + lcd.cls(); + stickPrevious = STICK_IDLE; + selectedMode = EFFECT_STRAIGHT; + selectedModeName = "Straight"; + effectGain = 0; + // Set the accelerometer to sample slightly + // faster than we poll the user interface. + accel.setSampleRate(32); +} + +/* + * Updates display, joystick and accelerometer + */ +void UI_Update(int32_t bufferLevel) +{ + serviceJoystick(); + serviceAccel(); + updateDisplay(bufferLevel); +} + + +effect_mode_t UI_GetEffectMode(void) { return selectedMode; } + +uint16_t UI_GetEffectGain(void) { return effectGain; } + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/user_interface.h Thu Mar 27 21:27:04 2014 +0000 @@ -0,0 +1,23 @@ +/******************************************************************************* + * Mangages LCD display, joystick and accelerometer for user interface. + * Bryan Wade + * 27 MAR 2014 + ******************************************************************************/ +#ifndef USER_INTERFACE_H +#define USER_INTERFACE_H + +#include "effects.h" + +// Initialize module. +void UI_Initialize(void); + +// Update the display and poll all input devices. +void UI_Update(int32_t bufferLevel); + +// Get the effect mode selected by joystick. +effect_mode_t UI_GetEffectMode(void); + +// Get the effect gain selected by accelerometer tilt. +uint16_t UI_GetEffectGain(void); + +#endif \ No newline at end of file