From 94704ab7b22cddf36288953ad1a84a780cc8dccf Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 25 Jul 2017 00:58:16 +0200 Subject: [PATCH] SSB demod: implemented basic AGC not optional --- debian/changelog | 6 ++++++ plugins/channelrx/demodnfm/nfmdemod.cpp | 2 -- plugins/channelrx/demodnfm/nfmdemod.h | 1 - plugins/channelrx/demodssb/ssbdemod.cpp | 13 ++++++++----- plugins/channelrx/demodssb/ssbdemod.h | 2 ++ plugins/channelrx/demodssb/ssbplugin.cpp | 2 +- sdrbase/dsp/agc.cpp | 24 ++++++++++++++++++++---- sdrbase/dsp/agc.h | 18 +++++++++++------- sdrbase/gui/aboutdialog.ui | 2 +- sdrbase/mainwindow.cpp | 4 ++-- 10 files changed, 51 insertions(+), 23 deletions(-) diff --git a/debian/changelog b/debian/changelog index 6ce5d4c87..36bc58989 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +sdrangel (3.5.3-1) unstable; urgency=medium + + * SSB demod: anded optional AGC + + -- Edouard Griffiths, F4EXB Sat, 28 Jul 2017 09:14:18 +0200 + sdrangel (3.5.2-1) unstable; urgency=medium * HackRF: stop Rx before start Tx automatically and vice versa diff --git a/plugins/channelrx/demodnfm/nfmdemod.cpp b/plugins/channelrx/demodnfm/nfmdemod.cpp index 9096ccd66..d5c20147a 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.cpp +++ b/plugins/channelrx/demodnfm/nfmdemod.cpp @@ -43,7 +43,6 @@ NFMDemod::NFMDemod() : m_magsqSum(0.0f), m_magsqPeak(0.0f), m_magsqCount(0), - m_AGC(40, 0), m_movingAverage(40, 0), m_afSquelch(2, afSqTones), m_fmExcursion(2400), @@ -71,7 +70,6 @@ NFMDemod::NFMDemod() : m_audioBufferFill = 0; m_agcLevel = 1.0; - m_AGC.resize(m_squelchGate, m_agcLevel); m_movingAverage.resize(32, 0); m_ctcssDetector.setCoefficients(3000, 6000.0); // 0.5s / 2 Hz resolution diff --git a/plugins/channelrx/demodnfm/nfmdemod.h b/plugins/channelrx/demodnfm/nfmdemod.h index 871e9ccca..77367717e 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.h +++ b/plugins/channelrx/demodnfm/nfmdemod.h @@ -231,7 +231,6 @@ private: Real m_lastArgument; //Complex m_m1Sample; //Complex m_m2Sample; - MagAGC m_AGC; MovingAverage m_movingAverage; AFSquelch m_afSquelch; Real m_agcLevel; // AGC will aim to this level diff --git a/plugins/channelrx/demodssb/ssbdemod.cpp b/plugins/channelrx/demodssb/ssbdemod.cpp index e2d594af4..f9262defd 100644 --- a/plugins/channelrx/demodssb/ssbdemod.cpp +++ b/plugins/channelrx/demodssb/ssbdemod.cpp @@ -32,6 +32,7 @@ SSBDemod::SSBDemod(BasebandSampleSink* sampleSink) : m_audioFlipChannels(false), m_dsb(false), m_audioMute(false), + m_agc(12000, 4.0, 1e-2), m_sampleSink(sampleSink), m_audioFifo(4, 24000), m_settingsMutex(QMutex::Recursive) @@ -166,23 +167,25 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto } else { + double agcVal = m_agc.feedAndGetValue(sideband[i]); + if (m_audioBinaual) { if (m_audioFlipChannels) { - m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].imag() * m_volume * 100); - m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].real() * m_volume * 100); + m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].imag() * m_volume * agcVal * 100); + m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].real() * m_volume * agcVal * 100); } else { - m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].real() * m_volume * 100); - m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].imag() * m_volume * 100); + m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].real() * m_volume * agcVal * 100); + m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].imag() * m_volume * agcVal * 100); } } else { Real demod = (sideband[i].real() + sideband[i].imag()) * 0.7; - qint16 sample = (qint16)(demod * m_volume * 100); + qint16 sample = (qint16)(demod * m_volume * agcVal * 100); m_audioBuffer[m_audioBufferFill].l = sample; m_audioBuffer[m_audioBufferFill].r = sample; } diff --git a/plugins/channelrx/demodssb/ssbdemod.h b/plugins/channelrx/demodssb/ssbdemod.h index 9b8c402d2..80a2ee004 100644 --- a/plugins/channelrx/demodssb/ssbdemod.h +++ b/plugins/channelrx/demodssb/ssbdemod.h @@ -24,6 +24,7 @@ #include "dsp/ncof.h" #include "dsp/interpolator.h" #include "dsp/fftfilt.h" +#include "dsp/agc.h" #include "audio/audiofifo.h" #include "util/message.h" @@ -142,6 +143,7 @@ private: double m_magsqSum; double m_magsqPeak; int m_magsqCount; + MagAGC m_agc; NCOF m_nco; Interpolator m_interpolator; diff --git a/plugins/channelrx/demodssb/ssbplugin.cpp b/plugins/channelrx/demodssb/ssbplugin.cpp index 3c1a4e988..4744acc10 100644 --- a/plugins/channelrx/demodssb/ssbplugin.cpp +++ b/plugins/channelrx/demodssb/ssbplugin.cpp @@ -7,7 +7,7 @@ const PluginDescriptor SSBPlugin::m_pluginDescriptor = { QString("SSB Demodulator"), - QString("3.5.2"), + QString("3.5.3"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/sdrbase/dsp/agc.cpp b/sdrbase/dsp/agc.cpp index 9c767ee5b..acb731910 100644 --- a/sdrbase/dsp/agc.cpp +++ b/sdrbase/dsp/agc.cpp @@ -42,9 +42,10 @@ Real AGC::getAverage() // m_magsq(0.0) //{} -MagSquaredAGC::MagSquaredAGC(int historySize, Real R) : +MagSquaredAGC::MagSquaredAGC(int historySize, double R, double threshold) : AGC(historySize, R), - m_magsq(0.0) + m_magsq(0.0), + m_threshold(threshold) {} MagSquaredAGC::~MagSquaredAGC() @@ -58,15 +59,23 @@ void MagSquaredAGC::feed(Complex& ci) ci *= m_u0; } +double MagSquaredAGC::feedAndGetValue(const Complex& ci) +{ + m_magsq = ci.real()*ci.real() + ci.imag()*ci.imag(); + m_moving_average.feed(m_magsq); + m_u0 = m_R / m_moving_average.average(); + return m_magsq > m_threshold ? m_u0 : 1.0; +} //MagAGC::MagAGC() : // AGC(), // m_magsq(0.0) //{} -MagAGC::MagAGC(int historySize, Real R) : +MagAGC::MagAGC(int historySize, double R, double threshold) : AGC(historySize, R), - m_magsq(0.0) + m_magsq(0.0), + m_threshold(threshold) {} MagAGC::~MagAGC() @@ -80,6 +89,13 @@ void MagAGC::feed(Complex& ci) ci *= m_u0; } +double MagAGC::feedAndGetValue(const Complex& ci) +{ + m_magsq = ci.real()*ci.real() + ci.imag()*ci.imag(); + m_moving_average.feed(m_magsq); + m_u0 = m_R / sqrt(m_moving_average.average()); + return m_magsq > m_threshold ? m_u0 : 1.0; +} //AlphaAGC::AlphaAGC() : // AGC(), diff --git a/sdrbase/dsp/agc.h b/sdrbase/dsp/agc.h index 52f0d2011..1556ea025 100644 --- a/sdrbase/dsp/agc.h +++ b/sdrbase/dsp/agc.h @@ -22,8 +22,8 @@ public: virtual void feed(Complex& ci) = 0; protected: - Real m_u0; - Real m_R; // objective mag + double m_u0; + double m_R; // objective mag MovingAverage m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC. int m_historySize; int m_count; @@ -32,23 +32,27 @@ protected: class MagSquaredAGC : public AGC { public: - MagSquaredAGC(int historySize, Real R); + MagSquaredAGC(int historySize, double R, double threshold); virtual ~MagSquaredAGC(); virtual void feed(Complex& ci); - Real getMagSq() const { return m_magsq; } + double feedAndGetValue(const Complex& ci); + double getMagSq() const { return m_magsq; } private: - Real m_magsq; + double m_magsq; + double m_threshold; }; class MagAGC : public AGC { public: - MagAGC(int historySize, Real R); + MagAGC(int historySize, double R, double threshold); virtual ~MagAGC(); virtual void feed(Complex& ci); + double feedAndGetValue(const Complex& ci); Real getMagSq() const { return m_magsq; } private: - Real m_magsq; + double m_magsq; + double m_threshold; }; class AlphaAGC : public AGC diff --git a/sdrbase/gui/aboutdialog.ui b/sdrbase/gui/aboutdialog.ui index 535c19415..dc4207b5d 100644 --- a/sdrbase/gui/aboutdialog.ui +++ b/sdrbase/gui/aboutdialog.ui @@ -84,7 +84,7 @@ - <html><head/><body><p>Version 3.5.2 - Copyright (C) 2015-2017 Edouard Griffiths, F4EXB. </p><p>Code at <a href="https://github.com/f4exb/sdrangel"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/f4exb/sdrangel</span></a></p><p>Many thanks to the original developers:</p><p>The osmocom developer team - especially horizon, Hoernchen &amp; tnt.</p><p>Christian Daniel from maintech GmbH.</p><p>John Greb (hexameron) for the contributions in <a href="https://github.com/hexameron/rtl-sdrangelove"><span style=" text-decoration: underline; color:#0000ff;">RTL-SDRangelove</span></a></p><p>The following rules apply to the SDRangel main application and libsdrbase:<br/>This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have received a copy of the GNU General Public License along with this program. If not, see <a href="http://www.gnu.org/licenses/"><span style=" text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a>.</p><p>For the license of installed plugins, look into the plugin list.</p></body></html> + <html><head/><body><p>Version 3.5.3 - Copyright (C) 2015-2017 Edouard Griffiths, F4EXB. </p><p>Code at <a href="https://github.com/f4exb/sdrangel"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/f4exb/sdrangel</span></a></p><p>Many thanks to the original developers:</p><p>The osmocom developer team - especially horizon, Hoernchen &amp; tnt.</p><p>Christian Daniel from maintech GmbH.</p><p>John Greb (hexameron) for the contributions in <a href="https://github.com/hexameron/rtl-sdrangelove"><span style=" text-decoration: underline; color:#0000ff;">RTL-SDRangelove</span></a></p><p>The following rules apply to the SDRangel main application and libsdrbase:<br/>This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have received a copy of the GNU General Public License along with this program. If not, see <a href="http://www.gnu.org/licenses/"><span style=" text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses/</span></a>.</p><p>For the license of installed plugins, look into the plugin list.</p></body></html> true diff --git a/sdrbase/mainwindow.cpp b/sdrbase/mainwindow.cpp index 2378515fd..51c07f9c5 100644 --- a/sdrbase/mainwindow.cpp +++ b/sdrbase/mainwindow.cpp @@ -455,9 +455,9 @@ void MainWindow::createStatusBar() { QString qtVersionStr = QString("Qt %1 ").arg(QT_VERSION_STR); #if QT_VERSION >= 0x050400 - m_showSystemWidget = new QLabel("SDRangel v3.5.2 " + qtVersionStr + QSysInfo::prettyProductName(), this); + m_showSystemWidget = new QLabel("SDRangel v3.5.3 " + qtVersionStr + QSysInfo::prettyProductName(), this); #else - m_showSystemWidget = new QLabel("SDRangel v3.5.2 " + qtVersionStr, this); + m_showSystemWidget = new QLabel("SDRangel v3.5.3 " + qtVersionStr, this); #endif statusBar()->addPermanentWidget(m_showSystemWidget);