mbed audio sampler

/media/uploads/subtask/mbed_sampler_connected.jpg

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

/media/uploads/subtask/sampler_system_diagram_2.jpg

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. /media/uploads/subtask/sampler_wiring_diagram_2.jpg [Audio Signal Processing and Rapid Prototyping with the ARM mbed, Toulson, 2010]

Completed offset cable

/media/uploads/subtask/mbed_dc_offset_cable_2.jpg

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.

/media/uploads/subtask/circular_buffer_3.png LuaVIEW

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

  1. Use timer to verify 16 byte sampling/playback rate of 44.1KHz. In progress.
  2. Use timer to verify disk file read/write rate of 16 bytes at 44.1KHz. Fail.
  3. Record and play wav file. Pass.
  4. Iterate through all menu options described in operation section above. In progress.
  5. Verify playback volume control. Pass.
  6. Verify LED blinking during recording/playback. Pass.

/media/uploads/subtask/time_duration_frequency_2.png 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:

06 Feb 2017

Hello, how did you code the mbed to sample at the frequency you wanted? (I assume you sampled at 44.1kHz)

08 Mar 2017

Muyiwa, just saw your comment. I sampled at 22.05kHz. 44.1kHz sounded terrible.

Ticker play_record_tick; unsigned samp_int = 1000000 / 22050; play_record_tick.attach_us(this,&wave_player::dac_in, samp_int);

13 Mar 2017

Hi, where I can see the code? Thanks

Please log in to post comments.