SSB demod: implemented basic AGC not optional

This commit is contained in:
f4exb 2017-07-25 00:58:16 +02:00
parent 0ad14d3acf
commit 94704ab7b2
10 changed files with 51 additions and 23 deletions

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
sdrangel (3.5.3-1) unstable; urgency=medium
* SSB demod: anded optional AGC
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> 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

View File

@ -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

View File

@ -231,7 +231,6 @@ private:
Real m_lastArgument;
//Complex m_m1Sample;
//Complex m_m2Sample;
MagAGC m_AGC;
MovingAverage<double> m_movingAverage;
AFSquelch m_afSquelch;
Real m_agcLevel; // AGC will aim to this level

View File

@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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(),

View File

@ -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<double> 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

View File

@ -84,7 +84,7 @@
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Version 3.5.2 - Copyright (C) 2015-2017 Edouard Griffiths, F4EXB. &lt;/p&gt;&lt;p&gt;Code at &lt;a href=&quot;https://github.com/f4exb/sdrangel&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com/f4exb/sdrangel&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Many thanks to the original developers:&lt;/p&gt;&lt;p&gt;The osmocom developer team - especially horizon, Hoernchen &amp;amp; tnt.&lt;/p&gt;&lt;p&gt;Christian Daniel from maintech GmbH.&lt;/p&gt;&lt;p&gt;John Greb (hexameron) for the contributions in &lt;a href=&quot;https://github.com/hexameron/rtl-sdrangelove&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;RTL-SDRangelove&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The following rules apply to the SDRangel main application and libsdrbase:&lt;br/&gt;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 &lt;a href=&quot;http://www.gnu.org/licenses/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://www.gnu.org/licenses/&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;For the license of installed plugins, look into the plugin list.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Version 3.5.3 - Copyright (C) 2015-2017 Edouard Griffiths, F4EXB. &lt;/p&gt;&lt;p&gt;Code at &lt;a href=&quot;https://github.com/f4exb/sdrangel&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;https://github.com/f4exb/sdrangel&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Many thanks to the original developers:&lt;/p&gt;&lt;p&gt;The osmocom developer team - especially horizon, Hoernchen &amp;amp; tnt.&lt;/p&gt;&lt;p&gt;Christian Daniel from maintech GmbH.&lt;/p&gt;&lt;p&gt;John Greb (hexameron) for the contributions in &lt;a href=&quot;https://github.com/hexameron/rtl-sdrangelove&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;RTL-SDRangelove&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The following rules apply to the SDRangel main application and libsdrbase:&lt;br/&gt;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 &lt;a href=&quot;http://www.gnu.org/licenses/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://www.gnu.org/licenses/&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;For the license of installed plugins, look into the plugin list.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>

View File

@ -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);