mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-13 11:51:47 -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);
|
||||
|
||||
m_volume = cfg.getVolume();
|
||||
m_volume *= m_volume * 0.1;
|
||||
m_volume *= 2.0;
|
||||
|
||||
m_spanLog2 = cfg.getSpanLog2();
|
||||
m_audioBinaual = cfg.getAudioBinaural();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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">
|
||||
|
@ -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() :
|
||||
|
@ -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
|
||||
|
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