1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-04-11 14:08:31 -04:00

SSB demod: AGC: implemented threshold gate to mitigate transients

This commit is contained in:
f4exb 2017-07-26 00:08:29 +02:00
parent 9ec4e6de98
commit 52eb869b7c
4 changed files with 40 additions and 19 deletions

View File

@ -37,6 +37,7 @@ SSBDemod::SSBDemod(BasebandSampleSink* sampleSink) :
m_agcActive(false),
m_agcNbSamples(12000),
m_agcPowerThreshold(1e-2),
m_agcThresholdGate(0),
m_sampleSink(sampleSink),
m_audioFifo(4, 24000),
m_settingsMutex(QMutex::Recursive)
@ -91,7 +92,8 @@ void SSBDemod::configure(MessageQueue* messageQueue,
bool audioMute,
bool agc,
int agcTimeLog2,
int agcPowerThreshold)
int agcPowerThreshold,
int agcThresholdGate)
{
Message* cmd = MsgConfigureSSBDemod::create(
Bandwidth,
@ -104,7 +106,8 @@ void SSBDemod::configure(MessageQueue* messageQueue,
audioMute,
agc,
agcTimeLog2,
agcPowerThreshold);
agcPowerThreshold,
agcThresholdGate);
messageQueue->push(cmd);
}
@ -313,6 +316,7 @@ bool SSBDemod::handleMessage(const Message& cmd)
int agcNbSamples = 48 * (1<<cfg.getAGCTimeLog2());
double agcPowerThreshold = CalcDb::powerFromdB(cfg.getAGCPowerThershold()) * (1<<30);
int agcThresholdGate = 48 * cfg.getAGCThersholdGate(); // ms
if (m_agcNbSamples != agcNbSamples)
{
@ -326,6 +330,12 @@ bool SSBDemod::handleMessage(const Message& cmd)
m_agcPowerThreshold = agcPowerThreshold;
}
if (m_agcThresholdGate != agcThresholdGate)
{
m_agc.setGate(agcThresholdGate);
m_agcThresholdGate = agcThresholdGate;
}
m_settingsMutex.unlock();
qDebug() << "SBDemod::handleMessage: MsgConfigureSSBDemod: m_Bandwidth: " << m_Bandwidth
@ -338,7 +348,8 @@ bool SSBDemod::handleMessage(const Message& cmd)
<< " m_audioMute: " << m_audioMute
<< " m_agcActive: " << m_agcActive
<< " agcNbSamples: " << agcNbSamples
<< " agcPowerThreshold: " << agcPowerThreshold;
<< " agcPowerThreshold: " << agcPowerThreshold
<< " agcThresholdGate: " << agcThresholdGate;
return true;
}

View File

@ -47,7 +47,8 @@ public:
bool audioMute,
bool agc,
int agcTimeLog2,
int agcPowerThreshold);
int agcPowerThreshold,
int agcThresholdGate);
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
virtual void start();
@ -81,8 +82,9 @@ private:
bool getDSB() const { return m_dsb; }
bool getAudioMute() const { return m_audioMute; }
bool getAGC() const { return m_agc; }
int getAGCTimeLog2() { return m_agcTimeLog2; }
int getAGCPowerThershold() { return m_agcPowerThreshold; }
int getAGCTimeLog2() const { return m_agcTimeLog2; }
int getAGCPowerThershold() const { return m_agcPowerThreshold; }
int getAGCThersholdGate() const { return m_agcThresholdGate; }
static MsgConfigureSSBDemod* create(Real Bandwidth,
Real LowCutoff,
@ -94,7 +96,8 @@ private:
bool audioMute,
bool agc,
int agcTimeLog2,
int agcPowerThreshold)
int agcPowerThreshold,
int agcThresholdGate)
{
return new MsgConfigureSSBDemod(
Bandwidth,
@ -107,7 +110,8 @@ private:
audioMute,
agc,
agcTimeLog2,
agcPowerThreshold);
agcPowerThreshold,
agcThresholdGate);
}
private:
@ -122,6 +126,7 @@ private:
bool m_agc;
int m_agcTimeLog2;
int m_agcPowerThreshold;
int m_agcThresholdGate;
MsgConfigureSSBDemod(Real Bandwidth,
Real LowCutoff,
@ -133,7 +138,8 @@ private:
bool audioMute,
bool agc,
int agcTimeLog2,
int agcPowerThreshold) :
int agcPowerThreshold,
int agcThresholdGate) :
Message(),
m_Bandwidth(Bandwidth),
m_LowCutoff(LowCutoff),
@ -145,7 +151,8 @@ private:
m_audioMute(audioMute),
m_agc(agc),
m_agcTimeLog2(agcTimeLog2),
m_agcPowerThreshold(agcPowerThreshold)
m_agcPowerThreshold(agcPowerThreshold),
m_agcThresholdGate(agcThresholdGate)
{ }
};
@ -177,6 +184,7 @@ private:
bool m_agcActive;
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
NCOF m_nco;
Interpolator m_interpolator;

View File

@ -82,6 +82,7 @@ QByteArray SSBDemodGUI::serialize() const
s.writeBool(11, ui->agc->isChecked());
s.writeS32(12, ui->agcTimeLog2->value());
s.writeS32(13, ui->agcPowerThreshold->value());
s.writeS32(14, ui->agcThresholdGate->value());
return s.final();
}
@ -138,7 +139,7 @@ bool SSBDemodGUI::deserialize(const QByteArray& data)
ui->agcPowerThresholdText->setText(s);
d.readS32(14, &tmp, 5);
ui->agcThresholdGate->setValue(tmp);
s = QString::number(tmp*10, 'f', 0);
s = QString::number(tmp, 'f', 0);
ui->agcThresholdGateText->setText(s);
blockApplySettings(false);
@ -304,7 +305,7 @@ void SSBDemodGUI::on_agcPowerThreshold_valueChanged(int value)
void SSBDemodGUI::on_agcThresholdGate_valueChanged(int value)
{
QString s = QString::number(value * 10, 'f', 0);
QString s = QString::number(value, 'f', 0);
ui->agcThresholdGateText->setText(s);
applySettings();
}
@ -515,7 +516,8 @@ void SSBDemodGUI::applySettings()
ui->audioMute->isChecked(),
ui->agc->isChecked(),
ui->agcTimeLog2->value(),
ui->agcPowerThreshold->value());
ui->agcPowerThreshold->value(),
ui->agcThresholdGate->value());
}
}

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>435</width>
<width>370</width>
<height>160</height>
</rect>
</property>
@ -36,7 +36,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>421</width>
<width>360</width>
<height>151</height>
</rect>
</property>
@ -568,13 +568,13 @@
<string>Set threshiold gate (ms)</string>
</property>
<property name="maximum">
<number>50</number>
<number>20</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
<number>4</number>
</property>
</widget>
</item>
@ -582,7 +582,7 @@
<widget class="QLabel" name="agcThresholdGateText">
<property name="minimumSize">
<size>
<width>24</width>
<width>16</width>
<height>0</height>
</size>
</property>
@ -590,7 +590,7 @@
<string>Threshiold gate (ms)</string>
</property>
<property name="text">
<string>000</string>
<string>00</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>