Thank you to Chris G for writing in and sharing with us his software VGA ADC controller for the RTL-SDR. AGC or 'automatic gain control' is an algorithm that attempts to automatically adjust the gain on the RTL-SDR in order to maximize the signal to noise ratio. The built in hardware AGC's on the RTL-SDR are intended for wideband TV signals, and work poorly with the narrower signals that SDR users typically deal with. However, it's possible that a software AGC implementation could be used instead.
Initially, I wanted to see how well things would work if I could manually control the VGA gain to avoid A/D overload within the 2832 chip.
I liked how things worked so I said: let's make things automatic! I implemented two variants of my AGC. One variant (my favorite) is an implementation of an AGC by Harris and Smith. It is an LMS algorithm that has equal transient response to a sudden increase in input signal magnitude and a sudden decrease in signal magnitude.
Since I'm doing this stuff in software, I operate on blocks of IQ data rather than operating on a sample by sample basis.
Initially, I observed limit cycles for at least two reasons:
- The (approximately) 3.5dB step size in VGA gain adjust.
- The fact that when I receive a block of IQ data, another block is in transit.
This resulted me adjusting the gain while a block of data was in transit.
For item 1, I allow the deadband go be settable.
For item 2, I allow a "blanking time" to be settable. For my use case, If the AGC just made an adjustment, I skip making an adjustment while the next black is in transit.
Here is output of my 'get agcinfo' command.
--------------------------------------------
AGC Internal Information
--------------------------------------------
AGC Emabled : Yes
AGC Type : Harris
Blanking Counter : 0 ticks
Blanking Limit : 1 ticks
Lowpass Filter Coefficient: 0.800
Deadband : 1 dB
Operating Point : -12 dBFs
IF Gain : 11 dB
/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
Signal Magnitude : 27
RSSI (After Mixer) : -24 dBFs
/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/Note that my setpoint and gain adjustment works in decibels. That way, I treat the AGC as a linear system (it's actually uses an LMS algorithm) to simplify processing.
Now, I have used the same algorithm for my HackRF software.
I should mention that I implemented a pretty nice software squelch system for the rtl-sdr (and HackRF of course) if you have any interest in that.
I have a github repository at github.com/wizardyesterday/RtlSdrDiags.
I've thought about adding an I2C DAC whose output is connected to the VGA analog gain control line, but I really hate to butcher my v3 dongle. Having 1dB (or less) gain resolution would be nice though.
Another thing that I noticed is that, when writing to the tuner registers, the I2C repeater is enabled and you hear a spike in the demodulated audio. This may also occur (I haven't done that experiment) when disabling the repeater. Maybe not......
I have composed a report in, github.com/wizardyesterday/RtlSdrDiags/blob/master/doc/agcResearch/README.txt
If you get curious how I implemented my AGC, you can look at the file, github.com/wizardyesterday/RtlSdrDiags/blob/master/radioDiags/src_diags/AutomaticGainControl.cc.
The header file is in radioDiags/hdr_diags/AutomaticGainControl.h.