diff --git a/sdrbase/dsp/agc.cpp b/sdrbase/dsp/agc.cpp index f87c5660f..ee4662593 100644 --- a/sdrbase/dsp/agc.cpp +++ b/sdrbase/dsp/agc.cpp @@ -5,6 +5,7 @@ * Author: f4exb */ +#include #include "dsp/agc.h" #include "util/smootherstep.h" @@ -48,13 +49,21 @@ MagSquaredAGC::MagSquaredAGC(int historySize, double R, double threshold) : m_magsq(0.0), m_threshold(threshold), m_gate(0), - m_stepCounter(0), + m_stepLength(std::min(2400, historySize/2)), + m_stepUpCounter(0), + m_stepDownCounter(0), m_gateCounter(0) {} MagSquaredAGC::~MagSquaredAGC() {} +void MagSquaredAGC::resize(int historySize, Real R) +{ + m_stepLength = std::min(2400, historySize/2); + AGC::resize(historySize, R); +} + void MagSquaredAGC::feed(Complex& ci) { m_magsq = ci.real()*ci.real() + ci.imag()*ci.imag(); @@ -91,16 +100,23 @@ double MagSquaredAGC::feedAndGetValue(const Complex& ci) if (m_count < m_moving_average.historySize()) { - if (m_stepCounter < 2400) { - m_stepCounter++; + m_stepDownCounter = m_stepLength; + + if (m_stepUpCounter < m_stepLength) { + m_stepUpCounter++; } - return m_u0 * StepFunctions::smootherstep(m_stepCounter/2400.0); + return m_u0 * StepFunctions::smootherstep(m_stepUpCounter/m_stepLength); } else { - m_stepCounter = 0; - return 0.0; + m_stepUpCounter = 0; + + if (m_stepDownCounter > 0) { + m_stepDownCounter--; + } + + return m_u0 * StepFunctions::smootherstep(m_stepDownCounter/m_stepLength); } //return (m_count < m_moving_average.historySize()) ? m_u0 : 0.0; @@ -116,13 +132,21 @@ MagAGC::MagAGC(int historySize, double R, double threshold) : m_magsq(0.0), m_threshold(threshold), m_gate(0), - m_stepCounter(0), + m_stepLength(std::min(2400, historySize/2)), + m_stepUpCounter(0), + m_stepDownCounter(0), m_gateCounter(0) {} MagAGC::~MagAGC() {} +void MagAGC::resize(int historySize, Real R) +{ + m_stepLength = std::min(2400, historySize/2); + AGC::resize(historySize, R); +} + void MagAGC::feed(Complex& ci) { m_magsq = ci.real()*ci.real() + ci.imag()*ci.imag(); @@ -159,16 +183,23 @@ double MagAGC::feedAndGetValue(const Complex& ci) if (m_count < m_moving_average.historySize()) { - if (m_stepCounter < 480) { - m_stepCounter++; + m_stepDownCounter = m_stepLength; + + if (m_stepUpCounter < m_stepLength) { + m_stepUpCounter++; } - return m_u0 * StepFunctions::smootherstep(m_stepCounter/480.0); + return m_u0 * StepFunctions::smootherstep(m_stepUpCounter/m_stepLength); } else { - m_stepCounter = 0; - return 0.0; + m_stepUpCounter = 0; + + if (m_stepDownCounter > 0) { + m_stepDownCounter--; + } + + return m_u0 * StepFunctions::smootherstep(m_stepDownCounter/m_stepLength); } //return (m_count < m_moving_average.historySize()) ? m_u0 : 0.0; diff --git a/sdrbase/dsp/agc.h b/sdrbase/dsp/agc.h index 61bb74c77..c07f2f487 100644 --- a/sdrbase/dsp/agc.h +++ b/sdrbase/dsp/agc.h @@ -34,6 +34,7 @@ class MagSquaredAGC : public AGC public: MagSquaredAGC(int historySize, double R, double threshold); virtual ~MagSquaredAGC(); + void resize(int historySize, Real R); virtual void feed(Complex& ci); double feedAndGetValue(const Complex& ci); double getMagSq() const { return m_magsq; } @@ -41,10 +42,12 @@ public: void setGate(int gate) { m_gate = gate; } private: double m_magsq; - double m_threshold; //!< squelch on magsq average with transition from +3dB - int m_gate; - int m_stepCounter; - int m_gateCounter; + double m_threshold; //!< squelch on magsq average + int m_gate; //!< power threshold gate in number of samples + int m_stepLength; //!< transition step length in number of samples + int m_stepUpCounter; //!< step up transition samples counter + int m_stepDownCounter; //!< step down transition samples counter + int m_gateCounter; //!< threshold gate samples counter }; class MagAGC : public AGC @@ -52,6 +55,7 @@ class MagAGC : public AGC public: MagAGC(int historySize, double R, double threshold); virtual ~MagAGC(); + void resize(int historySize, Real R); virtual void feed(Complex& ci); double feedAndGetValue(const Complex& ci); Real getMagSq() const { return m_magsq; } @@ -59,10 +63,12 @@ public: void setGate(int gate) { m_gate = gate; } private: double m_magsq; - double m_threshold; //!< squelch on magsq average - int m_gate; - int m_stepCounter; - int m_gateCounter; + double m_threshold; //!< squelch on magsq average + int m_gate; //!< power threshold gate in number of samples + int m_stepLength; //!< transition step length in number of samples + int m_stepUpCounter; //!< step up transition samples counter + int m_stepDownCounter; //!< step down transition samples counter + int m_gateCounter; //!< threshold gate samples counter }; class AlphaAGC : public AGC