From 3cdccd2cd00cca39356ac1dac5774f9831d17a66 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sat, 20 Jun 2015 09:28:57 +0200 Subject: [PATCH] Changed AGC to enhanced NFM squelch --- include-gpl/dsp/agc.h | 116 ++++++++++++++++++++++++++++++- include-gpl/dsp/movingaverage.h | 24 +++---- plugins/channel/am/amdemod.h | 2 +- plugins/channel/nfm/nfmdemod.cpp | 13 ++-- plugins/channel/nfm/nfmdemod.h | 4 +- plugins/channel/wfm/wfmdemod.h | 2 +- sdrbase/dsp/afsquelch.cpp | 4 +- 7 files changed, 141 insertions(+), 24 deletions(-) diff --git a/include-gpl/dsp/agc.h b/include-gpl/dsp/agc.h index 698683e42..7afd4122c 100644 --- a/include-gpl/dsp/agc.h +++ b/include-gpl/dsp/agc.h @@ -71,7 +71,121 @@ private: Real m_fill; // refill average at this level Real m_cutoff; // consider samples only above this level Real m_clip; // never go below this level - MovingAverage m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC. + MovingAverage m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC. +}; + + +class EvenSimplerAGC +{ +public: + + EvenSimplerAGC() : + m_u0(1.0), + m_R(1.0), + m_moving_average() + {} + + EvenSimplerAGC(int historySize, Real R) : + m_u0(1.0), + m_R(R), + m_moving_average(historySize, m_R) + {} + + void resize(int historySize, Real R) + { + m_R = R; + m_moving_average.resize(historySize, R); + } + + Real getValue() + { + return m_u0; + } + + void feed(Complex& ci) + { + ci *= m_u0; + Real magsq = ci.real()*ci.real() + ci.imag()*ci.imag(); + m_moving_average.feed(magsq); + m_u0 = m_R / m_moving_average.average(); + } + + void close() + { + m_moving_average.fill(m_R); + m_u0 = 1.0; + } + +private: + Real m_u0; + Real m_R; // objective magsq + MovingAverage m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC. +}; + +class AlphaAGC +{ +public: + + AlphaAGC() : + m_u0(1.0), + m_R(1.0), + m_alpha(0.1), + m_squelch(false), + m_moving_average() + {} + + AlphaAGC(int historySize, Real R, Real alpha) : + m_u0(1.0), + m_R(R), + m_alpha(alpha), + m_squelch(false), + m_moving_average(historySize, m_R) + {} + + void resize(int historySize, Real R, Real alpha) + { + m_R = R; + m_alpha = alpha; + m_squelch = false; + m_moving_average.resize(historySize, R); + } + + Real getValue() + { + return m_u0; + } + + void feed(Complex& ci) + { + ci *= m_u0; + Real magsq = ci.real()*ci.real() + ci.imag()*ci.imag(); + + if (m_squelch && (magsq < m_moving_average.average())) + { + m_moving_average.feed(m_moving_average.average() - m_alpha*(m_moving_average.average() - magsq)); + } + else + { + m_squelch = true; + m_moving_average.feed(magsq); + } + + m_u0 = m_R / m_moving_average.average(); + } + + void close() + { + m_moving_average.fill(m_R); + m_u0 = 1.0; + m_squelch = false; + } + +private: + Real m_u0; + Real m_R; // objective magsq + Real m_alpha; + bool m_squelch; + MovingAverage m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC. }; diff --git a/include-gpl/dsp/movingaverage.h b/include-gpl/dsp/movingaverage.h index 38ae278a4..545d46608 100644 --- a/include-gpl/dsp/movingaverage.h +++ b/include-gpl/dsp/movingaverage.h @@ -4,7 +4,7 @@ #include #include "dsp/dsptypes.h" -class MovingAverage { +template class MovingAverage { public: MovingAverage() : m_history(), @@ -13,23 +13,23 @@ public: { } - MovingAverage(int historySize, Real initial) : + MovingAverage(int historySize, Type initial) : m_history(historySize, initial), - m_sum(historySize * initial), + m_sum((float) historySize * initial), m_ptr(0) { } - void resize(int historySize, Real initial) + void resize(int historySize, Type initial) { m_history.resize(historySize); for(size_t i = 0; i < m_history.size(); i++) m_history[i] = initial; - m_sum = m_history.size() * initial; + m_sum = (float) m_history.size() * initial; m_ptr = 0; } - void feed(Real value) + void feed(Type value) { m_sum -= m_history[m_ptr]; m_history[m_ptr] = value; @@ -39,21 +39,21 @@ public: m_ptr = 0; } - void fill(Real value) + void fill(Type value) { for(size_t i = 0; i < m_history.size(); i++) m_history[i] = value; - m_sum = m_history.size() * value; + m_sum = (float) m_history.size() * value; } - Real average() const + Type average() const { - return m_sum / (Real)m_history.size(); + return m_sum / (float) m_history.size(); } protected: - std::vector m_history; - Real m_sum; + std::vector m_history; + Type m_sum; uint m_ptr; }; diff --git a/plugins/channel/am/amdemod.h b/plugins/channel/am/amdemod.h index c1a4663a9..7c068b5a6 100644 --- a/plugins/channel/am/amdemod.h +++ b/plugins/channel/am/amdemod.h @@ -117,7 +117,7 @@ private: Real m_lastArgument; Complex m_lastSample; - MovingAverage m_movingAverage; + MovingAverage m_movingAverage; SimpleAGC m_volumeAGC; AudioVector m_audioBuffer; diff --git a/plugins/channel/nfm/nfmdemod.cpp b/plugins/channel/nfm/nfmdemod.cpp index 33d37ef39..d8afc55f7 100644 --- a/plugins/channel/nfm/nfmdemod.cpp +++ b/plugins/channel/nfm/nfmdemod.cpp @@ -26,7 +26,7 @@ #include -static const Real afSqTones[2] = {2000.0, 8000.0}; +static const Real afSqTones[2] = {1200.0, 8000.0}; MESSAGE_CLASS_DEFINITION(NFMDemod::MsgConfigureNFMDemod, Message) @@ -53,10 +53,11 @@ NFMDemod::NFMDemod(AudioFifo* audioFifo, SampleSink* sampleSink) : m_movingAverage.resize(16, 0); m_agcLevel = 0.003; - m_AGC.resize(4096, m_agcLevel, 0, 0.1*m_agcLevel); + //m_AGC.resize(480, m_agcLevel, 0, 0.1*m_agcLevel); + m_AGC.resize(240, m_agcLevel*m_agcLevel, 0.1); m_ctcssDetector.setCoefficients(3000, 6000.0); // 0.5s / 2 Hz resolution - m_afSquelch.setCoefficients(24, 48000.0, 1, 1); // 4000 Hz span, 250us + m_afSquelch.setCoefficients(24, 48000.0, 5, 1); // 4000 Hz span, 250us m_afSquelch.setThreshold(0.001); } @@ -117,8 +118,10 @@ void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iter qint16 sample; - m_AGC.feed(abs(ci)); - ci *= (m_agcLevel / m_AGC.getValue()); + //m_AGC.feed(abs(ci)); + //ci *= (m_agcLevel / m_AGC.getValue()); + + m_AGC.feed(ci); // demod /* diff --git a/plugins/channel/nfm/nfmdemod.h b/plugins/channel/nfm/nfmdemod.h index 71bbba7c1..305f60ab5 100644 --- a/plugins/channel/nfm/nfmdemod.h +++ b/plugins/channel/nfm/nfmdemod.h @@ -145,8 +145,8 @@ private: Real m_lastArgument; Complex m_m1Sample; Complex m_m2Sample; - MovingAverage m_movingAverage; - SimpleAGC m_AGC; + MovingAverage m_movingAverage; + AlphaAGC m_AGC; Real m_agcLevel; // AGC will aim to this level Real m_agcFloor; // AGC will not go below this level diff --git a/plugins/channel/wfm/wfmdemod.h b/plugins/channel/wfm/wfmdemod.h index 585438871..e0450ebf4 100644 --- a/plugins/channel/wfm/wfmdemod.h +++ b/plugins/channel/wfm/wfmdemod.h @@ -122,7 +122,7 @@ private: Real m_lastArgument; Complex m_m1Sample; // x^-1 sample Complex m_m2Sample; // x^-1 sample - MovingAverage m_movingAverage; + MovingAverage m_movingAverage; AudioVector m_audioBuffer; uint m_audioBufferFill; diff --git a/sdrbase/dsp/afsquelch.cpp b/sdrbase/dsp/afsquelch.cpp index 77f1b95c8..91568f2ec 100644 --- a/sdrbase/dsp/afsquelch.cpp +++ b/sdrbase/dsp/afsquelch.cpp @@ -189,7 +189,7 @@ void AFSquelch::evaluate() if (open) { - if (attackCount < samplesAttack) + if (samplesAttack && (attackCount < samplesAttack)) { attackCount++; } @@ -201,7 +201,7 @@ void AFSquelch::evaluate() } else { - if (decayCount < samplesDecay) + if (samplesDecay && (decayCount < samplesDecay)) { decayCount++; }