Simple audio volume level demo
Phil Pilgrim (PhiPi)
Posts: 23,514
Here's a little demo I concocted for the Propeller Demo Board. It uses an envelope detector from the mic input to generate a bargraph output on the board's LEDs. It ain't much, but some mightt find it useful — or kinda fun, at least. It requires no other hardware besides the Demo Board:
Please forgive me it this has been done before. Sometimes it's easier just to start from scratch than to find something that's already been done.
-Phil
Post Edited (Phil Pilgrim (PhiPi)) : 12/3/2009 6:59:51 AM GMT
[b]CON[/b] [b]_clkmode[/b] = [b]xtal1[/b] + [b]pll16x[/b] [b]_xinfreq[/b] = 5_000_000 env_rate = 20 'Envelope is evaluated this many times per second. sample_rate = 8000 'Microphone is sampled this many times per second. gain = 256 'Envelope is multiplied by this amount. mic_inp = 8 'Microphone input pin. mic_fbk = 9 'Microphone feedback pin. [b]VAR[/b] [b]long[/b] value 'Hub location where envelope value is stored. [b]PUB[/b] demo | loud 'Demo program that uses LEDs on Demo Board to display loudness. start [b]dira[/b][noparse][[/noparse]*23..16]~~ [b]repeat[/b] loud := envelope [b]outa[/b] := $ff << ((loud / 31) + 8) [b]PUB[/b] start 'Start routine for object. mic_dt := clkfreq / sample_rate env_cyc := sample_rate / env_rate [b]cognew[/b](@env_det, @value) [b]PUB[/b] envelope 'Return a value between 0 and 255 for loudness. [b]return[/b] (value * gain) >> 16 <# 255 [b]DAT[/b] [b]org[/b] 0 env_det [b]mov[/b] [b]ctra[/b],[b]ctra[/b]0 [b]mov[/b] [b]dira[/b],[b]dira[/b]0 [b]mov[/b] [b]frqa[/b],#1 [b]mov[/b] bias,mic_dt 'Guess at adc bias level: [b]shr[/b] bias,#1 ' dt / 2. [b]mov[/b] mic_time,[b]cnt[/b] [b]add[/b] mic_time,mic_dt [b]mov[/b] pamp,[b]phsa[/b] env_lp [b]mov[/b] accum,#0 [b]mov[/b] env_cnt,env_cyc mic_lp [b]call[/b] #sample [b]addabs[/b] accum,amp [b]djnz[/b] env_cnt,#mic_lp [b]wrlong[/b] accum,[b]par[/b] [b]jmp[/b] #env_lp '-------[noparse][[/noparse]* sample ]------------------------------------------------------------- ' Read the ADC (microphone) input. sample [b]waitcnt[/b] mic_time,mic_dt 'Wait for adc value to be accumulated. [b]mov[/b] amp,[b]phsa[/b] 'Read it. [b]sub[/b] amp,pamp 'Subtract the previous reading. [b]add[/b] pamp,amp 'pamp := pamp + amp - pamp == pamp [b]sub[/b] amp,bias 'Subtract the DC bias. [b]shl[/b] bias,#4 'Compute running average of bias. [b]add[/b] bias,amp [b]shr[/b] bias,#4 sample_ret [b]ret[/b] env_cyc [b]long[/b] $-$ mic_dt [b]long[/b] $-$ [b]dira[/b]0 [b]long[/b] 1 << mic_fbk [b]ctra[/b]0 [b]long[/b] %01001 << 26 | mic_fbk << 9 | mic_inp bias [b]res[/b] 1 accum [b]res[/b] 1 env_cnt [b]res[/b] 1 mic_time [b]res[/b] 1 pamp [b]res[/b] 1 amp [b]res[/b] 1
Please forgive me it this has been done before. Sometimes it's easier just to start from scratch than to find something that's already been done.
-Phil
Post Edited (Phil Pilgrim (PhiPi)) : 12/3/2009 6:59:51 AM GMT
Comments
Thanks! I've been trying to learn a little PASM lately and it's always great to have some fun ideas to learn from.
This looks perfect for an application I have in mind, to read a voltage that fluctuates between 0-1V, display it on a bargraph; with the user being able to set dynamically the sensitivity via a 'volume' control. I was waiting for one of the Propeller Basic flavours to emerge this month, but it looks like your code does all of the difficult bits!
hope you find time to post more of these "bite sized" code demos - whether they've been done before or not!
Self contained examples requiring few components are most accessable. Plus, the overview of code nearly fitting·into one screen makes study easier.
No matter what your skill level, it's always good to see other programmers'·code - and when it makes lights·flash to tunes, how can we resist?
-·H
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
i have build a small DMX mixer to control with some potentiometers a 220V Dimmerpack (Europe ;-)
I use it for small Theater projects.
Now i would like very much to add a special mode that emulates psychedelic lights.
Your code would be perfect if i could have 3 or 4 levels for bass, middle and trebles.
It does not need to be a perfect FFT algorithm ...
...
Any idea ?
Ciao
Marcello
For your app, Goertzel filters might work. I did a Goertzel object that I used with a speech recognizer. It's included here:
····http://forums.parallax.com/showthread.php?p=837331
You can tune the width of Goertzel filters but not their shape. But for non-critical apps, this is probably enough. For more critical apps, a set of FIR or IIR passband filters would be better, since you can control both their width and shape. I haven't tried to implement one of those yet, though.
-Phil