question about audio capture

I have configured and programmed a 10 channel vu meter with peak hold.

I have created a voltage divider 2 10k resistors centertapped with a 10uf cap so that the audio comes in balanced.

I scan the input , subtract 512 (to set 0 reference), then take the abs value

I scraped together an averaging routine that works and I can see the programming is correct with a potentiometer (+5 and ground), I turn it one way the bar graph goes up, then turn it the other way the graph goes down as the voltage approaches 2.5 then goes back up again.

I am using the map command to map my input values (typically 0-127) to 0-15 for my display size.

The problem that I am having is that I only see some of the peaks from the audio and in the code I am skipping the averaging if the new input
is greater than the recorded max.

Does anyone have any ideas?

Thanks!

Use a [u]peak detector[/u]. You will probably need to experiment with different resistor & capacitor values to get the proper decay-time.

With the peak detector, you don't need the voltage divider/bias resistors, but you are only getting the positive peaks. Usually this is OK for a "casual" VU meter, but if you really need to read the negative peaks, you'll need to add a couple more op-amps to make a "full-wave precision rectifier" followed by the peak detector (or build a full-wave peak detector).

And if your op-amps run off more than 5V, it's a good idea to add a resistor & protection diodes at the Arduino input.

P.S
With a peak detector, obviously you cannot read a true average. However, with a quick discharge time (say 1/10th of a second) the peak readings will very a lot and you can take an average of the peaks (which will be a lot lower than the maximum-peak), or display the instantaneous varying-peaks , while optionally holding the maximum-peak in memory, and perhaps displaying the long-term peak at the same time.


A peak detector works by quickly charging-up a capacitor through a diode. The capacitor then holds the maximum voltage it has "seen", since it can't discharge "backwards" through the diode. The capacitor is either discharged later by turning-on a switch, or slowly discharged through a resistor. (The resistor-discharge method is normaly used in audio-related circuits.)

The op-amp does two things - The feedback circuit compensates for the 0.5 to 0.7V drop across the diode, which allows you to linarly detect low-level signals (belos 1/2V) that would otherwise be blocked by the diode. The op=amp also provides the current necessary to quickly charge-up the capacitor.

Awesome! Thank you for the detailed answer. Just because I am stubborn..... Isn't there a way I can simulate this in software?
I understand that everything has limitations, one of the unknowns for me is what the sample rate is working out to while my routine is running.

Awesome! Thank you for the detailed answer. Just because I am stubborn..... Isn't there a way I can simulate this in software?

Sure... But, you need more processing power to capture and process that much data. And if you want to take an average, you need to store lots of data. (A PC can handle it.)

The basic idea of the peak detector is that your software can run at a slow rate... Just fast enough to follow the volume "envelope" without following the actual audio waveform details... Your brain probably can't comprehend more than 10 readings/changes per second anyway. Any faster and it's just a flickering blurr... If you had a numerical display (rather than a bar-graph) 4 readings per second would probably be too fast to be useful. (If your digital speedometer updated 4 times per second, it would drive you nuts!)

If you want to capture the actual waveform, digital audio is sampled thousands of times per second. To capture the full audio range (up to about 20kHz) you need at least 40,000 samples per second (Nyquist theory). CDs are sampled at 44.1kHz. You've got 10 channels, so you'd need to capture 10 times as much total data. If you want to calculate a 1-second moving average for 10 channels, you need to store almost 1/2 Megabyte of data!!!! (EDIT - Actually more than that, since each sample is 10 bits.)

There are some tricks you can use to reduce the data storage, such as taking a 1/10th-second moving-average, and then calculating an average-of-averages to smooth-out the data over a longer period of time. But still, you are dealing with a ship-load of data coming at you very-fast.

...one of the unknowns for me is what the sample rate is working out to while my routine is running.

I'm not sure either. There is some maximum sample rate (which I don't know), and it also depends on how long it takes your sketch to process the data and get back-around to handling another sample.

P.S
The spec sheet says:

• Up to 76.9kSPS (Up to 15kSPS at Maximum Resolution)

So.. You can go faster that than the CD rate of 44,100 samples per second, but only 15,000 samples per second if you want the full 10-bit accuracy/resolution. And, your program still has run fast-enough to keep-up with rate you are trying to sample.

Thanks again! I am very familiar with the Nyquist theory. I was under the false assumption that the arduino was sampling at a lot faster rate.

The peak detector you referred me to, how long does that hold the sample? I really only need it to hold the rough average of the overall power of the audio.

My goal with this project is for my band. I play bass and I get to be the sound guy. When we are having a feedback issue , I want to be able to glance over and see which channel is pinned and know instantly which channel to adjust.

The Arduino ADC is a successive-approximation ADC of fairly modest specification. Run faster it will be noisier and not really achieve 10bit accuracy, but it should be reasonable. Running 10 channels fast will be too much I think.

How do you handle 10 channels? Is this an Arduino Mega?

If you have a circuit that stretches peaks it will reduce the speed your ADC has to run.