mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-23 00:18:37 -05:00
SSB demod: improve AGC threshold handling
This commit is contained in:
parent
2597883015
commit
9ec4e6de98
@ -302,7 +302,7 @@ bool SSBDemod::handleMessage(const Message& cmd)
|
|||||||
DSBFilter->create_dsb_filter((2.0f * m_Bandwidth) / (float) m_audioSampleRate);
|
DSBFilter->create_dsb_filter((2.0f * m_Bandwidth) / (float) m_audioSampleRate);
|
||||||
|
|
||||||
m_volume = cfg.getVolume();
|
m_volume = cfg.getVolume();
|
||||||
m_volume *= m_volume * 0.1;
|
m_volume *= 2.0;
|
||||||
|
|
||||||
m_spanLog2 = cfg.getSpanLog2();
|
m_spanLog2 = cfg.getSpanLog2();
|
||||||
m_audioBinaual = cfg.getAudioBinaural();
|
m_audioBinaual = cfg.getAudioBinaural();
|
||||||
|
@ -129,9 +129,17 @@ bool SSBDemodGUI::deserialize(const QByteArray& data)
|
|||||||
d.readBool(11, &booltmp, false);
|
d.readBool(11, &booltmp, false);
|
||||||
ui->agc->setChecked(booltmp);
|
ui->agc->setChecked(booltmp);
|
||||||
d.readS32(12, &tmp, 7);
|
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);
|
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);
|
blockApplySettings(false);
|
||||||
m_channelMarker.blockSignals(false);
|
m_channelMarker.blockSignals(false);
|
||||||
@ -275,20 +283,29 @@ void SSBDemodGUI::on_volume_valueChanged(int value)
|
|||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSBDemodGUI::on_agc_stateChanged(int state)
|
void SSBDemodGUI::on_agc_stateChanged(int state __attribute((__unused__)))
|
||||||
{
|
{
|
||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSBDemodGUI::on_agcTimeLog2_valueChanged(int value)
|
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();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSBDemodGUI::on_agcPowerThreshold_valueChanged(int value)
|
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();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ private slots:
|
|||||||
void on_agc_stateChanged(int state);
|
void on_agc_stateChanged(int state);
|
||||||
void on_agcTimeLog2_valueChanged(int value);
|
void on_agcTimeLog2_valueChanged(int value);
|
||||||
void on_agcPowerThreshold_valueChanged(int value);
|
void on_agcPowerThreshold_valueChanged(int value);
|
||||||
|
void on_agcThresholdGate_valueChanged(int value);
|
||||||
void on_audioMute_toggled(bool checked);
|
void on_audioMute_toggled(bool checked);
|
||||||
void on_spanLog2_valueChanged(int value);
|
void on_spanLog2_valueChanged(int value);
|
||||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>370</width>
|
<width>435</width>
|
||||||
<height>160</height>
|
<height>160</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -36,7 +36,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>360</width>
|
<width>421</width>
|
||||||
<height>151</height>
|
<height>151</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -479,8 +479,11 @@
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AGC time constant (ms in log2 steps)</string>
|
<string>AGC time constant (ms in log2 steps)</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>10</number>
|
<number>11</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="pageStep">
|
<property name="pageStep">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
@ -494,7 +497,7 @@
|
|||||||
<widget class="QLabel" name="agcTimeText">
|
<widget class="QLabel" name="agcTimeText">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>30</width>
|
<width>35</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@ -553,6 +556,47 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dsp/agc.h"
|
#include "dsp/agc.h"
|
||||||
|
#include "util/smootherstep.h"
|
||||||
|
|
||||||
|
|
||||||
AGC::AGC(int historySize, Real R) :
|
AGC::AGC(int historySize, Real R) :
|
||||||
@ -46,7 +47,9 @@ 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_thresholdCount(0)
|
m_gate(0),
|
||||||
|
m_stepCounter(0),
|
||||||
|
m_gateCounter(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
MagSquaredAGC::~MagSquaredAGC()
|
MagSquaredAGC::~MagSquaredAGC()
|
||||||
@ -68,16 +71,39 @@ double MagSquaredAGC::feedAndGetValue(const Complex& ci)
|
|||||||
|
|
||||||
if (m_magsq > m_threshold)
|
if (m_magsq > m_threshold)
|
||||||
{
|
{
|
||||||
m_thresholdCount = 0;
|
if (m_gateCounter < m_gate)
|
||||||
|
{
|
||||||
|
m_gateCounter++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_thresholdCount < m_moving_average.historySize()) {
|
m_count = 0;
|
||||||
m_thresholdCount++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_count < m_moving_average.historySize()) {
|
||||||
|
m_count++;
|
||||||
|
}
|
||||||
|
|
||||||
return (m_thresholdCount < m_moving_average.historySize()) ? m_u0 : 0.0;
|
m_gateCounter = 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() :
|
//MagAGC::MagAGC() :
|
||||||
@ -89,7 +115,9 @@ MagAGC::MagAGC(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_thresholdCount(0)
|
m_gate(0),
|
||||||
|
m_stepCounter(0),
|
||||||
|
m_gateCounter(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
MagAGC::~MagAGC()
|
MagAGC::~MagAGC()
|
||||||
@ -111,16 +139,39 @@ double MagAGC::feedAndGetValue(const Complex& ci)
|
|||||||
|
|
||||||
if (m_magsq > m_threshold)
|
if (m_magsq > m_threshold)
|
||||||
{
|
{
|
||||||
m_thresholdCount = 0;
|
if (m_gateCounter < m_gate)
|
||||||
|
{
|
||||||
|
m_gateCounter++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_thresholdCount < m_moving_average.historySize()) {
|
m_count = 0;
|
||||||
m_thresholdCount++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_count < m_moving_average.historySize()) {
|
||||||
|
m_count++;
|
||||||
|
}
|
||||||
|
|
||||||
return (m_thresholdCount < m_moving_average.historySize()) ? m_u0 : 0.0;
|
m_gateCounter = 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() :
|
//AlphaAGC::AlphaAGC() :
|
||||||
|
@ -38,10 +38,13 @@ 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 setGate(int gate) { m_gate = gate; }
|
||||||
private:
|
private:
|
||||||
double m_magsq;
|
double m_magsq;
|
||||||
double m_threshold; //!< squelch on magsq average with transition from +3dB
|
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
|
class MagAGC : public AGC
|
||||||
@ -53,10 +56,13 @@ public:
|
|||||||
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 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_thresholdCount;
|
int m_gate;
|
||||||
|
int m_stepCounter;
|
||||||
|
int m_gateCounter;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AlphaAGC : public AGC
|
class AlphaAGC : public AGC
|
||||||
|
30
sdrbase/util/smootherstep.h
Normal file
30
sdrbase/util/smootherstep.h
Normal file
@ -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_ */
|
Loading…
Reference in New Issue
Block a user