1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-02-03 09:44:01 -05:00

DSD demod plugin: removed AGC

This commit is contained in:
f4exb 2016-04-09 04:02:18 +02:00
parent 97b60ccb87
commit fd26ec52d5
4 changed files with 15 additions and 24 deletions

View File

@ -108,7 +108,7 @@ int getSymbol(dsd_opts * opts, dsd_state * state, int have_sync)
if (state->output_num_samples > state->output_length) if (state->output_num_samples > state->output_length)
{ {
fprintf(stderr, "WARNING: audio buffer over-run! Truncating output"); fprintf(stderr, "WARNING: audio buffer over-run! Truncating output\n");
state->output_num_samples = state->output_length; state->output_num_samples = state->output_length;
} }

View File

@ -33,9 +33,7 @@ MESSAGE_CLASS_DEFINITION(DSDDemod::MsgConfigureDSDDemod, Message)
DSDDemod::DSDDemod(SampleSink* sampleSink) : DSDDemod::DSDDemod(SampleSink* sampleSink) :
m_sampleCount(0), m_sampleCount(0),
m_squelchCount(0), m_squelchCount(0),
m_agcAttack(2400),
m_squelchOpen(false), m_squelchOpen(false),
m_afSquelch(2, afSqTones),
m_audioFifo(4, 48000), m_audioFifo(4, 48000),
m_fmExcursion(24), m_fmExcursion(24),
m_settingsMutex(QMutex::Recursive), m_settingsMutex(QMutex::Recursive),
@ -64,10 +62,7 @@ DSDDemod::DSDDemod(SampleSink* sampleSink) :
m_audioBuffer.resize(1<<14); m_audioBuffer.resize(1<<14);
m_audioBufferFill = 0; m_audioBufferFill = 0;
m_agcLevel = 1.0; m_movingAverage.resize(16, 0);
m_AGC.resize(m_agcAttack, m_agcLevel);
m_afSquelch.setCoefficients(24, 600, 48000.0, 200, 0); // 4000 Hz span, 250us, 100ms attack
DSPEngine::instance()->addAudioSink(&m_audioFifo); DSPEngine::instance()->addAudioSink(&m_audioFifo);
} }
@ -113,19 +108,19 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
{ {
if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci)) if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci))
{ {
qint16 sample; qint16 sample;
m_AGC.feed(ci); m_magsq = ((ci.real()*ci.real() + ci.imag()*ci.imag())) / (Real) (1<<30);
m_movingAverage.feed(m_magsq);
Real demod = 32768.0f * m_phaseDiscri.phaseDiscriminator(ci) * ((float) m_running.m_demodGain / 100.0f); Real demod = 32768.0f * m_phaseDiscri.phaseDiscriminator(ci) * ((float) m_running.m_demodGain / 100.0f);
m_sampleCount++; m_sampleCount++;
// AF processing // AF processing
if (getMag() > m_squelchLevel) if (getMagSq() > m_squelchLevel)
{ {
if (m_squelchCount < m_agcAttack) if (m_squelchCount < m_squelchGate)
{ {
m_squelchCount++; m_squelchCount++;
} }
@ -135,7 +130,7 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
m_squelchCount = 0; m_squelchCount = 0;
} }
m_squelchOpen = m_squelchCount == m_agcAttack; // wait for AGC to stabilize m_squelchOpen = m_squelchCount == m_squelchGate;
if (m_squelchOpen) if (m_squelchOpen)
{ {
@ -291,16 +286,14 @@ void DSDDemod::apply()
if (m_config.m_squelchGate != m_running.m_squelchGate) if (m_config.m_squelchGate != m_running.m_squelchGate)
{ {
m_agcAttack = 480 * m_config.m_squelchGate; // gate is given in 10s of ms at 48000 Hz audio sample rate m_squelchGate = 480 * m_config.m_squelchGate; // gate is given in 10s of ms at 48000 Hz audio sample rate
m_AGC.resize(m_agcAttack, m_agcLevel);
} }
if (m_config.m_squelch != m_running.m_squelch) if (m_config.m_squelch != m_running.m_squelch)
{ {
// input is a value in tenths of dB // input is a value in tenths of dB
m_squelchLevel = std::pow(10.0, m_config.m_squelch / 200.0); m_squelchLevel = std::pow(10.0, m_config.m_squelch / 100.0);
//m_squelchLevel *= m_squelchLevel; //m_squelchLevel *= m_squelchLevel;
m_afSquelch.setThreshold(m_squelchLevel);
} }
m_running.m_inputSampleRate = m_config.m_inputSampleRate; m_running.m_inputSampleRate = m_config.m_inputSampleRate;

View File

@ -27,7 +27,7 @@
#include "dsp/lowpass.h" #include "dsp/lowpass.h"
#include "dsp/bandpass.h" #include "dsp/bandpass.h"
#include "dsp/afsquelch.h" #include "dsp/afsquelch.h"
#include "dsp/agc.h" #include "dsp/movingaverage.h"
#include "dsp/afsquelch.h" #include "dsp/afsquelch.h"
#include "audio/audiofifo.h" #include "audio/audiofifo.h"
#include "util/message.h" #include "util/message.h"
@ -58,7 +58,7 @@ public:
m_dsdDemodGUI = dsdDemodGUI; m_dsdDemodGUI = dsdDemodGUI;
} }
Real getMag() { return m_AGC.getAverage() / (1<<15); } Real getMagSq() { return m_magsq; }
bool getSquelchOpen() const { return m_squelchOpen; } bool getSquelchOpen() const { return m_squelchOpen; }
private: private:
@ -158,16 +158,14 @@ private:
Real m_interpolatorDistanceRemain; Real m_interpolatorDistanceRemain;
int m_sampleCount; int m_sampleCount;
int m_squelchCount; int m_squelchCount;
int m_agcAttack; int m_squelchGate;
double m_squelchLevel; double m_squelchLevel;
bool m_squelchOpen; bool m_squelchOpen;
Real m_lastArgument; Real m_lastArgument;
MagAGC m_AGC; MovingAverage<Real> m_movingAverage;
AFSquelch m_afSquelch; Real m_magsq;
Real m_agcLevel; // AGC will aim to this level
Real m_agcFloor; // AGC will not go below this level
Real m_fmExcursion; Real m_fmExcursion;

View File

@ -354,7 +354,7 @@ void DSDDemodGUI::blockApplySettings(bool block)
void DSDDemodGUI::tick() void DSDDemodGUI::tick()
{ {
Real powDb = CalcDb::dbPower(m_dsdDemod->getMag()) * 2; Real powDb = CalcDb::dbPower(m_dsdDemod->getMagSq());
m_channelPowerDbAvg.feed(powDb); m_channelPowerDbAvg.feed(powDb);
ui->channelPower->setText(QString::number(m_channelPowerDbAvg.average(), 'f', 1)); ui->channelPower->setText(QString::number(m_channelPowerDbAvg.average(), 'f', 1));
bool squelchOpen = m_dsdDemod->getSquelchOpen(); bool squelchOpen = m_dsdDemod->getSquelchOpen();