Automatic Gain Control
This is an attempt to implement some kind of gain leveling for
the audio of my ssb GNU/Radio receiver. While tuning around, or
when different operators with different signal strengths speak
I have to 'ride' the volume control to hear the weak ones
and attenuate the loud ones. The audio.sink wants floating
point signal between -1 and 1, anything over that starts 'clicking'
and turns into noise.
Basically I just want to follow the envelope of the audio and adjust
the gain according. A quick check of google for 'dsp envelope follower'
turns up this interesting lecture
and down near the bottom is "Non-linear One Pole Application:
The Envelope Follower", which is basically an absolute value followed
by a "special one pole low-pass smoothing filter". That feedback
scheme looked familiar. Playing around
with different arrangements this is the best I could come up with:
audio -----+-----+==[sqr]----[int]----[offset]----[agc]-----out
| |
| |
| |
+----------------------------------------+
where sqr = gr.multiply_ff()
int = gr.iir_filter_ffd ( [.002, 0], [0, .999] )
offset = gr.add_constant_ff(1)
agc = gr.divide_ff()
where the signal is squared (in place of absolute value), run thru
our 'leaky' integrator, with the feed forward tap adjusted to give
reasonable values, add 1 then divide the input sigal with the agc
signal. Using a test signal simulated by a 600hz tone mixed with a 2hz
tone and a 2.2hz tone to get a low freq envelope gives this:
the red is the input signal, green the agc and blue the output,
where you can see we're getting some soft cutoff over .5. Putting
this code ('scale' is the previous audio output signal) into our receiver :
sqr1 = gr.multiply_ff()
int = gr.iir_filter_ffd ( [.002, 0], [0, .999] )
offset = gr.add_const_ff(1)
agc = gr.divide_ff()
fg.connect (scale, (sqr1, 0))
fg.connect (scale, (sqr1, 1))
fg.connect (sqr1, int)
fg.connect (int, offset)
fg.connect (offset, (agc, 1))
fg.connect (scale, (agc, 0))
fg.connect (agc, out)
and finding a loud signal we get this real world
performance:
which actually sounds much better and 'even', allowing weak signals thru
and controlling the stronger ones.