Arduino Realtime Audio Processing

I have one question about the input circuitry. I would like to know how you adjust the 10k trimpot to set the DC offset to 127?

  • run the loopback test sketch
  • open the serial monitor window with 57600 baud
  • after reset the actual value is shown "ADC offset=127"

this is the code section in setup() . Serial.print("ADC offset="); // trim to 127 ii=badc1; Serial.println(ii); .


Not sure what you are not getting.

You run this code and with no audio going in you getba stream of numbers in the monitor window. As you turn the pot these numbers will change, when you get the number 127 you stop turning the knob and never touch it again.

What changes should i make if the input audio signals from a USB port of a computer?

001neeraj: What changes should i make if the input audio signals from a USB port of a computer?

You can't recieve audio down the UBB port from a computer with the arduino unless you convert the audio into values that you can send down the serial port with some application on the PC.

I don't know anything about that project... But 127 doesn't seem right, and I don't even think it's possible with that circuit (assuming you are directly reading the ADC).

The Arduino has a 10-bit ADC. That means you can read values between zero an 1023. The normal half-way bias-point for AC audio signals would be 511 or 512. Are you getting readings around 500?

If I calculate the minimum reading from turning the offset pot all the way down, I get 1023 x 100K/210K = 487. (And, I get a calculated maximum of around 536.)

Ive built it and it works. It actually sounds pretty good minus a kind of distortion in the background. Anyone have any idea what that is? or how to get rid of it?

It is sampling noise, improve the filter on the output. Consider a 2nd or 4th order filter with a faster drop off.

Thats what I thought. I will look into it unless you have a suggested schematic.

Heres a quick youtube video to show the sound:

I tried an active highpass filter and it seems no different then the origonal one.

I tried an active highpass filter and it seems no different then the origonal one

You need a low pass filter not a hgh pass one.
You also need it to have either a lower break frequency or higher order.
It could be that your noise is aliasing, in which case you need a low pass filter on the front end as well.
But in the video it sounds like sampling noise. Remember it is only 10 bits and the sample rate is not great.

Sorry it was late, I meant lowpass. The filter I made is supposed to have a 1KHz cutoff. What to you reccomend?

The author of the project e-mailed me back and said it is quantization noise which will be more significant with low sound levels. I know nothing about this so any help is greatly appreciated.

Quantization noise comes about because of the difference between the real analogue level and the one you get as a result of digitising the analogue. This is reduced by using more bits in the analogue to digital converter or the digital to analogue converter at the output end.
Without adding extra hardware there is little you can do about this. The output is only 8 bits because of the way it uses PWM where as the input is 10 bits from the A/D converter. So you can add a D/A on the back end and reduce this a bit. However the best way is to use one with an SPI interface. There is one in the Lady Ada wave shield. I have used this in my “translator” for the Maker fair in Rome.

The schematic of the audio out bit is attached.


DC_Offset in this code is the Offset value used to make it a ONLY POSITIVE values for the pwm ( as its easier to work with this kind of signal calculations mimicking nature's laws ... ) As PWM will only work with values up to 255 the middle point is 127( a wave travels between +1 and -1 , with ZERO being the middle point). Does that make more sense ?! So DC_Offset is the value that offsets the result into a positive number( or zero), which is also the same as the value for the amplitude calculations( did you notice is also 127?! dc_offset +127= space wherethe wave will travel...its a cheap way of calculating it in the discrete domain ). Hope it helps! I tried to break down some of the techniques here. Hope it helps complement it a bit !

that sounds pretty good. if you want a reference design for aliasing filters, here is one that works pretty well.

there is a sound sample on there as well, so you can see if it will be any improvement over what you have.

On compiling the program given in 'arduino_audio_loopback' i am getting an error as " TCCR2A not declared" . plz hlp...

On compiling the program given in ‘arduino_audio_loopback’ i am getting an error as " TCCR2A not declared" . plz hlp…

No idea what program this is nor what you are trying to compile it on.
Please provide a link or post the code as an attachment or in code tags.
TCCR2A is a timer register in the ATmega 328 and others but it doesn’t appear on things like the Duo.

Mike is probably right, as usual... my guess would also go on...Maybe the wrong board/chip?! As far as i remember that specific example will work on atmega 328, 168 and previous compatibles( 8, etc). Even to use with the mega 2560 there might be the need for slight alterations in order to port the code( dont quote me on this, for this particular example you mentioned though... Havent looked at the code for a while) , but am sure it does compile and work on the Uno/328,etc.

hey i am missing how did you record your audio sample? and how did you save it without a shield? if you please can support me with a code. i really need it

Thanks in advance

Nice try whippoorwill but if you read the thread it is about processing audio not saving it.

I realize this is an old thread, if I should have started a new thread I'm sorry in advance. I was just going through the reverb example and something jumped out at me:

  // set adc prescaler  to 64 for 19kHz sampling frequency
  cbi(ADCSRA, ADPS2);
  sbi(ADCSRA, ADPS1);
  sbi(ADCSRA, ADPS0);

Doesn't this set the prescaler to 8, not 64? So its sampling at 153kHz rather. Was this intentional and the comment is just wrong? I attemped setting bits 2 and 1 and clearing pin 0 to set it to 64, but the output just isn't the same (much quieter for whatever reason). Still going through the rest of the code to see what's going on with that just thought someone might have some insight.