xcesmess:
Thats one half of the question… the other is what would be the proper way to port the audio into the ADC on the avr? For testing I put the audio from a headphone output directly into ADC0 and it gives me a reading but it is very jumpy and doesn’t seem consistent. Probably doesn’t give much of a good description there… I saw some others putting the audio through a couple of capacitors for filtering so maybe this is what I need to do…
Well, you need to understand how a VU meter works first. Since the meter readings are not changing fast (even an analog meter has to be “damped” to slow it appropriately) you can’t just read the audio with the ADC a few times a second and expect it to work well. You need to average the amplitude of the “envelope” before you display it.
Typically, VU meter circuits consist of a full-wave rectifier and a peak-detecting circuit, followed by a log converter.
This would probably be the easiest way to do the job, as it would take a lot of CPU (and maybe a faster ADC) to do the job in software.
Remember too that VU meters are logarithmic in response (more or less) since our ears’ response to audio is more or less logarithmic.
However…
If you want to do it in software, you have to sample fast enough to actually catch the peaks of the waveforms; this typically requires at least 5x the highest bandwidth of interest. If you want to capture the peaks of the signal up to (say) 10Khz you’d need a 50 Khz sample rate. This is 20 usec/sample.
But the ADC of (say) the Atmega48/88/168 will only give you 15000 samples/second at the maximum resolution. Not to worry; if you arrange for an appropriate clock (650Khz?) to the ADC you’ll be able to do this. You don’t need that many bits of resolution for a VU meter!
Then you have to do the rest of the work in 20 usec.
This would consist of:
-
getting the sample (you can grab either 8 or 16 bits here but you probably want 16 to get the full 10 bits of ADC result)
-
full-wave rectifying it (if it’s less than 0, negate it)
-
peak-detecting it: if the ADC value is greater than the current peak-detect signal, then keep this ADC value as a peak value
Meanwhile, you have to decay the peak-detect value; you can do this during a timer interrupt routine (I recommend an exponential filter here; subtracting (say) 1/256 of the value per interrupt would give you a smooth decay. And dividing by 256 is just a shift.
And at the same time (possibly from the same interrupt routine) you have to update the LCD readings. Though you could probably ignore the audio briefly during that period.
You’ll want to drive the LCD from the log of the peak-detector output. The easiest way to do this is to look at the highest bit that is set in the peak-detector accumulator; each bit location is worth 1/2 of the one before, or 6dB (since you’re measuring voltage).
Have fun!