From 68601d69474f3346be70060446ea85d141383f00 Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 11 Dec 2023 01:13:11 +0100 Subject: [PATCH] SSB demod: better algorithm for AGC limitation. For #1918 --- plugins/channelrx/demodssb/readme.md | 2 +- plugins/channelrx/demodssb/ssbdemodsink.cpp | 15 ++++----------- plugins/channelrx/demodssb/ssbdemodsink.h | 2 -- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/plugins/channelrx/demodssb/readme.md b/plugins/channelrx/demodssb/readme.md index 2a8f1ac90..9694a378a 100644 --- a/plugins/channelrx/demodssb/readme.md +++ b/plugins/channelrx/demodssb/readme.md @@ -143,7 +143,7 @@ This AGC is based on the calculated magnitude (square root of power of the filte

13.3: AGC clamping

-When on this clamps signal at the maximum amplitude. Normally this is not needed for most signals as the AGC amplitude order is quite conservative at 10% of the maximum. You may switch it on if you notice a loud click when a transmission starts. +This limits AGC gain when signal rises up sharply avoiding peak audio overload. You may switch it on if you notice a loud click on strong signals after silences.

13.4: Noise Reduction

diff --git a/plugins/channelrx/demodssb/ssbdemodsink.cpp b/plugins/channelrx/demodssb/ssbdemodsink.cpp index de11cf690..7531b4d69 100644 --- a/plugins/channelrx/demodssb/ssbdemodsink.cpp +++ b/plugins/channelrx/demodssb/ssbdemodsink.cpp @@ -73,8 +73,6 @@ SSBDemodSink::SSBDemodSink() : m_magsqSum = 0.0; m_magsqPeak = 0.0; m_magsqCount = 0; - m_magsqCur = 0.0; - m_magsqPrev = 0.0; SSBFilter = new fftfilt(m_LowCutoff / m_audioSampleRate, m_Bandwidth / m_audioSampleRate, m_ssbFftLen); DSBFilter = new fftfilt((2.0f * m_Bandwidth) / m_audioSampleRate, 2 * m_ssbFftLen); @@ -175,24 +173,20 @@ void SSBDemodSink::processOneSample(Complex &ci) float agcVal = m_agcActive ? m_agc.feedAndGetValue(sideband[i]) : 1.0; fftfilt::cmplx& delayedSample = m_squelchDelayLine.readBack(m_agc.getStepDownDelay()); m_audioActive = delayedSample.real() != 0.0; - m_magsqCur = std::norm(sideband[i]*agcVal); // Prevent overload based on squared magnitude variation // Only if AGC is active - if (m_agcActive && m_agcClamping && (std::abs(m_magsqCur - m_magsqPrev) > m_agcTarget*m_agcTarget*5.0) & (agcVal > 100.0)) + if (m_agcActive && m_agcClamping && agcVal > 100.0) { - float target = m_agcTarget*sqrt(agcVal); // Quench AGC depending on previous value - m_agc.reset(target); - m_squelchDelayLine.write(fftfilt::cmplx{target, 0.0}); - m_magsqCur = target*target; + qDebug("SSBDemodSink::processOneSample: %f", agcVal); + m_agc.reset(m_agcTarget*m_agcTarget); + m_squelchDelayLine.write(fftfilt::cmplx{0.0, 0.0}); } else { m_squelchDelayLine.write(sideband[i]*agcVal); } - m_magsqPrev = m_magsqCur; - if (m_audioMute) { m_audioBuffer[m_audioBufferFill].r = 0; @@ -200,7 +194,6 @@ void SSBDemodSink::processOneSample(Complex &ci) } else { - // fftfilt::cmplx z = m_agcActive ? delayedSample * m_agc.getStepValue() : delayedSample; fftfilt::cmplx z = (m_agcActive && m_agcClamping) ? fftfilt::cmplx{m_lowpassI.filter(delayedSample.real()), m_lowpassQ.filter(delayedSample.imag())} : delayedSample; diff --git a/plugins/channelrx/demodssb/ssbdemodsink.h b/plugins/channelrx/demodssb/ssbdemodsink.h index 7d26d2208..e2f36c3cd 100644 --- a/plugins/channelrx/demodssb/ssbdemodsink.h +++ b/plugins/channelrx/demodssb/ssbdemodsink.h @@ -102,8 +102,6 @@ private: double m_magsqSum; double m_magsqPeak; int m_magsqCount; - double m_magsqCur; - double m_magsqPrev; MagSqLevelsStore m_magSqLevelStore; MagAGC m_agc; bool m_agcActive;