Tagged: automatic gain control

A New Software Automatic Gain Control Algorithm C Library for RTL-SDR and other SDRs

Thank you to Chris Gianakopoulos for writing in and sharing with us the release of his open-source software-based Automatic Gain Control (AGC) library written in C. The library is hardware agnostic and designed to make it easy for programmers to implement an AGC algorithm into their programs. The AGC library can help automatically optimize the signal-to-noise-ratio (SNR) on SDRs with variable-gain amplifiers (VGA). Chris explains:

I converted my software AGC to C code with the following enhancements:

1. It is radio-agnostic.
2. Itis written in C so that both, C and C++ apps can use it.
3. The app provides two callback functions: one to provide the current amplifier gain setting and one to set the amplifier gain.
4. A signal magnitude is provided as input to the AGC algorithm
5. Among other things,the number of bits to represent the signal magnitude, at init time.

For more details, the repo is located at,

https://github.com/wizardyesterday/AutomaticGainControl

I have successfully integrated this AGC into a test version of radio diags, located at

https://github.com/wizardyesterday/RtlSdrWork_agc

-----

An Automatic Gain Control (AGC) is a feeback system that adjusts the gain of a variable-gain amplifier (VGA) to maintain an operating point such as a voltage magnitude level, current magnitude level, or in the case of a digital radio, the magnitude of signal samples presented to the AGC. Typically, an average magnitude of a block of data is used to perform a smoothing action to the input provided to the AGC.

An attempt was made to make an accurate implementation of what was described in the paper (by Fred Harris and Gregory Smith) in the doc/papers/ directory. For details on design and implementation, refer to that paper.

He goes on to mention why a software AGC is useful:

My motivation for creating an AGC was to give people the ability to run SDR software on radios which conain A/D converters that produce 8-bit output samples. With a 48dB (theoretically, ignoring implementation loss), you don't have much to work with in a radio environment with radically different signal strengths.

With an amplifier, whose output drives an A/D converter, on the rtl-sdr, when I listened to aircraft frequencies, I would hear strong tones when a strong signal would be received. The solution was to reduce the LNA and mixer gains.

I asked myself, why would I want to reduce front-end sensitivity when signal overload was not occuring at the variable gain amplifer input? It was A/D converter overload!

With an AGC, the user can establish a safe operating point that allows enough headroom to avoid overload when a strong signal arrives. When the signal goes away, the gain is increased so that you can hear weak signals.

Hopefully, developers of SDR software will see this and implement it into their software!

A Software Based VGA AGC Implementation for the RTL-SDR

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:

  1.  The (approximately) 3.5dB step size in VGA gain adjust.
  2. 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.