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();
int agcNbSamples = 48 * (1<<cfg.getAGCTimeLog2());
m_agc.setThresholdEnable(cfg.getAGCPowerThershold() != -99);
double agcPowerThreshold = CalcDb::powerFromdB(cfg.getAGCPowerThershold()) * (1<<30);
int agcThresholdGate = 48 * cfg.getAGCThersholdGate(); // ms

View File

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

View File

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

View File

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

View File

@ -49,6 +49,7 @@ MagSquaredAGC::MagSquaredAGC(int historySize, double R, double threshold) :
AGC(historySize, R),
m_magsq(0.0),
m_threshold(threshold),
m_thresholdEnable(true),
m_gate(0),
m_stepLength(std::min(StepLengthMax, historySize/2)),
m_stepDelta(1.0/m_stepLength),
@ -137,8 +138,10 @@ double MagSquaredAGC::feedAndGetValue(const Complex& ci)
MagAGC::MagAGC(int historySize, double R, double threshold) :
AGC(historySize, R),
m_squared(false),
m_magsq(0.0),
m_threshold(threshold),
m_thresholdEnable(true),
m_gate(0),
m_stepLength(std::min(StepLengthMax, historySize/2)),
m_stepDelta(1.0/m_stepLength),
@ -159,6 +162,17 @@ void MagAGC::resize(int historySize, Real 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)
{
ci *= feedAndGetValue(ci);
@ -168,55 +182,62 @@ 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());
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
{
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
{
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;
}
return m_u0;
}
}

View File

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