Arduino Digital Audio Recorder Mk. II

A couple of years ago, I developed a simple digital audio recorder(DAR) for the Arduino Uno just as a bit of a side project for our Arduino Masterclass series, but it’s turned out to be one of the most popular projects on the APC website (we still get comments on it).

So today, we’re introducing the Mk. II, based around the larger Arduino Mega2560. It still only captures single-channel 8-bit audio, but it’ll handle sample rates up to 48kHz and now includes automatic filename incrementing.

What’s new

Filenames are automatically incremented for each recording.

Filenames are automatically incremented for each recording.

A couple of requests from readers wanting a version that would work with the Arduino Mega2560 prompted this update, but it was already on the to-do list.

The Mega is quite a bit bigger than the Uno, but it has a couple of useful advantages. Apart from having four times the number of digital I/O pins, the Mega also has four times the RAM — 8KB to the Uno’s 2KB. It’s not much but that makes a big difference when capturing audio.

The Mk. I also only recorded to the filename ‘rec00000.wav’ — any new recording simply wiped the old one. This new Mk. II automatically increments the filename digits, starting with ‘rec0.wav’, ‘rec1.wav’, ‘rec2.wav’, up to ‘rec9999.wav’.

In other words, it now keeps everything you record, rather than wiping the one file each time.

Digital audio theory

The circuit diagram for our version 2.0 digital audio recorder.

The circuit diagram for our version 2.0 digital audio recorder.

We can’t do justice to digital audio theory in a single feature, so make sure you read the original stories on our website — Part 1 and Part 2 for the gory background detail.

Read it yet? You really should… Okay, let’s get cracking on the new version.

Getting the audio into the Arduino is the same as before — we’re using analog I/O pin A5 as the audio input into the Arduino’s analog-to-digital converter (ADC).

We’re also using the same divider or ‘prescaler’ trick, boosting the ADC clock from its default 125kHz up to 4MHz — that cranks up the sample rate from a sleepy 9.6kHz up to a possible 307kHz.

Now, obviously CD-audio sample rate is only 44.1kHz, but the extra speed gives us valuable time to do everything else we need.

Use this overlay diagram to build your own.

Use this overlay diagram to build your own.

To create recordings with more common sample rates, we code one of the Mega’s internal counters or ‘timers’ to trigger an interrupt at intervals the inverse of the desired sample rate, which you set in the source code prior to flashing to the Mega.

For example, for a 44,100Hz sample rate, we set the timer to fire every 1/44,100 seconds or approximately 22.7 microseconds — and at each interrupt, we get one audio sample.

SPI changes

This MicroSD card reader can read cards up to 32GB on an Arduino.

This MicroSD card reader can read cards up to 32GB on an Arduino.

We store the samples with a MicroSD card reader connected via the Mega’s SPI (Serial Peripheral Interface) port.

Like the Uno, the Mega has two SPI pin sets, but here, the MOSI pin is now 51, MISO is 50 and SCK is 52.

We use the excellent SdFat library to enable the Mega to write samples to a FAT32 formatted microSD card — but that’s after we’ve written the WAV header, which tells every media player how the file works.

Ring buffer

Every digital audio recorder uses some form of ring buffer.

Every digital audio recorder uses some form of ring buffer.

However, the really tricky bit is interleaving the audio sampling with the file writing, and we do that with a technique called a ‘ring buffer’.

The idea behind the ring buffer is dividing a slab of memory into equal-sized buffers, so that, while we’re recording audio samples into one buffer, we’re writing the previous buffer to the microSD card.

The Mk. I had just 1KB of RAM divided into eight buffers, each 128 bytes, and as each one was filled, it would be written to storage while samples were captured into the next.

However, 128 bytes at a sample rate of 44.1kHz takes just 2.9 milliseconds to fill up — the whole 1KB buffer ring can only hold 23.2 milliseconds of audio at a 44.1kHz sample rate.

The Arduino Mega2560 has four times the RAM of the Arduino Uno.

The Arduino Mega2560 has four times the RAM of the Arduino Uno.

For the most part, the microSD card and SPI port operate fast enough to ensure a smooth flow of audio samples to the card, but every now and then, the microSD card will delay the write, causing a backlog.

If that backlog extends beyond the ring buffer capacity, you lose samples and get skips in the audio.

The two simple ways to fix that are to capture audio samples at a slower rate, or get a bigger ring buffer ­— but that needs RAM, which is why we’ve gone for the Mega with its 8KB of RAM.

We still need to handle other code variables, so as before, we only assign half the RAM (4KB) to the ring buffer, but with a ring of four buffers, instead of eight.

The result is instead of 128 bytes per buffer, we now have 1024 bytes — it’s still not ideal, but is certainly better.

By having the audio sample code triggered precisely by a timed interrupt, the remaining time between completion of each sample and the next trigger is used to write data to the card.

So in other words, audio sampling takes precedence and writing data to the card happens around that.

Line-level audio only

most common request we’ve had has been readers wanting to plug a microphone into the input and record it.

The problem is that microphones deliver an output signal of less than 10mV RMS (0.01 volts), whereas the Atmel chip’s analog input expects a signal voltage 100 times that.

The answer is a microphone preamplifier, which most microcontrollers — and all of the Arduinos — don’t have.

You can make one externally, but it takes more than we have space for here.

Audio quality

This new recorder can handle any type of line-level audio input, but 8-bit audio also comes with a low 48dB dynamic range, which means the background noise will be noticeable on quieter passages of music.

CD-quality, it’s not. But here’s the thing — an Arduino DAR may lack sample bit-depth and overall speed, but we’re using exactly the same techniques the real DARs use.

So as a learning exercise, you can’t go wrong.

  • Sam Barker

    The links for Part1 and Part2 give “Page Not Found” errors.

  • theeraphon boonwan

    Use the original source code ?
    Thank You

  • Rishabh Sawant

    can you provide the source code for this project?
    thank you!

  • Elyssa

    I have a question about this. I am not tech savvy so I apologize if I use terms incorrectly or just don’t make sense. I want to record audio to an arduino board and either download the data to an SD card directly or transmit the recording via bluetooth or something to a receiver. The audio I want to record is heart beat, in the 100-400 Hz range. I don’t want the sound of the heart beat, rather the information that can be analyzed in beats per minute. Does this make storing the audio more or less complicated? I am looking at recording with an electret microphone by adafruit, some of which have amplifiers built in. Now to make this more complicated, I am putting the sensing equipment in an artificial egg put into a nest so I can get heart rate of an incubating bird. This is where size restrictions come into play. Also power requirements as I need it to last a minimum of 15 days. Do you think I can follow this design as a template or does anyone have some suggestions for me?
    Thanks

    • Elyssa, I’m assuming this is for university research? It can be done but not using standard off-the-shelf Arduino boards. First, all of these boards include LEDs, which consume as much if not more power than the microcontroller chips that make these boards work. Lose these LEDs and it might work.
      Second, 15 days is 360 hours. Given the size of a typical egg, you’ll be limited in the battery capacity you can physically fit into that space. I’d hazard a guess at 360mAh (milliamp-hours) at best. That means the electronics – all of the electronics, the microcontroller board, the electret mic, the SD storage – must consume no more than 1mA of electric current per hour on average, otherwise you’ll run out of battery juice before your 15 days. All of the standard Arduino boards consume at least 20mA of current, requiring at least a 7200mAh smartphone battery pack to get lose to lasting 360 hours.
      If you are working at a university, I’d contact the School of Electrical Engineering (if your uni has one) and present the problem to them as it’ll need a custom solution. Atmel’s SAMD21 is a 32-bit ARM Cortex M0 microcontroller chip that can last 360 hours on a couple of coin batteries, but you’ll need a custom build to meet all of your requirements. Off-the-shelf Arduino boards won’t work for this.
      Thanks,
      Darren.

      • Elyssa

        Hi Darren,
        Thank you for your advice. Yes I am a graduate student and this is for my master’s project. I was hoping I would be able to assemble something myself but I do believe I will need to have the design customized to meet all of my needs. Talking to the electric engineering department is my next step. I really appreciate your response and breakdown of power requirements. I am learning so much as I develop this project but the learning curve is steep. Good to know that I need more than off the shelf Arduino boards.

  • Viren Velacheri

    Can you write a different article about making the digital recorder with the Arduino Zero please?