AGC recovery rate?

Is there a setting to control the rate at which the KiwiSDR AGC recovers gain after a strong signal goes away? It seems to do this a little fast for my taste. There's a hang parameter, but after this expires the gain increases very rapidly.

The AGC I've implemented for my own SDR lets you set the recovery rate. I typically use 20 dB/sec for SSB, but that's a personal preference.

As an aside here's how my AGC works. I have the following parameters with my usual values for SSB:

Headroom = -15 dBFS (good for typical gaussian signal statistics)

Threshold = -15 dB (target level below "headroom" on noise only)

Hang time = 1.1 sec

Recovery rate = 20 dB/s

The headroom sets the target output level, averaged over a processing block time (typically 20 ms). -15 dBFS is good for the gaussian statistics of a typical signal.

"Threshold" is implemented rather differently because it uses a real-time measurement of the noise floor (done by looking at a wide frequency range and finding the lowest FFT bins). On pure noise the gain is set to bring the output noise level to "threshold" dB below the headroom setting (i.e., -15 dBFS - 15 dB = -30 dBFS). When a signal appears and gradually increases in level, the output level will increase from -30 dBFS to -15 dBFS and then the receiver gain will decrease to keep the signal at -15 dBFS as the signal continues to get stronger. (I haven't felt the need for a slope parameter, i.e., it's 0 dB).

When the signal disappears, gain is held constant for 1.1 sec and then begins to increase at 20 dB/s until the noise level again reaches -30 dBFS.


  • have you looked at the AGC options in kiwiclient?

  • I'm only looking at the interactive controls.

  • jksjks
    edited April 2022

    The AGC code is lifted straight out of Moe Wheatley's (AE4JY) CuteSDR program. I have no idea how it works beyond what is described in his manual. If there are suggestions for changes/improvements we could certainly try those.

  • Thanks for that document, looks pretty good! His AGC section mentions two recovery rates, fast and slow. But I can't find any controls in the web interface that would select this.

  • edited April 2022

    If you're taking suggestions, here goes...

    I can't find anyone else doing automatic AGC thresholding, so I think it's novel. (No, I'm not going to try to patent it. But I'd like to get it out there to keep anyone else from doing so).

    I think it works pretty well. Instead of having to readjust a threshold knob whenever the noise level changes (e.g., with a band change), I continually measure the noise level and use it to automatically adjust the AGC threshold.

    I do have a "threshold" knob, but you set it once to how loud you want the no-signal noise to be at the receiver output, e.g., -30 dBFS. The noise level decreases on a strong signal, but when the signal goes away and the receiver gain increases again (at a specified rate) it will not bring the noise above -30 dBFS.

    The only hard part is the noise floor measurement, which requires some part of your IF to not have a signal. My receiver uses fast correlation (filtering with FFTs) so it already has the entire receiver IF in the frequency domain. I estimate the noise floor by keeping a smoothed average power for each frequency bin and looking for the bin with the lowest average power. This is similar to how we estimate the noise floor on a spectrum analyzer by eye: reduce the video bandwidth to smooth out the grass and look for the point with the lowest level.

    The KiwiSDR could get its noise floor estimate from its waterfall data.

    There are some gotchas. Many tuner-type SDR front ends roll off the edges of the IF passband, and you don't want to be fooled by them. My front end driver already tells me the usable limits of the IF spectrum so I can simply ignore the edges in my noise estimation. But even if the receiver is flat and wide (like the KiwiSDR) the noise floor might not be flat, especially on HF, so you don't want to look too far away from your signal. But you want to look far enough to be reasonably sure of finding a FFT frequency bin with no signal. (Band edges are a no-man's land, so they might be a good choice.)

    I'm actively experimenting with various algorithms, and I'm thinking there may not be one ideal algorithm. HF, with its decidedly non-gaussian noise, may require a different method than VHF and above, where noise is usually thermal and flat. But even on VHF and UHF you have to be careful. I have been looking at digital TV pilots, and I don't want my noise estimate to be fooled by the DTV sidebands.

    A real-time noise floor estimate is a surprisingly useful thing to have in a receiver. Besides assisting an AGC it can give you real-time SNR (and N0, and S/N0) measurements, e.g., for signal reports that actually mean something. They might also be useful for squelches. My existing FM squelch works from first principles by computing the IF SNR from the mean and variance of the signal amplitude (any variation in an ideal FM signal is noise) and correcting for the Ricean (not gaussian) distribution of the amplitude. It works very well and I probably won't change it.

    My current AM squelch locks a PLL to the carrier with a lock detector gating the squelch. (My lock detector compares in-phase and quadrature power relative to the PLL oscillator, a classic method.) This works very well for VHF aviation AM. But SSB has no carrier, so SNR measurements would seem to be the way to go for an SSB squelch.

  • Wow, KA9Q!

    It was since I was 14 and I was doing packet radio on HF and VHF that I didn't see that call ;-) I like the idea for this AGC algorithm. I'll try to implement it on SuperSDR when I've got some spare time. Some time ago I used a similar method to compute the SNR of WSPR and FT8 transimssions since the one included into WSJTX is flawed.

    Thanks for the idea and all the cool software you created over the years!

    marco / IS0KYB

Sign In or Register to comment.