Wednesday, May 15, 2013

On Formatting Audio Samples to Use with the Arduino IDE

It is possible to play back audio samples using non-variable arrays in the Arduino IDE. But how is it possible to convert an audio file for use with the Arduino IDE as a non-variable array in the first place? This article will show how!

A Word About Audio Length and Quality
One thing to keep in mind when using Arduino to play back uncompressed samples (using the onboard memory only) is that there are severe limitations in terms of sample length and quality.

For starters, sample data must be 8 bits and mono (single channel) to maximise the available space. Keep in mind that there is only space for approx 25000 sample data points (our program might take up some room as well!).

Looking at this logically, if the audio has a sample rate of 22050 Hz (which is half of CD quality), then this limits the Arduino to just over 1 second of audio. This sampling rate can be halved to 11025 Hz for 2 seconds.

Of course, these lengths are so very short, but they should not be dismissed entirely - for example, check out a previous post about writing some music tracking software for the Arduino IDE which includes simultaneous sample and synthesis playback of sequencer material.

Preparing the Sound
In general, although any sounds can be converted into a suitable 8 bit format, it is worth noting that several recommendations are relevant.

• Sounds should be free of reverb tails or delays, as this might not translate well to 8 bits.
• Sounds should be compressed and maximized as much as possible.

For instance, I use the following two settings for Multiband Dynamics and and Voxengo Elephant in Ableton Live:

• Be aware of the exact length of a sound, in samples. Keep in mind that at CD quality, there are 44100 samples per second.
• Export your sound as an uncompressed WAV file, preferably 16-bits and 44.1KHz

Converting the Sound
The sound file needs to be converted from floating point values (-1. to 1.) format with a header to a header-less, uncompressed 8 bit (0 - 255) format without a header, where each value is separated by a comma and a space.

An easy way to do this is via this Max patch:

The patch will work with Max or Max Runtime. Max Runtime is free.

Using the patch is relatively straight forward. An example workflow is as follows:
1) Click on the read button and locate your WAV file

2) Set the samples field to the number of samples that you would like to read

3) Set the bits field to 8

4) Set the over field to how many samples you would like to read / skip. Setting this field to 1 will result in every sample being read. Setting this field to 2 means that every second sample will be read. Setting this field to 4 means that only 1 in 4 samples are read. This field - combined with the sample length field - set the total length and space that the samples will occupy.

5) Click on go

6) The index should count from 1 to the number of samples that you would like to read

7) A text box will appear with your samples. Select all samples in the text box and copy

You will notice that there are no commas separating the samples. They need to be added separately. To do this, create a new file in a text editing application and paste the sample data into it. Delete the very last space character at the very end of the file.

Then, do a find-and-replace-all and replace all instances of a space character (' ') with a space character preceded by a comma (', ').

Inserting the Sound into Arduino
Copy the data including the commas, and paste into Arduino.

To form a non-variable array within program space, add the following before the data:

prog_char sample_data[22050] PROGMEM = {

and add the following after the data:


Examples of Coding and Usage
An example for playing back audio data can be found at the end of this post.

Here is an Arduino-based drum machine that makes use of this.