SSB demod: improve AGC threshold handling

pull/60/head
f4exb 2017-07-25 23:39:27 +02:00
rodzic 2597883015
commit 9ec4e6de98
7 zmienionych plików z 171 dodań i 22 usunięć

Wyświetl plik

@ -302,7 +302,7 @@ bool SSBDemod::handleMessage(const Message& cmd)
DSBFilter->create_dsb_filter((2.0f * m_Bandwidth) / (float) m_audioSampleRate);
m_volume = cfg.getVolume();
m_volume *= m_volume * 0.1;
m_volume *= 2.0;
m_spanLog2 = cfg.getSpanLog2();
m_audioBinaual = cfg.getAudioBinaural();

Wyświetl plik

@ -129,9 +129,17 @@ bool SSBDemodGUI::deserialize(const QByteArray& data)
d.readBool(11, &booltmp, false);
ui->agc->setChecked(booltmp);
d.readS32(12, &tmp, 7);
ui->agcTimeText->setText(QString("%1").arg((1<<tmp), 0, 'f', 0));
ui->agcTimeLog2->setValue(tmp);
QString s = QString::number((1<<tmp), 'f', 0);
ui->agcTimeText->setText(s);
d.readS32(13, &tmp, -20);
ui->agcPowerThresholdText->setText(QString("%1").arg(tmp, 0, 'f', 0));
ui->agcPowerThreshold->setValue(tmp);
s = QString::number(tmp, 'f', 0);
ui->agcPowerThresholdText->setText(s);
d.readS32(14, &tmp, 5);
ui->agcThresholdGate->setValue(tmp);
s = QString::number(tmp*10, 'f', 0);
ui->agcThresholdGateText->setText(s);
blockApplySettings(false);
m_channelMarker.blockSignals(false);
@ -275,20 +283,29 @@ void SSBDemodGUI::on_volume_valueChanged(int value)
applySettings();
}
void SSBDemodGUI::on_agc_stateChanged(int state)
void SSBDemodGUI::on_agc_stateChanged(int state __attribute((__unused__)))
{
applySettings();
}
void SSBDemodGUI::on_agcTimeLog2_valueChanged(int value)
{
ui->agcTimeText->setText(QString("%1").arg((1<<value), 0, 'f', 0));
QString s = QString::number((1<<value), 'f', 0);
ui->agcTimeText->setText(s);
applySettings();
}
void SSBDemodGUI::on_agcPowerThreshold_valueChanged(int value)
{
ui->agcPowerThresholdText->setText(QString("%1").arg(value, 0, 'f', 0));
QString s = QString::number(value, 'f', 0);
ui->agcPowerThresholdText->setText(s);
applySettings();
}
void SSBDemodGUI::on_agcThresholdGate_valueChanged(int value)
{
QString s = QString::number(value * 10, 'f', 0);
ui->agcThresholdGateText->setText(s);
applySettings();
}

Wyświetl plik

@ -51,6 +51,7 @@ private slots:
void on_agc_stateChanged(int state);
void on_agcTimeLog2_valueChanged(int value);
void on_agcPowerThreshold_valueChanged(int value);
void on_agcThresholdGate_valueChanged(int value);
void on_audioMute_toggled(bool checked);
void on_spanLog2_valueChanged(int value);
void onWidgetRolled(QWidget* widget, bool rollDown);

Wyświetl plik

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>370</width>
<width>435</width>
<height>160</height>
</rect>
</property>
@ -36,7 +36,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>360</width>
<width>421</width>
<height>151</height>
</rect>
</property>
@ -479,8 +479,11 @@
<property name="toolTip">
<string>AGC time constant (ms in log2 steps)</string>
</property>
<property name="minimum">
<number>4</number>
</property>
<property name="maximum">
<number>10</number>
<number>11</number>
</property>
<property name="pageStep">
<number>1</number>
@ -494,7 +497,7 @@
<widget class="QLabel" name="agcTimeText">
<property name="minimumSize">
<size>
<width>30</width>
<width>35</width>
<height>0</height>
</size>
</property>
@ -553,6 +556,47 @@
</property>
</widget>
</item>
<item>
<widget class="QDial" name="agcThresholdGate">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Set threshiold gate (ms)</string>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="agcThresholdGateText">
<property name="minimumSize">
<size>
<width>24</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Threshiold gate (ms)</string>
</property>
<property name="text">
<string>000</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">

Wyświetl plik

@ -6,6 +6,7 @@
*/
#include "dsp/agc.h"
#include "util/smootherstep.h"
AGC::AGC(int historySize, Real R) :
@ -46,7 +47,9 @@ MagSquaredAGC::MagSquaredAGC(int historySize, double R, double threshold) :
AGC(historySize, R),
m_magsq(0.0),
m_threshold(threshold),
m_thresholdCount(0)
m_gate(0),
m_stepCounter(0),
m_gateCounter(0)
{}
MagSquaredAGC::~MagSquaredAGC()
@ -68,16 +71,39 @@ double MagSquaredAGC::feedAndGetValue(const Complex& ci)
if (m_magsq > m_threshold)
{
m_thresholdCount = 0;
if (m_gateCounter < m_gate)
{
m_gateCounter++;
}
else
{
m_count = 0;
}
}
else
{
if (m_thresholdCount < m_moving_average.historySize()) {
m_thresholdCount++;
if (m_count < m_moving_average.historySize()) {
m_count++;
}
m_gateCounter = 0;
}
return (m_thresholdCount < m_moving_average.historySize()) ? m_u0 : 0.0;
if (m_count < m_moving_average.historySize())
{
if (m_stepCounter < 2400) {
m_stepCounter++;
}
return m_u0 * StepFunctions::smootherstep(m_stepCounter/2400.0);
}
else
{
m_stepCounter = 0;
return 0.0;
}
//return (m_count < m_moving_average.historySize()) ? m_u0 : 0.0;
}
//MagAGC::MagAGC() :
@ -89,7 +115,9 @@ MagAGC::MagAGC(int historySize, double R, double threshold) :
AGC(historySize, R),
m_magsq(0.0),
m_threshold(threshold),
m_thresholdCount(0)
m_gate(0),
m_stepCounter(0),
m_gateCounter(0)
{}
MagAGC::~MagAGC()
@ -111,16 +139,39 @@ double MagAGC::feedAndGetValue(const Complex& ci)
if (m_magsq > m_threshold)
{
m_thresholdCount = 0;
if (m_gateCounter < m_gate)
{
m_gateCounter++;
}
else
{
m_count = 0;
}
}
else
{
if (m_thresholdCount < m_moving_average.historySize()) {
m_thresholdCount++;
if (m_count < m_moving_average.historySize()) {
m_count++;
}
m_gateCounter = 0;
}
return (m_thresholdCount < m_moving_average.historySize()) ? m_u0 : 0.0;
if (m_count < m_moving_average.historySize())
{
if (m_stepCounter < 480) {
m_stepCounter++;
}
return m_u0 * StepFunctions::smootherstep(m_stepCounter/480.0);
}
else
{
m_stepCounter = 0;
return 0.0;
}
//return (m_count < m_moving_average.historySize()) ? m_u0 : 0.0;
}
//AlphaAGC::AlphaAGC() :

Wyświetl plik

@ -38,10 +38,13 @@ public:
double feedAndGetValue(const Complex& ci);
double getMagSq() const { return m_magsq; }
void setThreshold(double threshold) { m_threshold = threshold; }
void setGate(int gate) { m_gate = gate; }
private:
double m_magsq;
double m_threshold; //!< squelch on magsq average with transition from +3dB
int m_thresholdCount;
int m_gate;
int m_stepCounter;
int m_gateCounter;
};
class MagAGC : public AGC
@ -53,10 +56,13 @@ public:
double feedAndGetValue(const Complex& ci);
Real getMagSq() const { return m_magsq; }
void setThreshold(double threshold) { m_threshold = threshold; }
void setGate(int gate) { m_gate = gate; }
private:
double m_magsq;
double m_threshold; //!< squelch on magsq average
int m_thresholdCount;
int m_gate;
int m_stepCounter;
int m_gateCounter;
};
class AlphaAGC : public AGC

Wyświetl plik

@ -0,0 +1,30 @@
/*
* smootherstep.h
*
* Created on: Jul 25, 2017
* Author: f4exb
*/
#ifndef SDRBASE_UTIL_SMOOTHERSTEP_H_
#define SDRBASE_UTIL_SMOOTHERSTEP_H_
class StepFunctions
{
public:
static float smootherstep(float x)
{
if (x == 1.0f) {
return 1.0f;
} else if (x == 0.0f) {
return 0.0f;
}
double x3 = x * x * x;
double x4 = x * x3;
double x5 = x * x4;
return (float) (6.0*x5 - 15.0*x4 + 10.0*x3);
}
};
#endif /* SDRBASE_UTIL_SMOOTHERSTEP_H_ */