SSB demod: remove AGC threshold (squelch) completely if level us fully turned down (-99 dB)

This commit is contained in:
f4exb 2017-07-27 10:50:41 +02:00
parent 7acc42436a
commit 86e52928d9
6 changed files with 99 additions and 54 deletions

View File

@ -318,6 +318,7 @@ bool SSBDemod::handleMessage(const Message& cmd)
m_agcActive = cfg.getAGC(); m_agcActive = cfg.getAGC();
int agcNbSamples = 48 * (1<<cfg.getAGCTimeLog2()); int agcNbSamples = 48 * (1<<cfg.getAGCTimeLog2());
m_agc.setThresholdEnable(cfg.getAGCPowerThershold() != -99);
double agcPowerThreshold = CalcDb::powerFromdB(cfg.getAGCPowerThershold()) * (1<<30); double agcPowerThreshold = CalcDb::powerFromdB(cfg.getAGCPowerThershold()) * (1<<30);
int agcThresholdGate = 48 * cfg.getAGCThersholdGate(); // ms int agcThresholdGate = 48 * cfg.getAGCThersholdGate(); // ms

View File

@ -61,6 +61,10 @@ void SSBDemodGUI::resetToDefaults()
ui->volume->setValue(40); ui->volume->setValue(40);
ui->deltaFrequency->setValue(0); ui->deltaFrequency->setValue(0);
ui->spanLog2->setValue(3); ui->spanLog2->setValue(3);
ui->agc->setChecked(false);
ui->agcTimeLog2->setValue(7);
ui->agcPowerThreshold->setValue(-40);
ui->agcThresholdGate->setValue(4);
blockApplySettings(false); blockApplySettings(false);
applySettings(); applySettings();
@ -133,11 +137,10 @@ bool SSBDemodGUI::deserialize(const QByteArray& data)
ui->agcTimeLog2->setValue(tmp); ui->agcTimeLog2->setValue(tmp);
QString s = QString::number((1<<tmp), 'f', 0); QString s = QString::number((1<<tmp), 'f', 0);
ui->agcTimeText->setText(s); ui->agcTimeText->setText(s);
d.readS32(13, &tmp, -20); d.readS32(13, &tmp, -40);
ui->agcPowerThreshold->setValue(tmp); ui->agcPowerThreshold->setValue(tmp);
s = QString::number(tmp, 'f', 0); displayAGCPowerThreshold(tmp);
ui->agcPowerThresholdText->setText(s); d.readS32(14, &tmp, 4);
d.readS32(14, &tmp, 5);
ui->agcThresholdGate->setValue(tmp); ui->agcThresholdGate->setValue(tmp);
s = QString::number(tmp, 'f', 0); s = QString::number(tmp, 'f', 0);
ui->agcThresholdGateText->setText(s); ui->agcThresholdGateText->setText(s);
@ -298,8 +301,7 @@ void SSBDemodGUI::on_agcTimeLog2_valueChanged(int value)
void SSBDemodGUI::on_agcPowerThreshold_valueChanged(int value) void SSBDemodGUI::on_agcPowerThreshold_valueChanged(int value)
{ {
QString s = QString::number(value, 'f', 0); displayAGCPowerThreshold(value);
ui->agcPowerThresholdText->setText(s);
applySettings(); applySettings();
} }
@ -522,6 +524,19 @@ void SSBDemodGUI::applySettings()
} }
} }
void SSBDemodGUI::displayAGCPowerThreshold(int value)
{
if (value == -99)
{
ui->agcPowerThresholdText->setText("---");
}
else
{
QString s = QString::number(value, 'f', 0);
ui->agcPowerThresholdText->setText(s);
}
}
void SSBDemodGUI::leaveEvent(QEvent*) void SSBDemodGUI::leaveEvent(QEvent*)
{ {
blockApplySettings(true); blockApplySettings(true);

View File

@ -88,6 +88,8 @@ private:
void blockApplySettings(bool block); void blockApplySettings(bool block);
void applySettings(); void applySettings();
void displayAGCPowerThreshold(int value);
void leaveEvent(QEvent*); void leaveEvent(QEvent*);
void enterEvent(QEvent*); void enterEvent(QEvent*);
}; };

View File

@ -533,7 +533,7 @@
<number>1</number> <number>1</number>
</property> </property>
<property name="value"> <property name="value">
<number>-50</number> <number>-40</number>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -49,6 +49,7 @@ 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), m_threshold(threshold),
m_thresholdEnable(true),
m_gate(0), m_gate(0),
m_stepLength(std::min(StepLengthMax, historySize/2)), m_stepLength(std::min(StepLengthMax, historySize/2)),
m_stepDelta(1.0/m_stepLength), m_stepDelta(1.0/m_stepLength),
@ -137,8 +138,10 @@ double MagSquaredAGC::feedAndGetValue(const Complex& ci)
MagAGC::MagAGC(int historySize, double R, double threshold) : MagAGC::MagAGC(int historySize, double R, double threshold) :
AGC(historySize, R), AGC(historySize, R),
m_squared(false),
m_magsq(0.0), m_magsq(0.0),
m_threshold(threshold), m_threshold(threshold),
m_thresholdEnable(true),
m_gate(0), m_gate(0),
m_stepLength(std::min(StepLengthMax, historySize/2)), m_stepLength(std::min(StepLengthMax, historySize/2)),
m_stepDelta(1.0/m_stepLength), m_stepDelta(1.0/m_stepLength),
@ -159,6 +162,17 @@ void MagAGC::resize(int historySize, Real R)
AGC::resize(historySize, R); AGC::resize(historySize, R);
} }
void MagAGC::setThresholdEnable(bool enable)
{
if (m_thresholdEnable != enable)
{
m_stepUpCounter = 0;
m_stepDownCounter = m_stepLength;
}
m_thresholdEnable = enable;
}
void MagAGC::feed(Complex& ci) void MagAGC::feed(Complex& ci)
{ {
ci *= feedAndGetValue(ci); ci *= feedAndGetValue(ci);
@ -168,55 +182,62 @@ double MagAGC::feedAndGetValue(const Complex& ci)
{ {
m_magsq = ci.real()*ci.real() + ci.imag()*ci.imag(); m_magsq = ci.real()*ci.real() + ci.imag()*ci.imag();
m_moving_average.feed(m_magsq); m_moving_average.feed(m_magsq);
m_u0 = m_R / sqrt(m_moving_average.average()); m_u0 = m_R / (m_squared ? m_moving_average.average() : sqrt(m_moving_average.average()));
if (m_magsq > m_threshold) if (m_thresholdEnable)
{ {
if (m_gateCounter < m_gate) if (m_magsq > m_threshold)
{ {
m_gateCounter++; if (m_gateCounter < m_gate)
{
m_gateCounter++;
}
else
{
m_count = 0;
}
} }
else else
{ {
m_count = 0; if (m_count < m_moving_average.historySize()) {
m_count++;
}
m_gateCounter = 0;
}
if (m_count < m_moving_average.historySize())
{
m_stepDownCounter = m_stepUpCounter;
if (m_stepUpCounter < m_stepLength)
{
m_stepUpCounter++;
return m_u0 * StepFunctions::smootherstep(m_stepUpCounter * m_stepDelta);
}
else
{
return m_u0;
}
}
else
{
m_stepUpCounter = m_stepDownCounter;
if (m_stepDownCounter > 0)
{
m_stepDownCounter--;
return m_u0 * StepFunctions::smootherstep(m_stepDownCounter * m_stepDelta);
}
else
{
return 0.0;
}
} }
} }
else else
{ {
if (m_count < m_moving_average.historySize()) { return m_u0;
m_count++;
}
m_gateCounter = 0;
}
if (m_count < m_moving_average.historySize())
{
m_stepDownCounter = m_stepUpCounter;
if (m_stepUpCounter < m_stepLength)
{
m_stepUpCounter++;
return m_u0 * StepFunctions::smootherstep(m_stepUpCounter * m_stepDelta);
}
else
{
return m_u0;
}
}
else
{
m_stepUpCounter = m_stepDownCounter;
if (m_stepDownCounter > 0)
{
m_stepDownCounter--;
return m_u0 * StepFunctions::smootherstep(m_stepDownCounter * m_stepDelta);
}
else
{
return 0.0;
}
} }
} }

View File

@ -39,16 +39,18 @@ public:
double feedAndGetValue(const Complex& ci); double feedAndGetValue(const Complex& ci);
double getMagSq() const { return m_magsq; } double getMagSq() const { return m_magsq; }
void setThreshold(double threshold) { m_threshold = threshold; } void setThreshold(double threshold) { m_threshold = threshold; }
void setThresholdEnable(bool enable) { m_thresholdEnable = enable; }
void setGate(int gate) { m_gate = gate; } void setGate(int gate) { m_gate = gate; }
private: private:
double m_magsq; double m_magsq;
double m_threshold; //!< squelch on magsq average double m_threshold; //!< squelch on magsq average
int m_gate; //!< power threshold gate in number of samples bool m_thresholdEnable; //!< enable squelch on power threshold
int m_stepLength; //!< transition step length in number of samples int m_gate; //!< power threshold gate in number of samples
double m_stepDelta; //!< transition step unit by sample int m_stepLength; //!< transition step length in number of samples
int m_stepUpCounter; //!< step up transition samples counter double m_stepDelta; //!< transition step unit by sample
int m_stepDownCounter; //!< step down transition samples counter int m_stepUpCounter; //!< step up transition samples counter
int m_gateCounter; //!< threshold gate samples counter int m_stepDownCounter; //!< step down transition samples counter
int m_gateCounter; //!< threshold gate samples counter
}; };
class MagAGC : public AGC class MagAGC : public AGC
@ -56,15 +58,19 @@ class MagAGC : public AGC
public: public:
MagAGC(int historySize, double R, double threshold); MagAGC(int historySize, double R, double threshold);
virtual ~MagAGC(); virtual ~MagAGC();
void setSquared(bool squared) { m_squared = squared; }
void resize(int historySize, Real R); void resize(int historySize, Real R);
virtual void feed(Complex& ci); virtual void feed(Complex& ci);
double feedAndGetValue(const Complex& ci); double feedAndGetValue(const Complex& ci);
Real getMagSq() const { return m_magsq; } Real getMagSq() const { return m_magsq; }
void setThreshold(double threshold) { m_threshold = threshold; } void setThreshold(double threshold) { m_threshold = threshold; }
void setThresholdEnable(bool enable);
void setGate(int gate) { m_gate = gate; } void setGate(int gate) { m_gate = gate; }
private: private:
double m_magsq; bool m_squared; //!< use squared magnitude (power) to compute AGC value
double m_magsq; //!< current squared magnitude (power)
double m_threshold; //!< squelch on magsq average double m_threshold; //!< squelch on magsq average
bool m_thresholdEnable; //!< enable squelch on power threshold
int m_gate; //!< power threshold gate in number of samples int m_gate; //!< power threshold gate in number of samples
int m_stepLength; //!< transition step length in number of samples int m_stepLength; //!< transition step length in number of samples
double m_stepDelta; //!< transition step unit by sample double m_stepDelta; //!< transition step unit by sample