1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-12-23 01:55:48 -05:00

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 sdrangel (3.5.2-1) unstable; urgency=medium
* HackRF: stop Rx before start Tx automatically and vice versa * HackRF: stop Rx before start Tx automatically and vice versa

View File

@ -43,7 +43,6 @@ NFMDemod::NFMDemod() :
m_magsqSum(0.0f), m_magsqSum(0.0f),
m_magsqPeak(0.0f), m_magsqPeak(0.0f),
m_magsqCount(0), m_magsqCount(0),
m_AGC(40, 0),
m_movingAverage(40, 0), m_movingAverage(40, 0),
m_afSquelch(2, afSqTones), m_afSquelch(2, afSqTones),
m_fmExcursion(2400), m_fmExcursion(2400),
@ -71,7 +70,6 @@ NFMDemod::NFMDemod() :
m_audioBufferFill = 0; m_audioBufferFill = 0;
m_agcLevel = 1.0; m_agcLevel = 1.0;
m_AGC.resize(m_squelchGate, m_agcLevel);
m_movingAverage.resize(32, 0); m_movingAverage.resize(32, 0);
m_ctcssDetector.setCoefficients(3000, 6000.0); // 0.5s / 2 Hz resolution m_ctcssDetector.setCoefficients(3000, 6000.0); // 0.5s / 2 Hz resolution

View File

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

View File

@ -32,6 +32,7 @@ SSBDemod::SSBDemod(BasebandSampleSink* sampleSink) :
m_audioFlipChannels(false), m_audioFlipChannels(false),
m_dsb(false), m_dsb(false),
m_audioMute(false), m_audioMute(false),
m_agc(12000, 4.0, 1e-2),
m_sampleSink(sampleSink), m_sampleSink(sampleSink),
m_audioFifo(4, 24000), m_audioFifo(4, 24000),
m_settingsMutex(QMutex::Recursive) m_settingsMutex(QMutex::Recursive)
@ -166,23 +167,25 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
} }
else else
{ {
double agcVal = m_agc.feedAndGetValue(sideband[i]);
if (m_audioBinaual) if (m_audioBinaual)
{ {
if (m_audioFlipChannels) if (m_audioFlipChannels)
{ {
m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].imag() * 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 * 100); m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].real() * m_volume * agcVal * 100);
} }
else else
{ {
m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].real() * 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 * 100); m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].imag() * m_volume * agcVal * 100);
} }
} }
else else
{ {
Real demod = (sideband[i].real() + sideband[i].imag()) * 0.7; 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].l = sample;
m_audioBuffer[m_audioBufferFill].r = sample; m_audioBuffer[m_audioBufferFill].r = sample;
} }

View File

@ -24,6 +24,7 @@
#include "dsp/ncof.h" #include "dsp/ncof.h"
#include "dsp/interpolator.h" #include "dsp/interpolator.h"
#include "dsp/fftfilt.h" #include "dsp/fftfilt.h"
#include "dsp/agc.h"
#include "audio/audiofifo.h" #include "audio/audiofifo.h"
#include "util/message.h" #include "util/message.h"
@ -142,6 +143,7 @@ private:
double m_magsqSum; double m_magsqSum;
double m_magsqPeak; double m_magsqPeak;
int m_magsqCount; int m_magsqCount;
MagAGC m_agc;
NCOF m_nco; NCOF m_nco;
Interpolator m_interpolator; Interpolator m_interpolator;

View File

@ -7,7 +7,7 @@
const PluginDescriptor SSBPlugin::m_pluginDescriptor = { const PluginDescriptor SSBPlugin::m_pluginDescriptor = {
QString("SSB Demodulator"), QString("SSB Demodulator"),
QString("3.5.2"), QString("3.5.3"),
QString("(c) Edouard Griffiths, F4EXB"), QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"), QString("https://github.com/f4exb/sdrangel"),
true, true,

View File

@ -42,9 +42,10 @@ Real AGC::getAverage()
// m_magsq(0.0) // m_magsq(0.0)
//{} //{}
MagSquaredAGC::MagSquaredAGC(int historySize, Real R) : MagSquaredAGC::MagSquaredAGC(int historySize, double R, double threshold) :
AGC(historySize, R), AGC(historySize, R),
m_magsq(0.0) m_magsq(0.0),
m_threshold(threshold)
{} {}
MagSquaredAGC::~MagSquaredAGC() MagSquaredAGC::~MagSquaredAGC()
@ -58,15 +59,23 @@ void MagSquaredAGC::feed(Complex& ci)
ci *= m_u0; 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() : //MagAGC::MagAGC() :
// AGC(), // AGC(),
// m_magsq(0.0) // m_magsq(0.0)
//{} //{}
MagAGC::MagAGC(int historySize, Real R) : MagAGC::MagAGC(int historySize, double R, double threshold) :
AGC(historySize, R), AGC(historySize, R),
m_magsq(0.0) m_magsq(0.0),
m_threshold(threshold)
{} {}
MagAGC::~MagAGC() MagAGC::~MagAGC()
@ -80,6 +89,13 @@ void MagAGC::feed(Complex& ci)
ci *= m_u0; 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() : //AlphaAGC::AlphaAGC() :
// AGC(), // AGC(),

View File

@ -22,8 +22,8 @@ public:
virtual void feed(Complex& ci) = 0; virtual void feed(Complex& ci) = 0;
protected: protected:
Real m_u0; double m_u0;
Real m_R; // objective mag double m_R; // objective mag
MovingAverage<double> m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC. MovingAverage<double> m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC.
int m_historySize; int m_historySize;
int m_count; int m_count;
@ -32,23 +32,27 @@ protected:
class MagSquaredAGC : public AGC class MagSquaredAGC : public AGC
{ {
public: public:
MagSquaredAGC(int historySize, Real R); MagSquaredAGC(int historySize, double R, double threshold);
virtual ~MagSquaredAGC(); virtual ~MagSquaredAGC();
virtual void feed(Complex& ci); virtual void feed(Complex& ci);
Real getMagSq() const { return m_magsq; } double feedAndGetValue(const Complex& ci);
double getMagSq() const { return m_magsq; }
private: private:
Real m_magsq; double m_magsq;
double m_threshold;
}; };
class MagAGC : public AGC class MagAGC : public AGC
{ {
public: public:
MagAGC(int historySize, Real R); MagAGC(int historySize, double R, double threshold);
virtual ~MagAGC(); virtual ~MagAGC();
virtual void feed(Complex& ci); virtual void feed(Complex& ci);
double feedAndGetValue(const Complex& ci);
Real getMagSq() const { return m_magsq; } Real getMagSq() const { return m_magsq; }
private: private:
Real m_magsq; double m_magsq;
double m_threshold;
}; };
class AlphaAGC : public AGC class AlphaAGC : public AGC

View File

@ -84,7 +84,7 @@
<item> <item>
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <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>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>

View File

@ -455,9 +455,9 @@ void MainWindow::createStatusBar()
{ {
QString qtVersionStr = QString("Qt %1 ").arg(QT_VERSION_STR); QString qtVersionStr = QString("Qt %1 ").arg(QT_VERSION_STR);
#if QT_VERSION >= 0x050400 #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 #else
m_showSystemWidget = new QLabel("SDRangel v3.5.2 " + qtVersionStr, this); m_showSystemWidget = new QLabel("SDRangel v3.5.3 " + qtVersionStr, this);
#endif #endif
statusBar()->addPermanentWidget(m_showSystemWidget); statusBar()->addPermanentWidget(m_showSystemWidget);