SSB demod: use delay line to squeeze squelch tail

pull/177/head
f4exb 2018-04-22 09:37:34 +02:00
rodzic 4670cbaa33
commit 7e6267f41c
5 zmienionych plików z 31 dodań i 9 usunięć

Wyświetl plik

@ -51,6 +51,7 @@ SSBDemod::SSBDemod(DeviceSourceAPI *deviceAPI) :
m_agcNbSamples(12000),
m_agcPowerThreshold(1e-2),
m_agcThresholdGate(0),
m_squelchDelayLine(2*48000),
m_audioActive(false),
m_sampleSink(0),
m_audioFifo(24000),
@ -207,8 +208,10 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
m_sum.imag(0.0);
}
double agcVal = m_agcActive ? m_agc.feedAndGetValue(sideband[i]) : 10.0; // 10.0 for 3276.8, 1.0 for 327.68
m_audioActive = agcVal != 0.0;
float agcVal = m_agcActive ? m_agc.feedAndGetValue(sideband[i]) : 10.0; // 10.0 for 3276.8, 1.0 for 327.68
fftfilt::cmplx& delayedSample = m_squelchDelayLine.readBack(m_agc.getStepDownDelay());
m_audioActive = delayedSample.real() != 0.0;
m_squelchDelayLine.write(sideband[i]*agcVal);
if (m_audioMute)
{
@ -217,23 +220,25 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
}
else
{
fftfilt::cmplx z = delayedSample * m_agc.getStepDownValue();
if (m_audioBinaual)
{
if (m_audioFlipChannels)
{
m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].imag() * m_volume * agcVal);
m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].real() * m_volume * agcVal);
m_audioBuffer[m_audioBufferFill].r = (qint16)(z.imag() * m_volume);
m_audioBuffer[m_audioBufferFill].l = (qint16)(z.real() * m_volume);
}
else
{
m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].real() * m_volume * agcVal);
m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].imag() * m_volume * agcVal);
m_audioBuffer[m_audioBufferFill].r = (qint16)(z.real() * m_volume);
m_audioBuffer[m_audioBufferFill].l = (qint16)(z.imag() * m_volume);
}
}
else
{
Real demod = (sideband[i].real() + sideband[i].imag()) * 0.7;
qint16 sample = (qint16)(demod * m_volume * agcVal);
Real demod = (z.real() + z.imag()) * 0.7;
qint16 sample = (qint16)(demod * m_volume);
m_audioBuffer[m_audioBufferFill].l = sample;
m_audioBuffer[m_audioBufferFill].r = sample;
}

Wyświetl plik

@ -29,6 +29,7 @@
#include "dsp/agc.h"
#include "audio/audiofifo.h"
#include "util/message.h"
#include "util/doublebufferfifo.h"
#include "ssbdemodsettings.h"
@ -259,6 +260,7 @@ private:
int m_agcNbSamples; //!< number of audio (48 kHz) samples for AGC averaging
double m_agcPowerThreshold; //!< AGC power threshold (linear)
int m_agcThresholdGate; //!< Gate length in number of samples befor threshold triggers
DoubleBufferFIFO<fftfilt::cmplx> m_squelchDelayLine;
bool m_audioActive; //!< True if an audio signal is produced (no AGC or AGC and above threshold)
NCOF m_nco;

Wyświetl plik

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

Wyświetl plik

@ -176,3 +176,15 @@ double MagAGC::feedAndGetValue(const Complex& ci)
return m_u0;
}
}
float MagAGC::getStepDownValue() const
{
if (m_count < m_stepDownDelay)
{
return 1.0f;
}
else
{
return StepFunctions::smootherstep(m_stepDownCounter * m_stepDelta);
}
}

Wyświetl plik

@ -50,6 +50,9 @@ public:
void setStepDownDelay(int stepDownDelay) { m_stepDownDelay = stepDownDelay; }
void setClamping(bool clamping) { m_clamping = clamping; }
void setClampMax(double clampMax) { m_clampMax = clampMax; }
int getStepDownDelay() const { return m_stepDownDelay; }
float getStepDownValue() const;
private:
bool m_squared; //!< use squared magnitude (power) to compute AGC value
double m_magsq; //!< current squared magnitude (power)