From 428d22579dd4665654f82daf0695f540b0c2e2d1 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sat, 5 Aug 2017 23:11:05 +0200 Subject: [PATCH] SSB modulator: added compression (AGC) volume order control --- plugins/channeltx/modssb/ssbmod.cpp | 8 ++++-- plugins/channeltx/modssb/ssbmod.h | 9 ++++++ plugins/channeltx/modssb/ssbmodgui.cpp | 12 ++++++++ plugins/channeltx/modssb/ssbmodgui.h | 1 + plugins/channeltx/modssb/ssbmodgui.ui | 40 +++++++++++++++++++++++--- sdrbase/dsp/agc.cpp | 10 +++++-- sdrbase/dsp/agc.h | 8 ++++-- 7 files changed, 77 insertions(+), 11 deletions(-) diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp index 3eebfe209..aa00a9ab7 100644 --- a/plugins/channeltx/modssb/ssbmod.cpp +++ b/plugins/channeltx/modssb/ssbmod.cpp @@ -135,6 +135,7 @@ void SSBMod::configure(MessageQueue* messageQueue, bool audioMute, bool playLoop, bool agc, + float agcOrder, int agcTime, int agcThreshold, int agcThresholdGate, @@ -151,6 +152,7 @@ void SSBMod::configure(MessageQueue* messageQueue, audioMute, playLoop, agc, + agcOrder, agcTime, agcThreshold, agcThresholdGate, @@ -617,6 +619,7 @@ bool SSBMod::handleMessage(const Message& cmd) m_config.m_agc = cfg.getAGC(); m_config.m_agcTime = 48 * cfg.getAGCTime(); // ms + m_config.m_agcOrder = cfg.getAGCOrder(); m_config.m_agcThresholdEnable = cfg.getAGCThreshold() != -99; m_config.m_agcThreshold = CalcDb::powerFromdB(cfg.getAGCThreshold()); // power dB m_config.m_agcThresholdGate = 48 * cfg.getAGCThresholdGate(); // ms @@ -752,9 +755,9 @@ void SSBMod::apply() } } - if (m_config.m_agcTime != m_running.m_agcTime) + if ((m_config.m_agcTime != m_running.m_agcTime) || (m_config.m_agcOrder != m_running.m_agcOrder)) { - m_inAGC.resize(m_config.m_agcTime, 0.2); + m_inAGC.resize(m_config.m_agcTime, m_config.m_agcOrder); } if (m_config.m_agcThresholdEnable != m_running.m_agcThresholdEnable) @@ -792,6 +795,7 @@ void SSBMod::apply() m_running.m_audioMute = m_config.m_audioMute; m_running.m_playLoop = m_config.m_playLoop; m_running.m_agc = m_config.m_agc; + m_running.m_agcOrder = m_config.m_agcOrder; m_running.m_agcTime = m_config.m_agcTime; m_running.m_agcThresholdEnable = m_config.m_agcThresholdEnable; m_running.m_agcThreshold = m_config.m_agcThreshold; diff --git a/plugins/channeltx/modssb/ssbmod.h b/plugins/channeltx/modssb/ssbmod.h index 91814a672..08851389d 100644 --- a/plugins/channeltx/modssb/ssbmod.h +++ b/plugins/channeltx/modssb/ssbmod.h @@ -189,6 +189,7 @@ public: bool audioMute, bool playLoop, bool agc, + float agcOrder, int agcTime, int agcThreshold, int agcThresholdGate, @@ -231,6 +232,7 @@ private: bool getAudioMute() const { return m_audioMute; } bool getPlayLoop() const { return m_playLoop; } bool getAGC() const { return m_agc; } + float getAGCOrder() const { return m_agcOrder; } int getAGCTime() const { return m_agcTime; } int getAGCThreshold() const { return m_agcThreshold; } int getAGCThresholdGate() const { return m_agcThresholdGate; } @@ -247,6 +249,7 @@ private: bool audioMute, bool playLoop, bool agc, + float agcOrder, int agcTime, int agcThreshold, int agcThresholdGate, @@ -263,6 +266,7 @@ private: audioMute, playLoop, agc, + agcOrder, agcTime, agcThreshold, agcThresholdGate, @@ -281,6 +285,7 @@ private: bool m_audioMute; bool m_playLoop; bool m_agc; + float m_agcOrder; int m_agcTime; int m_agcThreshold; int m_agcThresholdGate; @@ -297,6 +302,7 @@ private: bool audioMute, bool playLoop, bool agc, + float agcOrder, int agcTime, int agcThreshold, int agcThresholdGate, @@ -313,6 +319,7 @@ private: m_audioMute(audioMute), m_playLoop(playLoop), m_agc(agc), + m_agcOrder(agcOrder), m_agcTime(agcTime), m_agcThreshold(agcThreshold), m_agcThresholdGate(agcThresholdGate), @@ -349,6 +356,7 @@ private: bool m_audioMute; bool m_playLoop; bool m_agc; + float m_agcOrder; int m_agcTime; bool m_agcThresholdEnable; double m_agcThreshold; @@ -371,6 +379,7 @@ private: m_audioMute(false), m_playLoop(false), m_agc(false), + m_agcOrder(0.2), m_agcTime(9600), m_agcThresholdEnable(true), m_agcThreshold(1e-4), diff --git a/plugins/channeltx/modssb/ssbmodgui.cpp b/plugins/channeltx/modssb/ssbmodgui.cpp index cdc03fc68..0122cf415 100644 --- a/plugins/channeltx/modssb/ssbmodgui.cpp +++ b/plugins/channeltx/modssb/ssbmodgui.cpp @@ -122,6 +122,7 @@ QByteArray SSBModGUI::serialize() const s.writeS32(14, ui->agcThreshold->value()); s.writeS32(15, ui->agcThresholdGate->value()); s.writeS32(16, ui->agcThresholdDelay->value()); + s.writeS32(17, ui->agcOrder->value()); return s.final(); } @@ -185,6 +186,8 @@ bool SSBModGUI::deserialize(const QByteArray& data) ui->agcThresholdGate->setValue(tmp); d.readS32(16, &tmp, 5); ui->agcThresholdDelay->setValue(tmp); + d.readS32(17, &tmp, 20); + ui->agcOrder->setValue(tmp); displaySettings(); @@ -433,6 +436,12 @@ void SSBModGUI::on_agc_stateChanged(int state __attribute((__unused__))) applySettings(); } +void SSBModGUI::on_agcOrder_valueChanged(int value){ + QString s = QString::number(value / 100.0, 'f', 2); + ui->agcOrderText->setText(s); + applySettings(); +} + void SSBModGUI::on_agcTime_valueChanged(int value){ QString s = QString::number(m_agcTimeConstant[value], 'f', 0); ui->agcTimeText->setText(s); @@ -692,6 +701,7 @@ void SSBModGUI::applySettings() ui->audioMute->isChecked(), ui->playLoop->isChecked(), ui->agc->isChecked(), + ui->agcOrder->value() / 100.0, m_agcTimeConstant[ui->agcTime->value()], ui->agcThreshold->value(), ui->agcThresholdGate->value(), @@ -708,6 +718,8 @@ void SSBModGUI::displaySettings() ui->agcThresholdGateText->setText(s); s = QString::number(ui->agcThresholdDelay->value() * 10, 'f', 0); ui->agcThresholdDelayText->setText(s); + s = QString::number(ui->agcOrder->value() / 100.0, 'f', 2); + ui->agcOrderText->setText(s); } void SSBModGUI::displayAGCPowerThreshold(int value) diff --git a/plugins/channeltx/modssb/ssbmodgui.h b/plugins/channeltx/modssb/ssbmodgui.h index af43cf219..b0c37b67d 100644 --- a/plugins/channeltx/modssb/ssbmodgui.h +++ b/plugins/channeltx/modssb/ssbmodgui.h @@ -72,6 +72,7 @@ private slots: void on_toneFrequency_valueChanged(int value); void on_mic_toggled(bool checked); void on_agc_stateChanged(int state); + void on_agcOrder_valueChanged(int value); void on_agcTime_valueChanged(int value); void on_agcThreshold_valueChanged(int value); void on_agcThresholdGate_valueChanged(int value); diff --git a/plugins/channeltx/modssb/ssbmodgui.ui b/plugins/channeltx/modssb/ssbmodgui.ui index 2c619f820..909407cab 100644 --- a/plugins/channeltx/modssb/ssbmodgui.ui +++ b/plugins/channeltx/modssb/ssbmodgui.ui @@ -475,6 +475,38 @@ + + + + + 24 + 24 + + + + AGC volume order in faraction of maximum amplitude + + + 100 + + + 1 + + + 20 + + + + + + + AGC volume order in faraction of maximum amplitude + + + 0.00 + + + @@ -484,7 +516,7 @@ - Compressor time constant (attack) + Compressor time constant (attack) in ms 0 @@ -528,7 +560,7 @@ - Audio squelch threshold + Audio squelch threshold (db power) -99 @@ -572,7 +604,7 @@ - Audio squelch gate + Audio squelch gate in ms 1 @@ -610,7 +642,7 @@ - Audio squelch delay (release) + Audio squelch delay (release) in ms 1 diff --git a/sdrbase/dsp/agc.cpp b/sdrbase/dsp/agc.cpp index 6f99fc90c..e9c37027a 100644 --- a/sdrbase/dsp/agc.cpp +++ b/sdrbase/dsp/agc.cpp @@ -12,7 +12,7 @@ #define StepLengthMax 2400 // 50ms -AGC::AGC(int historySize, Real R) : +AGC::AGC(int historySize, double R) : m_u0(1.0), m_R(R), m_moving_average(historySize, m_R), @@ -23,7 +23,7 @@ AGC::AGC(int historySize, Real R) : AGC::~AGC() {} -void AGC::resize(int historySize, Real R) +void AGC::resize(int historySize, double R) { m_R = R; m_moving_average.resize(historySize, R); @@ -73,6 +73,12 @@ void MagAGC::resize(int historySize, Real R) AGC::resize(historySize, R); } +void MagAGC::setOrder(double R) +{ + m_R2 = R*R; + AGC::setOrder(R); +} + void MagAGC::setThresholdEnable(bool enable) { if (m_thresholdEnable != enable) diff --git a/sdrbase/dsp/agc.h b/sdrbase/dsp/agc.h index 332bec81e..ef99c7aec 100644 --- a/sdrbase/dsp/agc.h +++ b/sdrbase/dsp/agc.h @@ -13,10 +13,11 @@ class AGC { public: - AGC(int historySize, Real R); + AGC(int historySize, double R); virtual ~AGC(); - void resize(int historySize, Real R); + void resize(int historySize, double R); + void setOrder(double R) { m_R = R; } Real getValue(); Real getAverage(); virtual void feed(Complex& ci) = 0; @@ -37,9 +38,10 @@ public: virtual ~MagAGC(); void setSquared(bool squared) { m_squared = squared; } void resize(int historySize, Real R); + void setOrder(double R); virtual void feed(Complex& ci); double feedAndGetValue(const Complex& ci); - Real getMagSq() const { return m_magsq; } + double getMagSq() const { return m_magsq; } void setThreshold(double threshold) { m_threshold = threshold; } void setThresholdEnable(bool enable); void setGate(int gate) { m_gate = gate; }