IMG_0041 copy.jpg
Send sound into your Arduino.  This Instructable will show you how to prepare audio so that it can be sampled and processed by an Arduino to make sound responsive projects and audio effects.  (This article is a companion to another Instructable I've written about building an audio output circuit for an Arduino, find that here)

Some ideas that come to mind include:

beat detection- trigger lighting effects, build a set of turntables that beat match themselves, or make a robot that dances along with the music you play for it
amplitude detection- make a simple vu meter with LEDS
frequency analysis- you could make a project that reacts to different frequencies in different ways, recognizes certain melodies, turns audio into MIDI data, or translates incoming frequencies into square waves with the tone() library
digital effects boxes/digital signal processing- check out what I did with my vocal effects box (all processing done with Arduino), lots of possibilities here: pitch bending, distortion, sampling, delay, reverb, granular synthesis, mixing, and much more...  I've provided code in this Instructable that lets you sample at up to 38.5kHz.  Here is another instructable describing how to set up a simple audio out circuit with Arduino.
digital recorder- with the addition of an SD card of course (the Arduino has very limited memory by itself), this opens up the possibility of looping large samples and doing lots of other digital manipulations to pieces of stored audio  The circuits and code provided here are compatible with SD card shields that communicate via SPI.
graphical representations of sound- Arduino oscilloscope/visualizer

Feel free to use any of the info in this Instructable to put together an amazing project for the DIY Audio Contest!  We're giving away an HDTV, some DSLR cameras, and tons of other great stuff!  The contest closes Nov 26.

Parts list:
(x1) Microphone Radioshack 33-3038
(x1) TL072 Digikey 296-14997-5-ND or TL082 Digikey 296-1780-5-ND (TL081/TL071 are fine too)  I used a tl082 in my examples
(x2) 9V battery
(x2) 9V battery snap connector Radioshack 270-324
(x1) mono audio jack 1/4" Radioshack 274-340  or Radioshack 274-252 or 1/8" Radioshack 274-333 or Radioshack 274-251
(x1) LED Digikey C513A-WSN-CV0Y0151-ND
(x1) 10kOhm potentiometer linear Digikey 987-1301-ND
(x3) 100kOhm 1/4watt resistors Digikey CF14JT100KCT-ND
(x1) 10uF electrolytic capacitor Digikey P5134-ND
(x1) 47nF ceramic capacitor Digikey P4307-ND
(x1) Arduino Uno (Duemilanove is fine too) Sparkfun DEV-09950

Additional Materials:
22 gauge wire
solder
 
Remove these adsRemove these ads by Signing Up

Step 1: Preparing audio signals for Arduino

Screen shot 2012-09-27 at 2.25.50 PM.png
IMG_2376 copy.jpg
IMG_2381 copy.jpg
IMG_2397 copy.jpg
If  you've ever recorded audio on your computer, you may have seen it represented as a waveform like the one in fig 1.  If you zoom in on this wave (as in fig 2) you will see that the shape is made of thousands of tiny oscillations back and forth.  This is called an audio signal and when we are dealing with audio signals in electronics, these oscillations represent oscillating voltages over time.

When we look at an audio signal with an oscilloscope, we see a similar picture (fig 3).  Notice how the audio signal in fig 3 oscillates around a center voltage of 0V; this is typical of audio signals.  The amplitude of an audio signal is the distance between its center voltage and its high or low peak.  The amplitude of the wave in fig 3 is 2V: it reaches a maximum voltage of +2V and a minimum voltage of -2V.  This is a problem if we want to measure the audio signal with one of the Arduino's analog inputs because the Arduino can only measure voltages between 0 and 5V.  If we tried to measure the negative voltages in the signal from fig 3, the Arduino would read only 0V and we would end up clipping the bottom of the signal.  In this Instructable I'll show you how you can amplify and offset audio signals so that they fall within this 0-5V range.  Ideally you want a signal with an amplitude of 2.5V that oscillates around 2.5V (like in fig 7) so that its min voltage is 0V and its max voltage is 5V (see the calculations below).

Min voltage = Center Voltage - Amplitude
Min voltage = 2.5V - 2.5V = 0V

Max Voltage = Center Voltage + Amplitude
Max Voltage = 2.5V + 2.5V = 5V


Fig 4 shows the signal coming straight out of the microphone on an oscilloscope.  The signal is relatively weak, with an amplitude of only 200mV, you may find that signals from other sources (ipods, guitars, record players...) also produce audio signals with small amplitudes.  These signals need to be amplified to get them up to the amplitude we want (2.5V).  Amplification means increasing the amplitude (distance between the center point and max or min) of a signal.  Amplification also buffers the audio source (in my case this was a microphone) from any loads that you may put on it later in the circuit, which is a good thing because it prevents distortion.

Fig 5 shows the same microphone signal after amplification, you can see how the height of the peaks has increased so that the wave has an amplitude of 2.5V.  But since the center voltage of the wave is still 0, the wave is oscillating between -2.5 and +2.5V.  It will need to be DC offset to correct this.  DC offset means changing the center voltage that the wave oscillates around (the average voltage of the wave).  Fig 6 shows the signal after it has been DC offset; it still has an amplitude of 2.5V, but the center voltage is 2.5V instead of 0V, so the wave never drops down below 0V.  (Note- the slight change in shape between the signals in figures 5 and 6 is dues to changes in my voice between the two pics, it has nothing to do with the circuit).  The signal in fig 6 is ready to go to an Arduino analog input pin.

1-40 of 81Next »
lbais says: May 19, 2013. 1:53 PM
Hi, my name is Lucas and i'm one of your followers from Argentina.
I learnt yesterday your instructable about auido + arduino. And I have a few questions that may be you can explain to me.
I have a little project where I have to record a sample of audio in a SD card, I have the Arduino UNO and ethernet SHIELD.

I've made this input audio http://www.atmel.com/Images/doc1456.pdf (page 7) that I put in my A0 analog input.

I've made a audio format research and I've decide to write the bytes in a WAVE format, that is the simpler audio format that I've found.
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

Following those instructions and yours I could make a sample of audio but it's seems to be issue with the interrupt, like if the interrupt is not working at 38,5khz.

I also saw the interrupt guide that is in linked in your instructable, but I thing that is not clear at all what you are doing there, i can't understand that " ADCSRA " means and why do you put the prescaler to 500khz.

If I make a counting of samples into the main, it takes 27 second to record 380000 samples rate when it should take less than 10 seconds.

I'll send you my pice of code where you can find what I'm doing. (I know that the frecuency I putted in the WAVE header is not 38.5khz but putting 16khz its sounds better).

I hope you can understand what I said, sorry about my english it's pritty bad


//Audio out with 38.5kHz sampling rate and interrupts

#include

struct HEADER
{
byte chunkid[4];
byte chunksize[4];
byte format[4];
byte subchunk1id[4];
byte subchunk1size[4];
byte audioformat[2];
byte numchannels[2];
byte samplerate[4];
byte byterate[4];
byte blockalign[2];
byte bytepersample[2];
byte subchunk2id[4];
byte subchunk2size[4];
};

HEADER headerwave = {0x52, 0x49, 0x46, 0x46, // RIFF
0x00, 0x00, 0x00, 0x00, // 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size) o bien 36 + subchunk2size
0x57, 0x41, 0x56, 0x45, // WAVE
0x66, 0x6d, 0x74, 0x20, // FMT_
0x10, 0x00, 0x00, 0x00, // Chunk size 16 para pcm
0x01, 0x00, // Audio Format PCM
0x01, 0x00, // Cantidad de canales
0x80, 0x3E, 0x00, 0x00, // Frecuencia
0x80, 0x3E, 0x00, 0x00, // SampleRate * NumChannels * BitsPerSample/8
0x01, 0x00, //NumChannels * BitsPerSample/8
0x08, 0x00, // bits por muestra
0x64, 0x61, 0x74, 0x61, // DATA
0x00, 0x00, 0x00, 0x00, // NumSamples * NumChannels * BitsPerSample/8
};

unsigned long int samples = 0;
byte* headerbegin = &headerwave.chunkid[0];
const int chipSelect = 4;
int incomingAudio;
byte flag = 0;
byte iled = 0;
boolean eled = true;


void setup()
{
pinMode(10, OUTPUT);
if (!SD.begin(chipSelect)) {
return;
}

pinMode(7, OUTPUT);

cli();
ADCSRA = 0;
ADCSRB = 0;
ADMUX |= (1 << REFS0); //set reference voltage
ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
ADCSRA |= (1 << ADATE); //enabble auto trigger
ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements
sei();//enable interrupts
}

ISR(ADC_vect)
{//when new ADC value ready
incomingAudio = ADCH;//update the variable incomingAudio with new value from A0 (between 0 and 255)
flag = 0;
/* iled++;
if (iled == 1000)
{
iled = 0;
if (eled)
{
digitalWrite(7, LOW);
eled = false;
}
else
{
digitalWrite(7, HIGH);
eled = true;
}
} */
}


void loop()
{
digitalWrite(7, HIGH);
File dataFile = SD.open("test.wav", FILE_WRITE);
if(dataFile)
{
headerwave.subchunk2size[0] = 0x00;
headerwave.subchunk2size[1] = 0x71;
headerwave.subchunk2size[2] = 0x02;
headerwave.chunksize[0] = 0x24;
headerwave.chunksize[1] = 0x71;
headerwave.chunksize[2] = 0x02;
dataFile.write(headerbegin, 44);

while(true)
{
if(flag == 0)
{
flag = 1;
if (samples < 160000)
{

dataFile.write(incomingAudio);
samples ++;
}
else
{
dataFile.close();
digitalWrite(7, LOW);
}
}
}

}
}
Aldaron13 says: May 16, 2013. 11:28 PM
Hi there. I am new to arduino and was thinking of using this tutorial for a college project. I am just curious on the different applications/uses of this. Would you be able to, say, control something on your computer using sound? Not necessarily voice control but like getting a reaction from (for example) an animation? I am just trying to understand how useful this could be. Any help would be much appreciated!
bwaayer says: May 9, 2013. 2:20 AM
I'm not all to bothered about losing what's on A0, it's just that I can't remove it :( All I would need is say A1 working. Cheers for the quick reply!

I can't reply to your comment annoyingly, as it won't display the captcha :(
bwaayer says: May 9, 2013. 12:30 AM
Hi there, how would I go about reading off of say A1?
I already have something hard-wired to pin A0 :(
amandaghassaei (author) says: May 9, 2013. 1:09 AM
this code (running an analog in at this speed) renders all but one of the analog pins useless
nlarsson2 says: Apr 28, 2013. 9:14 PM
If I amplify the signal before feeding it into the circuit, could I feed the audio jack input straight into this part of the circuit in order to make it usable to the arduino?
amandaghassaei (author) says: Apr 29, 2013. 12:18 AM
Yes, you'll still need the dc offset, but as long as you are amplifying to 2.5v somewhere it should work
rulasIMT says: Apr 12, 2013. 11:32 AM
Hey Again Amanda, i would like to know if you could give me a hand understanding how the code works, i already have the op amp and sac working, and i would like to mix your tutorial with the sketches found in http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/
and also in http://monksoundworks.blogspot.mx
in order to use that effects that i don't understand where the actual effect its done, i mean in which part from sketch, and use them with your input output method
thanks, and hope quick answer still on school project
Regatds Raul
amandaghassaei (author) says: Apr 17, 2013. 11:44 AM
//Audio in with 38.5kHz sampling rate, interrupts, and clipping indicator
//by Amanda Ghassaei
//http://www.instructables.com/id/Arduino-Audio-Input/
//Sept 2012

/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
*/

//variable to store incoming and outgoing audio samples
byte audio;

//clipping indicator variables
boolean clipping = 0;

void setup(){

pinMode(13,OUTPUT);//led indicator pin
DDRD = B11111111;//digital pins 0-7 are all outputs

cli();//disable interrupts

//set up continuous sampling of analog pin 0

//clear ADCSRA and ADCSRB registers
ADCSRA = 0;
ADCSRB = 0;

ADMUX |= (1 << REFS0); //set reference voltage
ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only

ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
ADCSRA |= (1 << ADATE); //enabble auto trigger
ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements

sei();//enable interrupts

//if you want to add other things to setup(), do it here

}

ISR(ADC_vect) {//when new ADC value ready
audio = ADCH;//store 8 bit value from analog pin 0, audio input
if (audio == 0 || audio == 255){//if clipping
digitalWrite(13,HIGH);//set pin 13 high
clipping = 1;//currently clipping
}
//do all digital signal processing stuff here to the variable "audio"
PORTD = audio;//send the output to the DAC
}

void loop(){
if (clipping){//if currently clipping
clipping = 0;//
digitalWrite(13,LOW);//turn off clipping led indicator (pin 13)
}

delay(100);
}
eng mizo says: Apr 17, 2013. 9:49 AM
hay amanda ,, i hope u are well,, thank u very much for your fantastic topic :)

can you help me to do my project of wheelchair controlled voice ??
i need some information about required code
and how i can indicate the words " go , back , right , left , stop" in ardwino code

waiting your answer

thanks alot
amandaghassaei (author) says: Apr 17, 2013. 11:35 AM
hey, this sounds like a really cool project, unfortunately I don't know a ton about speech recognition and I'm not sure the arduino is powerful enough to handle something like that. definitely write back if you figure it out, sorry I couldn't help more.
rulasIMT says: Apr 6, 2013. 11:17 PM
im using your r2r ladder tutorial from there to guitar amp, if i run just a sine wave test it works awsome. i had checked with ociloscope, im using 10k and 22k resistors, at input im using 220k pot and 220k resistor, i also noticed that if i change from guitar if the guitar outputs more resistance lets 15k sounds better than my guitar that outputs 9.5 k
regards and thanks
amandaghassaei (author) says: Apr 7, 2013. 12:15 AM
Did you put a low pass filter on the output? Try increasing the value of the cap
rulasIMT says: Apr 6, 2013. 7:12 PM
Done amanda, now i eliminate the distortion but i have too much background noise
amandaghassaei (author) says: Apr 6, 2013. 8:51 PM
how are you outputting the audio?
rulasIMT says: Apr 6, 2013. 8:46 PM
using ceramic cap code 104
rulasIMT says: Apr 6, 2013. 8:45 PM
i used your clipping check code, and now its right, but what still giving me headaches its the background noise like a hum
rulasIMT says: Apr 6, 2013. 6:30 PM
thanks, mm we are talking about the resistor that bridges the 2 pins from op amp right?,also i made the one you pusted identical and i got a real nice distortion that for guitar pedal its gorgeous, but for my project i wanna get rid of it thanks
regards
amandaghassaei (author) says: Apr 6, 2013. 7:24 PM
the 10k and 100k resistors here:
http://www.instructables.com/id/Arduino-Audio-Input/step3/Non-Inverting-Amplifier/
sounds like you might be clipping, try turning down the amplification
rulasIMT says: Apr 6, 2013. 4:59 PM
Hey Amanda your projects had been very useful for a school project i working on, i would very glad and pleased if yo can help me with the schemtic of the non-inverting amp, but instead a mic, i would use a guitar
regards and thanks in advance
amandaghassaei (author) says: Apr 6, 2013. 5:22 PM
the schematic is the same, you may have to mess around with the resistor value a little bit to get it in the right range
stringstretcher says: Feb 7, 2013. 2:22 AM
Amanda has asked me to post my question here in hopes of finding an answer to my problems.. (at least THIS one!)

I want to log data using an Arduino Uno but am having problems reading my input correctly. The device I want to read is a Radio Shack Sun and Sky Station. It has contacts for DC output, which is in millivolts, never more than 1.5V at max. On my meter it reads a steady voltage, but the Arduino shows a fluctuating reading when using the analog/serial data sketch. I have asked on several of the forums and received varying answers, none of which I can make work. Is the solution an amplifier for the signals? Why does the Arduino give me any reading at all? It seems to vary in an almost sinusoidal wave, but I don't have a scope to see that. Sample and hold? Opamp? Any ideas?

Jim ,
Västerås, Sweden
amandaghassaei (author) says: Feb 16, 2013. 9:16 AM
have you been reading it with you meter while it is attached to the arduino? sometimes meters aren't fast enough to notice these types of fluctuations, can you tell approx what frequency it is by the readings from the arduino?
amandaghassaei (author) says: Feb 16, 2013. 9:17 AM
also, do you have the arduino grounded to the Radio Shack thing's ground?
stringstretcher says: Feb 22, 2013. 2:25 AM
I tried grounding the device's battery to the arduino, with no change. I have not had the Volt/Ohm meter connected while the arduino was reading. I tried adjusting the gain on the device, but the arduino spits out small spikes, or peaks, not a continuous stream, like it should if there were a constant voltage present at the Analog input, which the "should be!"
amandaghassaei (author) says: Mar 28, 2013. 11:05 PM
have you figured it out? sorry I couldn't help more.
stringstretcher says: Apr 3, 2013. 12:56 AM
I managed to get a fair signal reading by placing a 3300 uF cap across the output leads. I took the device to my local shop and asked them to look at the signal output on their scope. They determined a sine ripple, and we could rectify it and get a reading with the Arduino.
Thanks for all the help, we all learn here.
favrin says: Feb 26, 2013. 10:49 AM
Hello amandaghassaei
Great instructable. I followed your unstructions for audio input. I need help to record adc values to sd card. I'm stuck. When i try to write data to sd card i get poor quality audio, with lot of noise and barely audiable. can you help pls?
amandaghassaei (author) says: Mar 28, 2013. 2:21 PM
can you post your code and schematic?
GianfrancoPa says: Mar 11, 2013. 3:17 PM
good works!!!

But, if instead a microphone, I wish to use the magnetic head of a magstripe reader??? What I have to change???

Thanks a lot!!!
amandaghassaei (author) says: Mar 28, 2013. 2:20 PM
yes definitely, I think the setup should be pretty much the same, just replace the two inputs from the mic with the two inputs from the magnetic strip reader.
bhar92 says: Mar 28, 2013. 10:01 AM
Yay! It worked, thanks so much Amanda!
You're awesome!

Bhargav
Bangalore, India
amandaghassaei (author) says: Mar 28, 2013. 2:20 PM
great! what are you using it for?
chownRusBase says: Mar 28, 2013. 1:47 PM
This looks great for a project I want to tackle. How much more work is involved to get the sound out via the USB port?

Thanks!
amandaghassaei (author) says: Mar 28, 2013. 2:19 PM
the arduino is not fast enough to send out this data serially at 38kHz unfortunately.
Dairibar says: Feb 13, 2013. 12:06 PM
Hi Amanda, sorry if this question is to simple, but i dont get why the 47 [nf] capacitor is needed.
Hope you can help me.
Thanks for the tut.
amandaghassaei (author) says: Feb 16, 2013. 9:13 AM
it just helps to decrease noise
aolinger says: Jan 24, 2013. 2:25 AM
Hi Amanda,

many thanks for this nice instructable. I will definitely build it, hook up an oscilloscope and demo the output to my students which are attending an Arduino workshop.

I just came across a small problem in your schematics in Step 3 and 4: A connection is missing: Vin should be connected to the plus pole of the lower 9V battery... the breadboard pictures are showing this vital connection :-)

Have a nice day,

Alex. ICT Teacher.
amandaghassaei (author) says: Feb 4, 2013. 11:17 PM
ah thanks! I will change this asap.
JiahuanZhang says: Jan 16, 2013. 1:20 AM
Wow, I understand! Thank you amandaghassaei. Thank you a lot.
1-40 of 81Next »
Pro

Get More Out of Instructables

Already have an Account?

close

PDF Downloads
As a Pro member, you will gain access to download any Instructable in the PDF format. You also have the ability to customize your PDF download.

Upgrade to Pro today!