From 56c0aaedcdaeddeb7208ba20b6c584051cfb12c5 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 6 May 2018 02:39:39 +0200 Subject: [PATCH] Mag AGC: corrected step calculation. Added method to combine step up and down smoothing --- plugins/channelrx/demodssb/ssbdemod.cpp | 6 +++--- plugins/channelrx/udpsrc/udpsrc.cpp | 2 +- plugins/channeltx/modssb/ssbmod.cpp | 7 +++++-- plugins/channeltx/modssb/ssbmod.h | 1 + sdrbase/dsp/agc.cpp | 20 +++++++++++++++----- sdrbase/dsp/agc.h | 3 ++- 6 files changed, 27 insertions(+), 12 deletions(-) diff --git a/plugins/channelrx/demodssb/ssbdemod.cpp b/plugins/channelrx/demodssb/ssbdemod.cpp index a3320cffd..38e5c51d7 100644 --- a/plugins/channelrx/demodssb/ssbdemod.cpp +++ b/plugins/channelrx/demodssb/ssbdemod.cpp @@ -220,7 +220,7 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto } else { - fftfilt::cmplx z = delayedSample * m_agc.getStepDownValue(); + fftfilt::cmplx z = delayedSample * m_agc.getStepValue(); if (m_audioBinaual) { @@ -405,7 +405,7 @@ void SSBDemod::applyAudioSampleRate(int sampleRate) if (m_agcNbSamples != agcNbSamples) { - m_agc.resize(agcNbSamples, agcTarget); + m_agc.resize(agcNbSamples, std::min(sampleRate/20, agcNbSamples/2), agcTarget); m_agc.setStepDownDelay(agcNbSamples); m_agcNbSamples = agcNbSamples; } @@ -503,7 +503,7 @@ void SSBDemod::applySettings(const SSBDemodSettings& settings, bool force) if (m_agcNbSamples != agcNbSamples) { m_settingsMutex.lock(); - m_agc.resize(agcNbSamples, agcTarget); + m_agc.resize(agcNbSamples, std::min((int)m_audioSampleRate/20, agcNbSamples/2), agcTarget); m_agc.setStepDownDelay(agcNbSamples); m_agcNbSamples = agcNbSamples; m_settingsMutex.unlock(); diff --git a/plugins/channelrx/udpsrc/udpsrc.cpp b/plugins/channelrx/udpsrc/udpsrc.cpp index 09370909b..191700b1f 100644 --- a/plugins/channelrx/udpsrc/udpsrc.cpp +++ b/plugins/channelrx/udpsrc/udpsrc.cpp @@ -524,7 +524,7 @@ void UDPSrc::applySettings(const UDPSrcSettings& settings, bool force) m_squelchRelease = (settings.m_outputSampleRate * settings.m_squelchGate) / 100; initSquelch(m_squelchOpen); - m_agc.resize(settings.m_outputSampleRate * 0.2, m_agcTarget); // Fixed 200 ms + m_agc.resize(settings.m_outputSampleRate/5, settings.m_outputSampleRate/20, m_agcTarget); // Fixed 200 ms int stepDownDelay = (settings.m_outputSampleRate * (settings.m_squelchGate == 0 ? 1 : settings.m_squelchGate))/100; m_agc.setStepDownDelay(stepDownDelay); m_agc.setGate(settings.m_outputSampleRate * 0.05); diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp index 04daf762b..b31332d19 100644 --- a/plugins/channeltx/modssb/ssbmod.cpp +++ b/plugins/channeltx/modssb/ssbmod.cpp @@ -68,7 +68,8 @@ SSBMod::SSBMod(DeviceSinkAPI *deviceAPI) : m_levelCalcCount(0), m_peakLevel(0.0f), m_levelSum(0.0f), - m_inAGC(9600, 0.2, 1e-4) + m_inAGC(9600, 0.2, 1e-4), + m_agcStepLength(2400) { setObjectName(m_channelId); @@ -690,6 +691,8 @@ void SSBMod::applyAudioSampleRate(int sampleRate) m_toneNco.setFreq(m_settings.m_toneFrequency, sampleRate); m_cwKeyer.setSampleRate(sampleRate); + m_agcStepLength = std::min(sampleRate/20, m_settings.m_agcTime/2); // 50 ms or half the AGC length whichever is smaller + m_settingsMutex.unlock(); m_audioSampleRate = sampleRate; @@ -796,7 +799,7 @@ void SSBMod::applySettings(const SSBModSettings& settings, bool force) (settings.m_agcOrder != m_settings.m_agcOrder) || force) { m_settingsMutex.lock(); - m_inAGC.resize(settings.m_agcTime, settings.m_agcOrder); + m_inAGC.resize(settings.m_agcTime, m_agcStepLength, settings.m_agcOrder); m_settingsMutex.unlock(); } diff --git a/plugins/channeltx/modssb/ssbmod.h b/plugins/channeltx/modssb/ssbmod.h index 4276f3b30..72cad1980 100644 --- a/plugins/channeltx/modssb/ssbmod.h +++ b/plugins/channeltx/modssb/ssbmod.h @@ -309,6 +309,7 @@ private: CWKeyer m_cwKeyer; MagAGC m_inAGC; + int m_agcStepLength; static const int m_levelNbSamples; diff --git a/sdrbase/dsp/agc.cpp b/sdrbase/dsp/agc.cpp index 82f2f59b7..1a94b7457 100644 --- a/sdrbase/dsp/agc.cpp +++ b/sdrbase/dsp/agc.cpp @@ -10,8 +10,6 @@ #include "util/stepfunctions.h" -#define StepLengthMax 2400 // 50ms - AGC::AGC(int historySize, double R) : m_u0(1.0), m_R(R), @@ -49,7 +47,7 @@ MagAGC::MagAGC(int historySize, double R, double threshold) : m_threshold(threshold), m_thresholdEnable(true), m_gate(0), - m_stepLength(std::min(StepLengthMax, historySize/2)), + m_stepLength(std::min(2400, historySize/2)), // max 50 ms (at 48 kHz) m_stepDelta(1.0/m_stepLength), m_stepUpCounter(0), m_stepDownCounter(m_stepLength), @@ -63,10 +61,10 @@ MagAGC::MagAGC(int historySize, double R, double threshold) : MagAGC::~MagAGC() {} -void MagAGC::resize(int historySize, Real R) +void MagAGC::resize(int historySize, int stepLength, Real R) { m_R2 = R*R; - m_stepLength = std::min(StepLengthMax, historySize/2); + m_stepLength = stepLength; m_stepDelta = 1.0 / m_stepLength; m_stepUpCounter = 0; m_stepDownCounter = m_stepLength; @@ -188,3 +186,15 @@ float MagAGC::getStepDownValue() const return StepFunctions::smootherstep(m_stepDownCounter * m_stepDelta); } } + +float MagAGC::getStepValue() const +{ + if (m_count < m_stepDownDelay) + { + return StepFunctions::smootherstep(m_stepUpCounter * m_stepDelta); // step up + } + else + { + return StepFunctions::smootherstep(m_stepDownCounter * m_stepDelta); // step down + } +} diff --git a/sdrbase/dsp/agc.h b/sdrbase/dsp/agc.h index 75f3959c7..4e0e2939c 100644 --- a/sdrbase/dsp/agc.h +++ b/sdrbase/dsp/agc.h @@ -39,7 +39,7 @@ public: MagAGC(int historySize, double R, double threshold); virtual ~MagAGC(); void setSquared(bool squared) { m_squared = squared; } - void resize(int historySize, Real R); + void resize(int historySize, int stepLength, Real R); void setOrder(double R); virtual void feed(Complex& ci); double feedAndGetValue(const Complex& ci); @@ -52,6 +52,7 @@ public: void setClampMax(double clampMax) { m_clampMax = clampMax; } int getStepDownDelay() const { return m_stepDownDelay; } float getStepDownValue() const; + float getStepValue() const; private: bool m_squared; //!< use squared magnitude (power) to compute AGC value