mbed audio sampler
Objective
The objective of this project is to implement professional features of a recording studio into a portable device while maintaining a simplified user experience. The initial features of this prototype include sound playback, sound recording and sound looping with additonal features to follow.
Features
initial
- Playback of wav formatted sounds
- Adjustable playback volume
- Analog sound recording
- Analog sound conversion to wav format
- Sound looping
future
- MP3 playback and conversion
- Sound mixing on multiple channels
- 60Hz bandstop DSP hum eliminator
- Multiple band graphic equalizer
advanced
- Song composition
- Instrument tansposition
- Sound source seperation
note
In sound recording, 60Hz hum is due to alternating current of power line frequency.
Requirements
- 16 byte sampling/playback rate of 44.1KHz, hard constraint.
- Disk file read\write rate of 16 bytes at 44.1KHz, hard constraint.
- 8, 16, 24 and 32 byte sampling/playback resolution, hard constraint.
- Device ready within 1 second of on, soft constraint.
- File open within 1 second, soft constraint.
- 8 minute maximum recording time, hard constraint.
note
Human hearing range is 20Hz to 20KHz. The Nyquist-Shannon sampling theorem requires sound sampling to occur at greater than twice the reproduced frequency. 44.1KHz is CD quality.
System Diagram
Wiring for 1.65V offset
The mbed requires analog input voltage in the range of 0 to 3.3V. Typical output line votage of a device with headphone line out is 0.7V RMS with negative voltage allowed. This circuit applies a 1.65V DC offset to the incoming signal. [Audio Signal Processing and Rapid Prototyping with the ARM mbed, Toulson, 2010]
Completed offset cable
Operation
play/loop/record
- Analog in to acquire sound
- Analog out to play sound
- Ticker interrupt to record sound
- Ticker interrupt to play sound
- LED blinking to indicate playback and sampling enabled
- USB host to store wav files
user interface
- LCD output to show menu options
- Ticker interrupt to display selected option and playback/record information
- Left joystick button interrupt to get preceding menu option
- Right joystick button interrupt to get next menu option
- Top joystick button interrupt to increase option value
- Bottom joystick button interrupt decrease option value
- Middle joystick button interrupt to enable, select, start or stop option
Implementation
wave_player library
The mbed wave_player library [Steve Ravet, 2011] is imported into the project to interpret the wav file header and format and to successfully play wav files. Although it does not have a record function, it is selected because it well documented. A Ticker function is used to write to the DAC at the rate specified by the wav file header. A circular buffer is used to pass the data from the wav file to the DAC.
SimpleWaveRecorderPlayer record
The record function from SimpleWaveRecorderPlayer, [Nakamura, 2012] is added to the wave_player library in this project to provide this critical feature. A Ticker function is used to read data from the ADC at a fixed interval. A circular buffer is used here to pass data from the ADC to the new wav file.
loop enable
A looping feature is developed and added to the wave_player library. The essential looping option logic is shown in the following code snippet.
// get offset position from beginning of file where samples begin offset = ftell(wavefile); if (offset<=0) { printf("Oops -- file position error\n"); exit(1); } // initialize end position values slice_start=0; loop_start=0; slice_end=num_slices; loop_end=num_slices; while(!stop) { // if looping enabled, determine beginning and end position of the // data to read from file if (loop_enabled) { // do not set loop end greater than number of samples in file if (loop_end>num_slices) { loop_end=num_slices; } slice_start=loop_start; slice_end=loop_end-loop_start; } // move to beginning of loop in file chk=fseek(wavefile,offset+slice_start,SEEK_SET); if (chk) { printf("Oops -- file seek error\n"); exit(1); } for (slice=0;slice<slice_end;slice+=1) { // read sample from wav file fread(slice_buf,wav_format.block_align,1,wavefile); if (feof(wavefile)) { printf("Oops -- not enough slices in the wave file\n"); exit(1); } // continue to format data and write to circular buffer for DAC to read // at sample rate
Test Cases
- Use timer to verify 16 byte sampling/playback rate of 44.1KHz. In progress.
- Use timer to verify disk file read/write rate of 16 bytes at 44.1KHz. Fail.
- Record and play wav file. Pass.
- Iterate through all menu options described in operation section above. In progress.
- Verify playback volume control. Pass.
- Verify LED blinking during recording/playback. Pass.
Average measured duration: 48.1 us. Duration required for 44.1KHz: 22.7 us.
Audio Samples
short loop
Recorded at 22.05KHz. Set loop start time to 0.382 and end time to 4.401 seconds for looping demo.
long recording
Recorded at 22.05KHz with cracks and pops.
video of sound looping
Recorded at 22.05KHz. 6 second sample. Start time: 0.382 seconds. End time: 4.401 seconds.
Issues
- Beta USB Host library in beta with last commit 17 days ago
- The USB Host library was not compatible with the rtos library
- Performance is better without rtos libray as cracks and pops are added to sound when enabled
- Overall sound quality can be improved
- File write operations do not keep up with sample rate
- Will switch from circular buffer to linked list to attempt to repair audio quality
- A quality soldered cable would reduce noise in recording
3 comments on mbed audio sampler:
Please log in to post comments.
Hello, how did you code the mbed to sample at the frequency you wanted? (I assume you sampled at 44.1kHz)