diff --git a/plugins/channelrx/wdsprx/CMakeLists.txt b/plugins/channelrx/wdsprx/CMakeLists.txt index ea4ce5d61..84898fa74 100644 --- a/plugins/channelrx/wdsprx/CMakeLists.txt +++ b/plugins/channelrx/wdsprx/CMakeLists.txt @@ -38,6 +38,8 @@ if(NOT SERVER_MODE) wdsprxdnrdialog.ui wdsprxfmdialog.cpp wdsprxfmdialog.ui + wdsprxsquelchdialog.cpp + wdsprxsquelchdialog.ui wdsprxgui.cpp wdsprxgui.ui ) @@ -50,6 +52,7 @@ if(NOT SERVER_MODE) wdsprxdnbdialog.h wdsprxdnrdialog.h wdsprxfmdialog.h + wdsprxsquelchdialog.h ) set(TARGET_NAME wdsprx) set(TARGET_LIB "Qt::Widgets") diff --git a/plugins/channelrx/wdsprx/wdsprxfmdialog.ui b/plugins/channelrx/wdsprx/wdsprxfmdialog.ui index 4e0d8f684..ce505318c 100644 --- a/plugins/channelrx/wdsprx/wdsprxfmdialog.ui +++ b/plugins/channelrx/wdsprx/wdsprxfmdialog.ui @@ -262,7 +262,7 @@ AF volume limter gain (dB) - 0 + -30 30 @@ -271,7 +271,7 @@ 1 - 10 + 0 diff --git a/plugins/channelrx/wdsprx/wdsprxgui.cpp b/plugins/channelrx/wdsprx/wdsprxgui.cpp index e69474c76..bc706cec2 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.cpp +++ b/plugins/channelrx/wdsprx/wdsprxgui.cpp @@ -43,6 +43,7 @@ #include "wdsprxamdialog.h" #include "wdsprxfmdialog.h" #include "wdsprxcwpeakdialog.h" +#include "wdsprxsquelchdialog.h" WDSPRxGUI* WDSPRxGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel) { @@ -211,6 +212,15 @@ void WDSPRxGUI::on_agc_toggled(bool checked) applySettings(); } +void WDSPRxGUI::on_agcGain_valueChanged(int value) +{ + QString s = QString::number(value, 'f', 0); + ui->agcGainText->setText(s); + m_settings.m_agcGain = value; + m_settings.m_profiles[m_settings.m_profileIndex].m_agcGain = m_settings.m_agcGain; + applySettings(); +} + void WDSPRxGUI::on_dnr_toggled(bool checked) { m_settings.m_dnr = checked; @@ -232,12 +242,18 @@ void WDSPRxGUI::on_cwPeaking_toggled(bool checked) applySettings(); } -void WDSPRxGUI::on_agcGain_valueChanged(int value) +void WDSPRxGUI::on_squelch_toggled(bool checked) { - QString s = QString::number(value, 'f', 0); - ui->agcGainText->setText(s); - m_settings.m_agcGain = value; - m_settings.m_profiles[m_settings.m_profileIndex].m_agcGain = m_settings.m_agcGain; + m_settings.m_squelch = checked; + m_settings.m_profiles[m_settings.m_profileIndex].m_squelch = m_settings.m_squelch; + applySettings(); +} + +void WDSPRxGUI::on_squelchThreshold_valueChanged(int value) +{ + m_settings.m_squelchThreshold = value; + m_settings.m_profiles[m_settings.m_profileIndex].m_squelchThreshold = m_settings.m_squelchThreshold; + ui->squelchThresholdText->setText(tr("%1").arg(m_settings.m_squelchThreshold)); applySettings(); } @@ -322,6 +338,12 @@ void WDSPRxGUI::on_profileIndex_valueChanged(int value) m_settings.m_fmAFLimiterGain = m_settings.m_profiles[m_settings.m_profileIndex].m_fmAFLimiterGain; m_settings.m_fmCTCSSNotch = m_settings.m_profiles[m_settings.m_profileIndex].m_fmCTCSSNotch; m_settings.m_fmCTCSSNotchFrequency = m_settings.m_profiles[m_settings.m_profileIndex].m_fmCTCSSNotchFrequency; + // Squelch + m_settings.m_squelch = m_settings.m_profiles[m_settings.m_profileIndex].m_squelch; + m_settings.m_squelchMode = m_settings.m_profiles[m_settings.m_profileIndex].m_squelchMode; + m_settings.m_ssqlTauMute = m_settings.m_profiles[m_settings.m_profileIndex].m_ssqlTauMute; + m_settings.m_ssqlTauUnmute = m_settings.m_profiles[m_settings.m_profileIndex].m_ssqlTauUnmute; + m_settings.m_amsqMaxTail = m_settings.m_profiles[m_settings.m_profileIndex].m_amsqMaxTail; displaySettings(); applyBandwidths(m_settings.m_profiles[m_settings.m_profileIndex].m_spanLog2, true); // does applySettings(true) } @@ -344,7 +366,7 @@ void WDSPRxGUI::on_demod_currentIndexChanged(int index) break; } displaySettings(); - applySettings(); + applyBandwidths(m_settings.m_profiles[m_settings.m_profileIndex].m_spanLog2, true); // does applySettings(true) } void WDSPRxGUI::onMenuDialogCalled(const QPoint &p) @@ -424,7 +446,8 @@ WDSPRxGUI::WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam m_dnrDialog(nullptr), m_amDialog(nullptr), m_fmDialog(nullptr), - m_cwPeakDialog(nullptr) + m_cwPeakDialog(nullptr), + m_squelchDialog(nullptr) { setAttribute(Qt::WA_DeleteOnClose, true); m_helpURL = "plugins/channelrx/demodssb/readme.md"; @@ -455,6 +478,9 @@ WDSPRxGUI::WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam CRightClickEnabler *cwPeakRightClickEnabler = new CRightClickEnabler(ui->cwPeaking); connect(cwPeakRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(cwPeakSetupDialog(const QPoint &))); + CRightClickEnabler *squelchRightClickEnabler = new CRightClickEnabler(ui->squelch); + connect(squelchRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(squelchSetupDialog(const QPoint &))); + CRightClickEnabler *demodRightClickEnabler = new CRightClickEnabler(ui->demod); connect(demodRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(demodSetupDialog(const QPoint &))); @@ -727,6 +753,9 @@ void WDSPRxGUI::displaySettings() ui->dnr->setChecked(m_settings.m_dnr); ui->dnb->setChecked(m_settings.m_dnb); ui->cwPeaking->setChecked(m_settings.m_cwPeaking); + ui->squelch->setChecked(m_settings.m_squelch); + ui->squelchThreshold->setValue(m_settings.m_squelchThreshold); + ui->squelchThresholdText->setText(tr("%1").arg(m_settings.m_squelchThreshold)); ui->audioBinaural->setChecked(m_settings.m_audioBinaural); ui->audioFlipChannels->setChecked(m_settings.m_audioFlipChannels); ui->audioMute->setChecked(m_settings.m_audioMute); @@ -1122,6 +1151,56 @@ void WDSPRxGUI::fmSetup(int iValueChanged) } } +void WDSPRxGUI::squelchSetupDialog(const QPoint& p) +{ + m_squelchDialog = new WDSPRxSquelchDialog(); + m_squelchDialog->move(p); + m_squelchDialog->setMode(m_settings.m_squelchMode); + m_squelchDialog->setSSQLTauMute(m_settings.m_ssqlTauMute); + m_squelchDialog->setSSQLTauUnmute(m_settings.m_ssqlTauUnmute); + m_squelchDialog->setAMSQMaxTail(m_settings.m_amsqMaxTail); + QObject::connect(m_squelchDialog, &WDSPRxSquelchDialog::valueChanged, this, &WDSPRxGUI::squelchSetup); + m_squelchDialog->exec(); + QObject::disconnect(m_squelchDialog, &WDSPRxSquelchDialog::valueChanged, this, &WDSPRxGUI::squelchSetup); + m_squelchDialog->deleteLater(); + m_squelchDialog = nullptr; +} + +void WDSPRxGUI::squelchSetup(int iValueChanged) +{ + if (!m_squelchDialog) { + return; + } + + WDSPRxSquelchDialog::ValueChanged valueChanged = (WDSPRxSquelchDialog::ValueChanged) iValueChanged; + + switch (valueChanged) + { + case WDSPRxSquelchDialog::ChangedMode: + m_settings.m_squelchMode = m_squelchDialog->getMode(); + m_settings.m_profiles[m_settings.m_profileIndex].m_squelchMode = m_settings.m_squelchMode; + applySettings(); + break; + case WDSPRxSquelchDialog::ChangedSSQLTauMute: + m_settings.m_ssqlTauMute = m_squelchDialog->getSSQLTauMute(); + m_settings.m_profiles[m_settings.m_profileIndex].m_ssqlTauMute = m_settings.m_ssqlTauMute; + applySettings(); + break; + case WDSPRxSquelchDialog::ChangedSSQLTauUnmute: + m_settings.m_ssqlTauUnmute = m_squelchDialog->getSSQLTauUnmute(); + m_settings.m_profiles[m_settings.m_profileIndex].m_ssqlTauUnmute = m_settings.m_ssqlTauUnmute; + applySettings(); + break; + case WDSPRxSquelchDialog::ChangedAMSQMaxTail: + m_settings.m_amsqMaxTail = m_squelchDialog->getAMSQMaxTail(); + m_settings.m_profiles[m_settings.m_profileIndex].m_amsqMaxTail = m_settings.m_amsqMaxTail; + applySettings(); + break; + default: + break; + } +} + void WDSPRxGUI::tick() { double powDbAvg, powDbPeak; @@ -1176,6 +1255,8 @@ void WDSPRxGUI::makeUIConnections() QObject::connect(ui->filterIndex, &QDial::valueChanged, this, &WDSPRxGUI::on_profileIndex_valueChanged); QObject::connect(ui->demod, QOverload::of(&QComboBox::currentIndexChanged), this, &WDSPRxGUI::on_demod_currentIndexChanged); QObject::connect(ui->cwPeaking, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_cwPeaking_toggled); + QObject::connect(ui->squelch, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_squelch_toggled); + QObject::connect(ui->squelchThreshold, &QDial::valueChanged, this, &WDSPRxGUI::on_squelchThreshold_valueChanged); } void WDSPRxGUI::updateAbsoluteCenterFrequency() diff --git a/plugins/channelrx/wdsprx/wdsprxgui.h b/plugins/channelrx/wdsprx/wdsprxgui.h index 92e945a14..9c8bc9c80 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.h +++ b/plugins/channelrx/wdsprx/wdsprxgui.h @@ -40,6 +40,7 @@ class WDSPRxDNRDialog; class WDSPRxAMDialog; class WDSPRxFMDialog; class WDSPRxCWPeakDialog; +class WDSPRxSquelchDialog; class SpectrumVis; class BasebandSampleSink; @@ -101,6 +102,7 @@ private: WDSPRxAMDialog* m_amDialog; WDSPRxFMDialog* m_fmDialog; WDSPRxCWPeakDialog* m_cwPeakDialog; + WDSPRxSquelchDialog* m_squelchDialog; QIcon m_iconDSBUSB; QIcon m_iconDSBLSB; @@ -140,6 +142,8 @@ private slots: void on_profileIndex_valueChanged(int value); void on_demod_currentIndexChanged(int index); void on_cwPeaking_toggled(bool checked); + void on_squelch_toggled(bool checked); + void on_squelchThreshold_valueChanged(int value); void onWidgetRolled(QWidget* widget, bool rollDown); void onMenuDialogCalled(const QPoint& p); void handleInputMessages(); @@ -155,6 +159,8 @@ private slots: void demodSetupDialog(const QPoint& p); void amSetup(int valueChanged); void fmSetup(int valueChanged); + void squelchSetupDialog(const QPoint& p); + void squelchSetup(int valueChanged); void tick(); }; diff --git a/plugins/channelrx/wdsprx/wdsprxgui.ui b/plugins/channelrx/wdsprx/wdsprxgui.ui index 04044f7d2..0f1d01047 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.ui +++ b/plugins/channelrx/wdsprx/wdsprxgui.ui @@ -429,7 +429,7 @@ - Select filter in filter bank + Select profile in profile bank 0 @@ -936,6 +936,63 @@ + + + + Toggle squelch (righ-click for options) + + + SQ + + + true + + + + + + + + 24 + 24 + + + + Squelch threshold (%) + + + 0 + + + 100 + + + 1 + + + 3 + + + + + + + + 22 + 0 + + + + Power threshold gate (ms) + + + 000 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.cpp b/plugins/channelrx/wdsprx/wdsprxsettings.cpp index ddd347551..850e3b75e 100644 --- a/plugins/channelrx/wdsprx/wdsprxsettings.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsettings.cpp @@ -82,10 +82,17 @@ void WDSPRxSettings::resetToDefaults() m_fmAFLimiterGain = 10.0; m_fmCTCSSNotch = false; m_fmCTCSSNotchFrequency = 67.0; + // Squelch + m_squelch = false; + m_squelchThreshold = 3; + m_squelchMode = WDSPRxProfile::SquelchModeVoice; + m_ssqlTauMute = 0.1; + m_ssqlTauUnmute = 0.1; + m_amsqMaxTail = 1.5; // m_volume = 1.0; m_inputFrequencyOffset = 0; - m_rgbColor = QColor(0, 255, 0).rgb(); + m_rgbColor = QColor(0, 255, 196).rgb(); m_title = "WDSP Receiver"; m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; m_streamIndex = 0; @@ -150,6 +157,12 @@ QByteArray WDSPRxSettings::serialize() const s.writeDouble(49, m_fmAFLimiterGain); s.writeBool( 50, m_fmCTCSSNotch); s.writeDouble(51, m_fmCTCSSNotchFrequency); + // Squelch + s.writeBool( 60, m_squelch); + s.writeS32( 61, m_squelchThreshold); + s.writeDouble(62, m_ssqlTauMute); + s.writeDouble(63, m_ssqlTauUnmute); + s.writeDouble(64, m_amsqMaxTail); // s.writeString(70, m_title); s.writeString(71, m_audioDeviceName); @@ -213,6 +226,12 @@ QByteArray WDSPRxSettings::serialize() const s.writeDouble(149 + 100*i, m_profiles[i].m_fmAFLimiterGain); s.writeBool( 150 + 100*i, m_profiles[i].m_fmCTCSSNotch); s.writeDouble(151 + 100*i, m_profiles[i].m_fmCTCSSNotchFrequency); + // Squelch + s.writeBool( 160 + 100*i, m_profiles[i].m_squelch); + s.writeS32( 161 + 100*i, m_profiles[i].m_squelchThreshold); + s.writeDouble(162 + 100*i, m_profiles[i].m_ssqlTauMute); + s.writeDouble(163 + 100*i, m_profiles[i].m_ssqlTauUnmute); + s.writeDouble(164 + 100*i, m_profiles[i].m_amsqMaxTail); } return s.final(); @@ -294,6 +313,12 @@ bool WDSPRxSettings::deserialize(const QByteArray& data) d.readDouble(49, &m_fmAFLimiterGain, 10.0); d.readBool( 50, &m_fmCTCSSNotch, false); d.readDouble(51, &m_fmCTCSSNotchFrequency, 67.0); + // Squelch + d.readBool( 60, &m_squelch, false); + d.readS32( 61, &m_squelchThreshold, 3); + d.readDouble(62, &m_ssqlTauMute, 0.1); + d.readDouble(63, &m_ssqlTauUnmute, 0.1); + d.readDouble(64, &m_amsqMaxTail, 1.5); // d.readString(70, &m_title, "WDSP Receiver"); d.readString(71, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName); @@ -327,49 +352,64 @@ bool WDSPRxSettings::deserialize(const QByteArray& data) for (unsigned int i = 0; (i < 10); i++) { - d.readS32 (104 + 50*i, &tmp, 9); + d.readS32 (104 + 100*i, &tmp, 9); m_profiles[i].m_demod = (WDSPRxProfile::WDSPRxDemod) tmp; // Filter - d.readS32 (100 + 50*i, &m_profiles[i].m_spanLog2, 3); - d.readS32 (101 + 50*i, &tmp, 30); + d.readS32 (100 + 100*i, &m_profiles[i].m_spanLog2, 3); + d.readS32 (101 + 100*i, &tmp, 30); m_profiles[i].m_highCutoff = tmp * 100.0; - d.readS32 (102 + 50*i, &tmp, 3); + d.readS32 (102 + 100*i, &tmp, 3); m_profiles[i].m_lowCutoff = tmp * 100.0; - d.readS32 (103 + 50*i, &m_profiles[i].m_fftWindow, 0); + d.readS32 (103 + 100*i, &m_profiles[i].m_fftWindow, 0); // AGC - d.readBool( 110, &m_profiles[i].m_agc, true); - d.readS32( 111, &tmp, 2); + d.readBool( 110 + 100*i, &m_profiles[i].m_agc, true); + d.readS32( 111 + 100*i, &tmp, 2); m_profiles[i].m_agcMode = (WDSPRxProfile::WDSPRxAGCMode) tmp; - d.readS32( 112, &m_profiles[i].m_agcGain, 80); - d.readS32( 113, &m_profiles[i].m_agcSlope, 35); - d.readS32( 114, &m_profiles[i].m_agcHangThreshold, 0); + d.readS32( 112 + 100*i, &m_profiles[i].m_agcGain, 80); + d.readS32( 113 + 100*i, &m_profiles[i].m_agcSlope, 35); + d.readS32( 114 + 100*i, &m_profiles[i].m_agcHangThreshold, 0); // Noise blanker - d.readBool (120 + 50*i, &m_profiles[i].m_dnb, false); - d.readS32 (121 + 50*i, &tmp); + d.readBool (120 + 100*i, &m_profiles[i].m_dnb, false); + d.readS32 (121 + 100*i, &tmp); m_profiles[i].m_nbScheme = (WDSPRxProfile::WDSPRxNBScheme) tmp; - d.readS32 (122 + 50*i, &tmp); + d.readS32 (122 + 100*i, &tmp); m_profiles[i].m_nb2Mode = (WDSPRxProfile::WDSPRxNB2Mode) tmp; - d.readDouble(123 + 50*i, &m_profiles[i].m_nbSlewTime, 0.1); - d.readDouble(124 + 50*i, &m_profiles[i].m_nbLeadTime, 0.1); - d.readDouble(125 + 50*i, &m_profiles[i].m_nbLagTime, 0.1); - d.readS32 (126 + 50*i, &m_profiles[i].m_nbThreshold, 30); - d.readDouble(127 + 50*i, &m_profiles[i].m_nbAvgTime, 50.0); + d.readDouble(123 + 100*i, &m_profiles[i].m_nbSlewTime, 0.1); + d.readDouble(124 + 100*i, &m_profiles[i].m_nbLeadTime, 0.1); + d.readDouble(125 + 100*i, &m_profiles[i].m_nbLagTime, 0.1); + d.readS32 (126 + 100*i, &m_profiles[i].m_nbThreshold, 30); + d.readDouble(127 + 100*i, &m_profiles[i].m_nbAvgTime, 50.0); // Noise reduction - d.readBool (130 + 50*i, &m_profiles[i].m_dnr, false); - d.readBool (132 + 50*i, &m_profiles[i].m_anf, false); - d.readS32 (133 + 50*i, &tmp); + d.readBool (130 + 100*i, &m_profiles[i].m_dnr, false); + d.readBool (132 + 100*i, &m_profiles[i].m_anf, false); + d.readS32 (133 + 100*i, &tmp); m_profiles[i].m_nrScheme = (WDSPRxProfile::WDSPRxNRScheme) tmp; - d.readS32 (134 + 50*i, &tmp); + d.readS32 (134 + 100*i, &tmp); m_profiles[i].m_nr2Gain = (WDSPRxProfile::WDSPRxNR2Gain) tmp; - d.readS32 (135 + 50*i, &tmp); + d.readS32 (135 + 100*i, &tmp); m_profiles[i].m_nr2NPE = (WDSPRxProfile::WDSPRxNR2NPE) tmp; - d.readS32 (136 + 50*i, &tmp); + d.readS32 (136 + 100*i, &tmp); m_profiles[i].m_nrPosition = (WDSPRxProfile::WDSPRxNRPosition) tmp; - d.readBool (137 + 50*i, &m_profiles[i].m_nr2ArtifactReduction); + d.readBool (137 + 100*i, &m_profiles[i].m_nr2ArtifactReduction); // Demods - d.readBool (140 + 50*i, &m_amFadeLevel, false); - d.readBool (141 + 50*i, &m_cwPeaking, false); - d.readDouble(142 + 50*i, &m_profiles[i].m_cwPeakFrequency, 600.0); + d.readBool (140 + 100*i, &m_amFadeLevel, false); + d.readBool (141 + 100*i, &m_cwPeaking, false); + d.readDouble(142 + 100*i, &m_profiles[i].m_cwPeakFrequency, 600.0); + d.readDouble(143 + 100*i, &m_profiles[i].m_cwBandwidth, 100.0); + d.readDouble(144 + 100*i, &m_profiles[i].m_cwGain, 2.0); + d.readDouble(145 + 100*i, &m_profiles[i].m_fmDeviation, 2500.0); + d.readDouble(146 + 100*i, &m_profiles[i].m_fmAFLow, 300.0); + d.readDouble(147 + 100*i, &m_profiles[i].m_fmAFHigh, 3000.0); + d.readBool( 148 + 100*i, &m_profiles[i].m_fmAFLimiter, false); + d.readDouble(149 + 100*i, &m_profiles[i].m_fmAFLimiterGain, 10.0); + d.readBool( 150 + 100*i, &m_profiles[i].m_fmCTCSSNotch, false); + d.readDouble(151 + 100*i, &m_profiles[i].m_fmCTCSSNotchFrequency, 67.0); + // Squelch + d.readBool( 160 + 100*i, &m_profiles[i].m_squelch, false); + d.readS32( 161 + 100*i, &m_profiles[i].m_squelchThreshold, 3); + d.readDouble(161 + 100*i, &m_profiles[i].m_ssqlTauMute, 0.1); + d.readDouble(162 + 100*i, &m_profiles[i].m_ssqlTauUnmute, 0.1); + d.readDouble(163 + 100*i, &m_profiles[i].m_amsqMaxTail, 1.5); } return true; diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.h b/plugins/channelrx/wdsprx/wdsprxsettings.h index 67938990b..be51a2e36 100644 --- a/plugins/channelrx/wdsprx/wdsprxsettings.h +++ b/plugins/channelrx/wdsprx/wdsprxsettings.h @@ -76,6 +76,12 @@ struct WDSPRxProfile NB2ModeHoldSample, NB2ModeInterpolate, }; + enum WDSPRxSquelchMode + { + SquelchModeVoice, + SquelchModeAM, + SquelchModeFM, + }; WDSPRxDemod m_demod; // Filter @@ -119,6 +125,13 @@ struct WDSPRxProfile double m_fmAFLimiterGain; bool m_fmCTCSSNotch; double m_fmCTCSSNotchFrequency; + // Squelch + bool m_squelch; + int m_squelchThreshold; + WDSPRxSquelchMode m_squelchMode; + double m_ssqlTauMute; //!< Voice squelch tau mute + double m_ssqlTauUnmute; //!< Voice squelch tau unmute + double m_amsqMaxTail; WDSPRxProfile() : m_demod(DemodSSB), @@ -157,7 +170,13 @@ struct WDSPRxProfile m_fmAFLimiter(false), m_fmAFLimiterGain(10.0), m_fmCTCSSNotch(false), - m_fmCTCSSNotchFrequency(67.0) + m_fmCTCSSNotchFrequency(67.0), + m_squelch(false), + m_squelchThreshold(3), + m_squelchMode(SquelchModeVoice), + m_ssqlTauMute(0.1), + m_ssqlTauUnmute(0.1), + m_amsqMaxTail(1.5) {} }; @@ -209,6 +228,13 @@ struct WDSPRxSettings double m_fmAFLimiterGain; bool m_fmCTCSSNotch; double m_fmCTCSSNotchFrequency; + // Squelch + bool m_squelch; + int m_squelchThreshold; + WDSPRxProfile::WDSPRxSquelchMode m_squelchMode; + double m_ssqlTauMute; //!< Voice squelch tau mute + double m_ssqlTauUnmute; //!< Voice squelch tau unmute + double m_amsqMaxTail; quint32 m_rgbColor; QString m_title; diff --git a/plugins/channelrx/wdsprx/wdsprxsink.cpp b/plugins/channelrx/wdsprx/wdsprxsink.cpp index 50b4a44cb..5b8db0769 100644 --- a/plugins/channelrx/wdsprx/wdsprxsink.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsink.cpp @@ -39,6 +39,9 @@ #include "amd.hpp" #include "fmd.hpp" #include "iir.cpp" +#include "ssql.hpp" +#include "amsq.hpp" +#include "fmsq.hpp" #include "wdsprxsink.h" @@ -656,6 +659,60 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force) WDSP::FMD::SetCTCSSFreq(*m_rxa, settings.m_fmCTCSSNotchFrequency); } + // Squelch + + if ((m_settings.m_squelch != settings.m_squelch) + || (m_settings.m_squelchThreshold != settings.m_squelchThreshold) + || (m_settings.m_squelchMode != settings.m_squelchMode) || force) + { + WDSP::SSQL::SetSSQLRun(*m_rxa, 0); + WDSP::AMSQ::SetAMSQRun(*m_rxa, 0); + WDSP::FMSQ::SetFMSQRun(*m_rxa, 0); + + if (settings.m_squelch) + { + switch(settings.m_squelchMode) + { + case WDSPRxProfile::SquelchModeVoice: + { + WDSP::SSQL::SetSSQLRun(*m_rxa, 1); + double threshold = 0.0075 * settings.m_squelchThreshold; + WDSP::SSQL::SetSSQLThreshold(*m_rxa, threshold); + } + break; + case WDSPRxProfile::SquelchModeAM: + { + WDSP::AMSQ::SetAMSQRun(*m_rxa, 1); + double threshold = ((settings.m_squelchThreshold / 100.0) * 160.0) - 160.0; + WDSP::AMSQ::SetAMSQThreshold(*m_rxa, threshold); + } + break; + case WDSPRxProfile::SquelchModeFM: + { + WDSP::FMSQ::SetFMSQRun(*m_rxa, 1); + double threshold = pow(10.0, -2.0 * ((double) settings.m_squelchThreshold) / 100.0); + qDebug("WDSPRxSink::applySettings: FM squelch %lf", threshold); + WDSP::FMSQ::SetFMSQThreshold(*m_rxa, threshold); + } + break; + default: + break; + } + } + } + + if ((m_settings.m_ssqlTauMute != settings.m_ssqlTauMute) || force) { + WDSP::SSQL::SetSSQLTauMute(*m_rxa, settings.m_ssqlTauMute); + } + + if ((m_settings.m_ssqlTauUnmute != settings.m_ssqlTauUnmute) || force) { + WDSP::SSQL::SetSSQLTauUnMute(*m_rxa, settings.m_ssqlTauUnmute); + } + + if ((m_settings.m_amsqMaxTail != settings.m_amsqMaxTail) || force) { + WDSP::AMSQ::SetAMSQMaxTail(*m_rxa, settings.m_amsqMaxTail); + } + // Audio panel if ((m_settings.m_volume != settings.m_volume) || force) { diff --git a/plugins/channelrx/wdsprx/wdsprxsquelchdialog.cpp b/plugins/channelrx/wdsprx/wdsprxsquelchdialog.cpp new file mode 100644 index 000000000..34d38f123 --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxsquelchdialog.cpp @@ -0,0 +1,172 @@ +/////////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2024 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////////// + +#include "wdsprxsquelchdialog.h" +#include "ui_wdsprxsquelchdialog.h" + +WDSPRxSquelchDialog::WDSPRxSquelchDialog(QWidget* parent) : + QDialog(parent), + ui(new Ui::WDSPRxSquelchDialog) +{ + ui->setupUi(this); +} + +WDSPRxSquelchDialog::~WDSPRxSquelchDialog() +{ + delete ui; +} + +void WDSPRxSquelchDialog::setMode(WDSPRxProfile::WDSPRxSquelchMode mode) +{ + ui->voiceSquelchGroup->blockSignals(true); + ui->amSquelchGroup->blockSignals(true); + ui->fmSquelchGroup->blockSignals(true); + + ui->voiceSquelchGroup->setChecked(false); + ui->amSquelchGroup->setChecked(false); + ui->fmSquelchGroup->setChecked(false); + + switch(mode) + { + case WDSPRxProfile::SquelchModeVoice: + ui->voiceSquelchGroup->setChecked(true); + break; + case WDSPRxProfile::SquelchModeAM: + ui->amSquelchGroup->setChecked(true); + break; + case WDSPRxProfile::SquelchModeFM: + ui->fmSquelchGroup->setChecked(true); + break; + default: + break; + } + + ui->voiceSquelchGroup->blockSignals(false); + ui->amSquelchGroup->blockSignals(false); + ui->fmSquelchGroup->blockSignals(false); +} + +void WDSPRxSquelchDialog::setSSQLTauMute(double value) +{ + ui->ssqlTauMute->blockSignals(true); + ui->ssqlTauMute->setValue(value); + ui->ssqlTauMute->blockSignals(false); +} + +void WDSPRxSquelchDialog::setSSQLTauUnmute(double value) +{ + ui->ssqlTauUnmute->blockSignals(true); + ui->ssqlTauUnmute->setValue(value); + ui->ssqlTauUnmute->blockSignals(false); +} + +void WDSPRxSquelchDialog::setAMSQMaxTail(double value) +{ + ui->amsqMaxTail->blockSignals(true); + ui->amsqMaxTail->setValue(value); + ui->amsqMaxTail->blockSignals(false); +} + +void WDSPRxSquelchDialog::on_voiceSquelchGroup_clicked(bool checked) +{ + if (checked) + { + ui->amSquelchGroup->blockSignals(true); + ui->fmSquelchGroup->blockSignals(true); + + ui->amSquelchGroup->setChecked(false); + ui->fmSquelchGroup->setChecked(false); + + m_mode = WDSPRxProfile::SquelchModeVoice; + + ui->amSquelchGroup->blockSignals(false); + ui->fmSquelchGroup->blockSignals(false); + emit valueChanged(ChangedMode); + } + else + { + ui->voiceSquelchGroup->blockSignals(true); + ui->voiceSquelchGroup->setChecked(true); + ui->voiceSquelchGroup->blockSignals(false); + } +} + +void WDSPRxSquelchDialog::on_amSquelchGroup_clicked(bool checked) +{ + if (checked) + { + ui->voiceSquelchGroup->blockSignals(true); + ui->fmSquelchGroup->blockSignals(true); + + ui->voiceSquelchGroup->setChecked(false); + ui->fmSquelchGroup->setChecked(false); + + m_mode = WDSPRxProfile::SquelchModeAM; + + ui->voiceSquelchGroup->blockSignals(false); + ui->fmSquelchGroup->blockSignals(false); + emit valueChanged(ChangedMode); + } + else + { + ui->amSquelchGroup->blockSignals(true); + ui->amSquelchGroup->setChecked(true); + ui->amSquelchGroup->blockSignals(false); + } +} + +void WDSPRxSquelchDialog::on_fmSquelchGroup_clicked(bool checked) +{ + if (checked) + { + ui->voiceSquelchGroup->blockSignals(true); + ui->amSquelchGroup->blockSignals(true); + + ui->voiceSquelchGroup->setChecked(false); + ui->amSquelchGroup->setChecked(false); + + m_mode = WDSPRxProfile::SquelchModeFM; + + ui->voiceSquelchGroup->blockSignals(false); + ui->amSquelchGroup->blockSignals(false); + emit valueChanged(ChangedMode); + } + else + { + ui->fmSquelchGroup->blockSignals(true); + ui->fmSquelchGroup->setChecked(true); + ui->fmSquelchGroup->blockSignals(false); + } +} + +void WDSPRxSquelchDialog::on_ssqlTauMute_valueChanged(double value) +{ + m_ssqlTauMute = value; + emit valueChanged(ChangedSSQLTauMute); +} + +void WDSPRxSquelchDialog::on_ssqlTauUnmute_valueChanged(double value) +{ + m_ssqlTauUnmute = value; + emit valueChanged(ChangedSSQLTauUnmute); +} + +void WDSPRxSquelchDialog::on_amsqMaxTail_valueChanged(double value) +{ + m_amsqMaxTail = value; + emit valueChanged(ChangedAMSQMaxTail); +} diff --git a/plugins/channelrx/wdsprx/wdsprxsquelchdialog.h b/plugins/channelrx/wdsprx/wdsprxsquelchdialog.h new file mode 100644 index 000000000..b74570092 --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxsquelchdialog.h @@ -0,0 +1,71 @@ +/////////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2024 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////////// +#ifndef INCLUDE_WDSPRXSQUELCHDIALOG_H +#define INCLUDE_WDSPRXSQUELCHDIALOG_H + +#include + +#include "export.h" +#include "wdsprxsettings.h" + +namespace Ui { + class WDSPRxSquelchDialog; +} + +class SDRGUI_API WDSPRxSquelchDialog : public QDialog { + Q_OBJECT +public: + enum ValueChanged { + ChangedMode, + ChangedSSQLTauMute, + ChangedSSQLTauUnmute, + ChangedAMSQMaxTail, + }; + + explicit WDSPRxSquelchDialog(QWidget* parent = nullptr); + ~WDSPRxSquelchDialog(); + + void setMode(WDSPRxProfile::WDSPRxSquelchMode mode); + void setSSQLTauMute(double value); + void setSSQLTauUnmute(double value); + void setAMSQMaxTail(double value); + + WDSPRxProfile::WDSPRxSquelchMode getMode() const { return m_mode; } + double getSSQLTauMute() const { return m_ssqlTauMute; } + double getSSQLTauUnmute() const { return m_ssqlTauUnmute; } + double getAMSQMaxTail() const { return m_amsqMaxTail; } + +signals: + void valueChanged(int valueChanged); + +private: + Ui::WDSPRxSquelchDialog *ui; + WDSPRxProfile::WDSPRxSquelchMode m_mode; + double m_ssqlTauMute; //!< Voice squelch tau mute + double m_ssqlTauUnmute; //!< Voice squelch tau unmute + double m_amsqMaxTail; + +private slots: + void on_voiceSquelchGroup_clicked(bool checked); + void on_amSquelchGroup_clicked(bool checked); + void on_fmSquelchGroup_clicked(bool checked); + void on_ssqlTauMute_valueChanged(double value); + void on_ssqlTauUnmute_valueChanged(double value); + void on_amsqMaxTail_valueChanged(double value); +}; + +#endif diff --git a/plugins/channelrx/wdsprx/wdsprxsquelchdialog.ui b/plugins/channelrx/wdsprx/wdsprxsquelchdialog.ui new file mode 100644 index 000000000..0d90102ee --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxsquelchdialog.ui @@ -0,0 +1,268 @@ + + + WDSPRxSquelchDialog + + + + 0 + 0 + 382 + 238 + + + + Squelch Settings + + + + + + + 370 + 70 + + + + QGroupBox { + border: 1px solid gray; + } + + + Voice Squelch (SSB) + + + true + + + false + + + + + 10 + 30 + 91 + 26 + + + + Tau mute (s) + + + + + + 100 + 30 + 70 + 29 + + + + Add yaw offset to help with aligning images on the map. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + 0.100000000000000 + + + 2.000000000000000 + + + 0.100000000000000 + + + 0.100000000000000 + + + + + + 180 + 30 + 111 + 26 + + + + Tau unmute (s) + + + + + + 290 + 30 + 70 + 29 + + + + Add yaw offset to help with aligning images on the map. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + 0.100000000000000 + + + 1.000000000000000 + + + 0.100000000000000 + + + 0.100000000000000 + + + + + + + + + 370 + 70 + + + + QGroupBox { + border: 1px solid gray; + } + + + AM Squelch (AM, SAM, CW) + + + true + + + false + + + + + 10 + 30 + 81 + 26 + + + + Max Tail (s) + + + + + + 100 + 30 + 70 + 29 + + + + Add yaw offset to help with aligning images on the map. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 2 + + + 0.100000000000000 + + + 3.000000000000000 + + + 0.010000000000000 + + + 1.500000000000000 + + + + + + + + + 370 + 35 + + + + QGroupBox { + border: 1px solid gray; + } + + + FM Squelch (FM) + + + true + + + false + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + WDSPRxSquelchDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + WDSPRxSquelchDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/wdsp/amd.cpp b/wdsp/amd.cpp index f1e26b494..717767e09 100644 --- a/wdsp/amd.cpp +++ b/wdsp/amd.cpp @@ -38,7 +38,7 @@ warren@wpratt.com namespace WDSP { AMD* AMD::create_amd - ( +( int run, int buff_size, float *in_buff, @@ -47,13 +47,13 @@ AMD* AMD::create_amd int levelfade, int sbmode, int sample_rate, - float fmin, - float fmax, - float zeta, - float omegaN, - float tauR, - float tauI - ) + double fmin, + double fmax, + double zeta, + double omegaN, + double tauR, + double tauI +) { AMD *a = new AMD(); a->run = run; @@ -126,13 +126,13 @@ void AMD::flush_amd (AMD *a) void AMD::xamd (AMD *a) { int i; - float audio; - float vco[2]; - float corr[2]; - float det; - float del_out; - float ai, bi, aq, bq; - float ai_ps, bi_ps, aq_ps, bq_ps; + double audio; + double vco[2]; + double corr[2]; + double det; + double del_out; + double ai, bi, aq, bq; + double ai_ps, bi_ps, aq_ps, bq_ps; int j, k; if (a->run) { @@ -279,8 +279,14 @@ void AMD::SetAMDRun(RXA& rxa, int run) AMD *a = rxa.amd.p; if (a->run != run) { - RXA::bp1Check (rxa, run, rxa.snba.p->run, rxa.emnr.p->run, - rxa.anf.p->run, rxa.anr.p->run); + RXA::bp1Check ( + rxa, + run, + rxa.snba.p->run, + rxa.emnr.p->run, + rxa.anf.p->run, + rxa.anr.p->run + ); rxa.csDSP.lock(); a->run = run; RXA::bp1Set (rxa); diff --git a/wdsp/amd.hpp b/wdsp/amd.hpp index cd6117e27..6616d97fe 100644 --- a/wdsp/amd.hpp +++ b/wdsp/amd.hpp @@ -50,33 +50,33 @@ public: float *in_buff; // pointer to input buffer float *out_buff; // pointer to output buffer int mode; // demodulation mode - float sample_rate; // sample rate - float dc; // dc component in demodulated output - float fmin; // pll - minimum carrier freq to lock - float fmax; // pll - maximum carrier freq to lock - float omega_min; // pll - minimum lock check parameter - float omega_max; // pll - maximum lock check parameter - float zeta; // pll - damping factor; as coded, must be <=1.0 - float omegaN; // pll - natural frequency - float phs; // pll - phase accumulator - float omega; // pll - locked pll frequency - float fil_out; // pll - filter output - float g1, g2; // pll - filter gain parameters - float tauR; // carrier removal time constant - float tauI; // carrier insertion time constant - float mtauR; // carrier removal multiplier - float onem_mtauR; // 1.0 - carrier_removal_multiplier - float mtauI; // carrier insertion multiplier - float onem_mtauI; // 1.0 - carrier_insertion_multiplier - float a[3 * STAGES + 3]; // Filter a variables - float b[3 * STAGES + 3]; // Filter b variables - float c[3 * STAGES + 3]; // Filter c variables - float d[3 * STAGES + 3]; // Filter d variables - float c0[STAGES]; // Filter coefficients - path 0 - float c1[STAGES]; // Filter coefficients - path 1 - float dsI; // delayed sample, I path - float dsQ; // delayed sample, Q path - float dc_insert; // dc component to insert in output + double sample_rate; // sample rate + double dc; // dc component in demodulated output + double fmin; // pll - minimum carrier freq to lock + double fmax; // pll - maximum carrier freq to lock + double omega_min; // pll - minimum lock check parameter + double omega_max; // pll - maximum lock check parameter + double zeta; // pll - damping factor; as coded, must be <=1.0 + double omegaN; // pll - natural frequency + double phs; // pll - phase accumulator + double omega; // pll - locked pll frequency + double fil_out; // pll - filter output + double g1, g2; // pll - filter gain parameters + double tauR; // carrier removal time constant + double tauI; // carrier insertion time constant + double mtauR; // carrier removal multiplier + double onem_mtauR; // 1.0 - carrier_removal_multiplier + double mtauI; // carrier insertion multiplier + double onem_mtauI; // 1.0 - carrier_insertion_multiplier + double a[3 * STAGES + 3]; // Filter a variables + double b[3 * STAGES + 3]; // Filter b variables + double c[3 * STAGES + 3]; // Filter c variables + double d[3 * STAGES + 3]; // Filter d variables + double c0[STAGES]; // Filter coefficients - path 0 + double c1[STAGES]; // Filter coefficients - path 1 + double dsI; // delayed sample, I path + double dsQ; // delayed sample, Q path + double dc_insert; // dc component to insert in output int sbmode; // sideband mode int levelfade; // Fade Leveler switch @@ -90,12 +90,12 @@ public: int levelfade, int sbmode, int sample_rate, - float fmin, - float fmax, - float zeta, - float omegaN, - float tauR, - float tauI + double fmin, + double fmax, + double zeta, + double omegaN, + double tauR, + double tauI ); static void init_amd (AMD *a); diff --git a/wdsp/amsq.cpp b/wdsp/amsq.cpp index 794148e23..ad6efe630 100644 --- a/wdsp/amsq.cpp +++ b/wdsp/amsq.cpp @@ -37,15 +37,15 @@ namespace WDSP { void AMSQ::compute_slews(AMSQ *a) { int i; - float delta, theta; - delta = PI / (float)a->ntup; + double delta, theta; + delta = PI / (double)a->ntup; theta = 0.0; for (i = 0; i <= a->ntup; i++) { a->cup[i] = a->muted_gain + (1.0 - a->muted_gain) * 0.5 * (1.0 - cos (theta)); theta += delta; } - delta = PI / (float)a->ntdown; + delta = PI / (double)a->ntdown; theta = 0.0; for (i = 0; i <= a->ntdown; i++) { @@ -78,8 +78,22 @@ void AMSQ::decalc_amsq (AMSQ *a) delete[] a->trigsig; } -AMSQ* AMSQ::create_amsq (int run, int size, float* in, float* out, float* trigger, int rate, float avtau, - float tup, float tdown, float tail_thresh, float unmute_thresh, float min_tail, float max_tail, float muted_gain) +AMSQ* AMSQ::create_amsq ( + int run, + int size, + float* in, + float* out, + float* trigger, + int rate, + double avtau, + double tup, + double tdown, + double tail_thresh, + double unmute_thresh, + double min_tail, + double max_tail, + double muted_gain +) { AMSQ *a = new AMSQ; a->run = run; @@ -127,7 +141,7 @@ void AMSQ::xamsq (AMSQ *a) if (a->run) { int i; - float sig, siglimit; + double sig, siglimit; for (i = 0; i < a->size; i++) { sig = sqrt (a->trigsig[2 * i + 0] * a->trigsig[2 * i + 0] + a->trigsig[2 * i + 1] * a->trigsig[2 * i + 1]); @@ -222,16 +236,16 @@ void AMSQ::SetAMSQRun (RXA& rxa, int run) rxa.csDSP.unlock(); } -void AMSQ::SetAMSQThreshold (RXA& rxa, float threshold) +void AMSQ::SetAMSQThreshold (RXA& rxa, double threshold) { - float thresh = pow (10.0, threshold / 20.0); + double thresh = pow (10.0, threshold / 20.0); rxa.csDSP.lock(); rxa.amsq.p->tail_thresh = 0.9 * thresh; rxa.amsq.p->unmute_thresh = thresh; rxa.csDSP.unlock(); } -void AMSQ::SetAMSQMaxTail (RXA& rxa, float tail) +void AMSQ::SetAMSQMaxTail (RXA& rxa, double tail) { AMSQ *a; rxa.csDSP.lock(); @@ -254,7 +268,7 @@ void AMSQ::SetAMSQRun (TXA& txa, int run) txa.csDSP.unlock(); } -void AMSQ::SetAMSQMutedGain (TXA& txa, float dBlevel) +void AMSQ::SetAMSQMutedGain (TXA& txa, double dBlevel) { // dBlevel is negative AMSQ *a; txa.csDSP.lock(); @@ -264,9 +278,9 @@ void AMSQ::SetAMSQMutedGain (TXA& txa, float dBlevel) txa.csDSP.unlock(); } -void AMSQ::SetAMSQThreshold (TXA& txa, float threshold) +void AMSQ::SetAMSQThreshold (TXA& txa, double threshold) { - float thresh = pow (10.0, threshold / 20.0); + double thresh = pow (10.0, threshold / 20.0); txa.csDSP.lock(); txa.amsq.p->tail_thresh = 0.9 * thresh; txa.amsq.p->unmute_thresh = thresh; diff --git a/wdsp/amsq.hpp b/wdsp/amsq.hpp index a1d433321..41a3f820b 100644 --- a/wdsp/amsq.hpp +++ b/wdsp/amsq.hpp @@ -43,26 +43,41 @@ public: float* out; // squelch output signal buffer float* trigger; // pointer to trigger data source float* trigsig; // buffer containing trigger signal - float rate; // sample rate - float avtau; // time constant for averaging noise - float avm; - float onem_avm; - float avsig; + double rate; // sample rate + double avtau; // time constant for averaging noise + double avm; + double onem_avm; + double avsig; int state; // state machine control int count; - float tup; - float tdown; + double tup; + double tdown; int ntup; int ntdown; float* cup; float* cdown; - float tail_thresh; - float unmute_thresh; - float min_tail; - float max_tail; - float muted_gain; + double tail_thresh; + double unmute_thresh; + double min_tail; + double max_tail; + double muted_gain; - static AMSQ* create_amsq (int run, int size, float* in, float* out, float* trigger, int rate, float avtau, float tup, float tdown, float tail_thresh, float unmute_thresh, float min_tail, float max_tail, float muted_gain); + static AMSQ* create_amsq ( + int run, + int size, + float* in, + float* out, + float* trigger, + int rate, + double avtau, + double tup, + double tdown, + double tail_thresh, + double unmute_thresh, + double min_tail, + double max_tail, + double muted_gain + ); static void destroy_amsq (AMSQ *a); static void flush_amsq (AMSQ *a); static void xamsq (AMSQ *a); @@ -72,12 +87,12 @@ public: static void setSize_amsq (AMSQ *a, int size); // RXA Properties static void SetAMSQRun (RXA& rxa, int run); - static void SetAMSQThreshold (RXA& rxa, float threshold); - static void SetAMSQMaxTail (RXA& rxa, float tail); + static void SetAMSQThreshold (RXA& rxa, double threshold); + static void SetAMSQMaxTail (RXA& rxa, double tail); // TXA Properties static void SetAMSQRun (TXA& txa, int run); - static void SetAMSQMutedGain (TXA& txa, float dBlevel); - static void SetAMSQThreshold (TXA& txa, float threshold); + static void SetAMSQMutedGain (TXA& txa, double dBlevel); + static void SetAMSQThreshold (TXA& txa, double threshold); private: static void compute_slews(AMSQ *a); diff --git a/wdsp/emnr.cpp b/wdsp/emnr.cpp index 2472787c7..15d175d47 100644 --- a/wdsp/emnr.cpp +++ b/wdsp/emnr.cpp @@ -298,8 +298,8 @@ void EMNR::calc_emnr(EMNR *a) } else { - memcpy (a->g.GG, Calculus::GG, 241 * 241 * sizeof(float)); - memcpy (a->g.GGS, Calculus::GGS, 241 * 241 * sizeof(float)); + std::copy(Calculus::GG, Calculus::GG + (241 * 241), a->g.GG); + std::copy(Calculus::GGS, Calculus::GGS + (241 * 241), a->g.GGS); } // @@ -380,10 +380,10 @@ void EMNR::calc_emnr(EMNR *a) a->np.subwc = a->np.V; a->np.amb_idx = 0; for (k = 0; k < a->np.msize; k++) a->np.lambda_y[k] = 0.5; - memcpy(a->np.p, a->np.lambda_y, a->np.msize * sizeof(float)); - memcpy(a->np.sigma2N, a->np.lambda_y, a->np.msize * sizeof(float)); - memcpy(a->np.pbar, a->np.lambda_y, a->np.msize * sizeof(float)); - memcpy(a->np.pmin_u, a->np.lambda_y, a->np.msize * sizeof(float)); + std::copy(a->np.lambda_y, a->np.lambda_y + a->np.msize, a->np.p); + std::copy(a->np.lambda_y, a->np.lambda_y + a->np.msize, a->np.sigma2N); + std::copy(a->np.lambda_y, a->np.lambda_y + a->np.msize, a->np.pbar); + std::copy(a->np.lambda_y, a->np.lambda_y + a->np.msize, a->np.pmin_u); for (k = 0; k < a->np.msize; k++) { a->np.p2bar[k] = a->np.lambda_y[k] * a->np.lambda_y[k]; @@ -392,7 +392,7 @@ void EMNR::calc_emnr(EMNR *a) for (ku = 0; ku < a->np.U; ku++) a->np.actminbuff[ku][k] = 1.0e300; } - memset(a->np.lmin_flag, 0, a->np.msize * sizeof(int)); + std::fill(a->np.lmin_flag, a->np.lmin_flag + a->np.msize, 0); } a->nps.incr = a->incr; @@ -507,10 +507,10 @@ EMNR* EMNR::create_emnr (int run, int position, int size, float* in, float* out, void EMNR::flush_emnr (EMNR *a) { int i; - memset (a->inaccum, 0, a->iasize * sizeof (float)); + std::fill(a->inaccum, a->inaccum + a->iasize, 0); for (i = 0; i < a->ovrlp; i++) - memset (a->save[i], 0, a->fsize * sizeof (float)); - memset (a->outaccum, 0, a->oasize * sizeof (float)); + std::fill(a->save[i], a->save[i] + a->fsize, 0); + std::fill(a->outaccum, a->outaccum + a->oasize, 0); a->nsamps = 0; a->iainidx = 0; a->iaoutidx = 0; @@ -587,7 +587,7 @@ void EMNR::LambdaD(EMNR *a) a->np.bmin[k] = 1.0 + 2.0 * (a->np.D - 1.0) / QeqTilda; a->np.bmin_sub[k] = 1.0 + 2.0 * (a->np.V - 1.0) / QeqTildaSub; } - memset (a->np.k_mod, 0, a->np.msize * sizeof (int)); + std::fill(a->np.k_mod, a->np.k_mod + a->np.msize, 0); for (k = 0; k < a->np.msize; k++) { f3 = a->np.p[k] * a->np.bmin[k] * bc; @@ -647,7 +647,7 @@ void EMNR::LambdaD(EMNR *a) } ++a->np.subwc; } - memcpy (a->np.lambda_d, a->np.sigma2N, a->np.msize * sizeof (float)); + std::copy(a->np.sigma2N, a->np.sigma2N + a->np.msize, a->np.lambda_d); } void EMNR::LambdaDs (EMNR *a) @@ -662,7 +662,7 @@ void EMNR::LambdaDs (EMNR *a) a->nps.EN2y[k] = (1.0 - a->nps.PH1y[k]) * a->nps.lambda_y[k] + a->nps.PH1y[k] * a->nps.sigma2N[k]; a->nps.sigma2N[k] = a->nps.alpha_pow * a->nps.sigma2N[k] + (1.0 - a->nps.alpha_pow) * a->nps.EN2y[k]; } - memcpy (a->nps.lambda_d, a->nps.sigma2N, a->nps.msize * sizeof (float)); + std::copy(a->nps.sigma2N, a->nps.sigma2N + a->nps.msize, a->nps.lambda_d); } void EMNR::aepf(EMNR *a) @@ -694,7 +694,7 @@ void EMNR::aepf(EMNR *a) a->ae.nmask[k] += a->mask[m]; a->ae.nmask[k] /= (float)N; } - memcpy (a->mask + n, a->ae.nmask, (a->ae.msize - 2 * n) * sizeof (float)); + std::copy(a->ae.nmask, a->ae.nmask + (a->ae.msize - 2 * n), a->mask + n); } float EMNR::getKey(float* type, float gamma, float xi) @@ -874,7 +874,7 @@ void EMNR::xemnr (EMNR *a, int pos) } } else if (a->out != a->in) - memcpy (a->out, a->in, a->bsize * sizeof (wcomplex)); + std::copy(a->in, a->in + a->bsize * 2, a->out); } void EMNR::setBuffers_emnr (EMNR *a, float* in, float* out) diff --git a/wdsp/fmd.cpp b/wdsp/fmd.cpp index 632b2b29c..3151f7823 100644 --- a/wdsp/fmd.cpp +++ b/wdsp/fmd.cpp @@ -94,17 +94,17 @@ FMD* FMD::create_fmd( float* in, float* out, int rate, - float deviation, - float f_low, - float f_high, - float fmin, - float fmax, - float zeta, - float omegaN, - float tau, - float afgain, + double deviation, + double f_low, + double f_high, + double fmin, + double fmax, + double zeta, + double omegaN, + double tau, + double afgain, int sntch_run, - float ctcss_freq, + double ctcss_freq, int nc_de, int mp_de, int nc_aud, @@ -176,8 +176,8 @@ void FMD::xfmd (FMD *a) if (a->run) { int i; - float det, del_out; - float vco[2], corr[2]; + double det, del_out; + double vco[2], corr[2]; for (i = 0; i < a->size; i++) { // pll @@ -272,7 +272,7 @@ void FMD::setSize_fmd (FMD *a, int size) * * ********************************************************************************************************/ -void FMD::SetFMDeviation (RXA& rxa, float deviation) +void FMD::SetFMDeviation (RXA& rxa, double deviation) { FMD *a; rxa.csDSP.lock(); @@ -282,7 +282,7 @@ void FMD::SetFMDeviation (RXA& rxa, float deviation) rxa.csDSP.unlock(); } -void FMD::SetCTCSSFreq (RXA& rxa, float freq) +void FMD::SetCTCSSFreq (RXA& rxa, double freq) { FMD *a; rxa.csDSP.lock(); @@ -368,9 +368,9 @@ void FMD::SetFMLimRun (RXA& rxa, int run) rxa.csDSP.unlock(); } -void FMD::SetFMLimGain (RXA& rxa, float gaindB) +void FMD::SetFMLimGain (RXA& rxa, double gaindB) { - float gain = pow(10.0, gaindB / 20.0); + double gain = pow(10.0, gaindB / 20.0); FMD *a = rxa.fmd.p; rxa.csDSP.lock(); if (a->lim_gain != gain) @@ -382,7 +382,7 @@ void FMD::SetFMLimGain (RXA& rxa, float gaindB) rxa.csDSP.unlock(); } -void FMD::SetFMAFFilter(RXA& rxa, float low, float high) +void FMD::SetFMAFFilter(RXA& rxa, double low, double high) { FMD *a = rxa.fmd.p; float* impulse; diff --git a/wdsp/fmd.hpp b/wdsp/fmd.hpp index fcb9855f6..8013973b1 100644 --- a/wdsp/fmd.hpp +++ b/wdsp/fmd.hpp @@ -44,29 +44,29 @@ public: int size; float* in; float* out; - float rate; - float f_low; // audio low cutoff - float f_high; // audio high cutoff + double rate; + double f_low; // audio low cutoff + double f_high; // audio high cutoff // pll - float fmin; // pll - minimum carrier freq to lock - float fmax; // pll - maximum carrier freq to lock - float omega_min; // pll - minimum lock check parameter - float omega_max; // pll - maximum lock check parameter - float zeta; // pll - damping factor; as coded, must be <=1.0 - float omegaN; // pll - natural frequency - float phs; // pll - phase accumulator - float omega; // pll - locked pll frequency - float fil_out; // pll - filter output - float g1, g2; // pll - filter gain parameters - float pllpole; // pll - pole frequency + double fmin; // pll - minimum carrier freq to lock + double fmax; // pll - maximum carrier freq to lock + double omega_min; // pll - minimum lock check parameter + double omega_max; // pll - maximum lock check parameter + double zeta; // pll - damping factor; as coded, must be <=1.0 + double omegaN; // pll - natural frequency + double phs; // pll - phase accumulator + double omega; // pll - locked pll frequency + double fil_out; // pll - filter output + double g1, g2; // pll - filter gain parameters + double pllpole; // pll - pole frequency // for dc removal - float tau; - float mtau; - float onem_mtau; - float fmdc; + double tau; + double mtau; + double onem_mtau; + double fmdc; // pll audio gain - float deviation; - float again; + double deviation; + double again; // for de-emphasis filter float* audio; FIRCORE *pde; @@ -76,16 +76,16 @@ public: FIRCORE *paud; int nc_aud; int mp_aud; - float afgain; + double afgain; // CTCSS removal SNOTCH *sntch; int sntch_run; - float ctcss_freq; + double ctcss_freq; // detector limiter WCPAGC *plim; int lim_run; - float lim_gain; - float lim_pre_gain; + double lim_gain; + double lim_pre_gain; static FMD* create_fmd ( int run, @@ -93,17 +93,17 @@ public: float* in, float* out, int rate, - float deviation, - float f_low, - float f_high, - float fmin, - float fmax, - float zeta, - float omegaN, - float tau, - float afgain, + double deviation, + double f_low, + double f_high, + double fmin, + double fmax, + double zeta, + double omegaN, + double tau, + double afgain, int sntch_run, - float ctcss_freq, + double ctcss_freq, int nc_de, int mp_de, int nc_aud, @@ -116,16 +116,16 @@ public: static void setSamplerate_fmd (FMD *a, int rate); static void setSize_fmd (FMD *a, int size); // RXA Properties - static void SetFMDeviation (RXA& rxa, float deviation); - static void SetCTCSSFreq (RXA& rxa, float freq); + static void SetFMDeviation (RXA& rxa, double deviation); + static void SetCTCSSFreq (RXA& rxa, double freq); static void SetCTCSSRun (RXA& rxa, int run); static void SetFMNCde (RXA& rxa, int nc); static void SetFMMPde (RXA& rxa, int mp); static void SetFMNCaud (RXA& rxa, int nc); static void SetFMMPaud (RXA& rxa, int mp); static void SetFMLimRun (RXA& rxa, int run); - static void SetFMLimGain (RXA& rxa, float gaindB); - static void SetFMAFFilter(RXA& rxa, float low, float high); + static void SetFMLimGain (RXA& rxa, double gaindB); + static void SetFMAFFilter(RXA& rxa, double low, double high); private: static void calc_fmd (FMD *a); diff --git a/wdsp/fmsq.cpp b/wdsp/fmsq.cpp index 3f2aac011..12027ca10 100644 --- a/wdsp/fmsq.cpp +++ b/wdsp/fmsq.cpp @@ -35,7 +35,7 @@ namespace WDSP { void FMSQ::calc_fmsq (FMSQ *a) { - float delta, theta; + double delta, theta; float* impulse; int i; // noise filter @@ -99,17 +99,17 @@ FMSQ* FMSQ::create_fmsq ( float* outsig, float* trigger, int rate, - float fc, - float* pllpole, - float tdelay, - float avtau, - float longtau, - float tup, - float tdown, - float tail_thresh, - float unmute_thresh, - float min_tail, - float max_tail, + double fc, + double* pllpole, + double tdelay, + double avtau, + double longtau, + double tup, + double tdown, + double tail_thresh, + double unmute_thresh, + double min_tail, + double max_tail, int nc, int mp ) @@ -264,7 +264,7 @@ void FMSQ::SetFMSQRun (RXA& rxa, int run) rxa.csDSP.unlock(); } -void FMSQ::SetFMSQThreshold (RXA& rxa, float threshold) +void FMSQ::SetFMSQThreshold (RXA& rxa, double threshold) { rxa.csDSP.lock(); rxa.fmsq.p->tail_thresh = threshold; diff --git a/wdsp/fmsq.hpp b/wdsp/fmsq.hpp index 41f592a3c..5f083b9ba 100644 --- a/wdsp/fmsq.hpp +++ b/wdsp/fmsq.hpp @@ -43,36 +43,36 @@ public: float* insig; // squelch input signal buffer float* outsig; // squelch output signal buffer float* trigger; // buffer used to trigger mute/unmute (may be same as input; matches timing of input buffer) - float rate; // sample rate + double rate; // sample rate float* noise; - float fc; // corner frequency for sig / noise detection - float* pllpole; // pointer to pole frequency of the fm demodulator pll + double fc; // corner frequency for sig / noise detection + double* pllpole; // pointer to pole frequency of the fm demodulator pll float F[4]; float G[4]; - float avtau; // time constant for averaging noise - float avm; - float onem_avm; - float avnoise; - float longtau; // time constant for long averaging - float longavm; - float onem_longavm; - float longnoise; + double avtau; // time constant for averaging noise + double avm; + double onem_avm; + double avnoise; + double longtau; // time constant for long averaging + double longavm; + double onem_longavm; + double longnoise; int state; // state machine control int count; - float tup; - float tdown; + double tup; + double tdown; int ntup; int ntdown; float* cup; float* cdown; - float tail_thresh; - float unmute_thresh; - float min_tail; - float max_tail; + double tail_thresh; + double unmute_thresh; + double min_tail; + double max_tail; int ready; - float ramp; - float rstep; - float tdelay; + double ramp; + double rstep; + double tdelay; int nc; int mp; FIRCORE *p; @@ -84,17 +84,17 @@ public: float* outsig, float* trigger, int rate, - float fc, - float* pllpole, - float tdelay, - float avtau, - float longtau, - float tup, - float tdown, - float tail_thresh, - float unmute_thresh, - float min_tail, - float max_tail, + double fc, + double* pllpole, + double tdelay, + double avtau, + double longtau, + double tup, + double tdown, + double tail_thresh, + double unmute_thresh, + double min_tail, + double max_tail, int nc, int mp ); @@ -106,7 +106,7 @@ public: static void setSize_fmsq (FMSQ *a, int size); // RXA Properties static void SetFMSQRun (RXA& rxa, int run); - static void SetFMSQThreshold (RXA& rxa, float threshold); + static void SetFMSQThreshold (RXA& rxa, double threshold); static void SetFMSQNC (RXA& rxa, int nc); static void SetFMSQMP (RXA& rxa, int mp); diff --git a/wdsp/ssql.cpp b/wdsp/ssql.cpp index b55c2c4ec..d62a8cb52 100644 --- a/wdsp/ssql.cpp +++ b/wdsp/ssql.cpp @@ -39,7 +39,7 @@ namespace WDSP { * * ********************************************************************************************************/ -FTOV* FTOV::create_ftov (int run, int size, int rate, int rsize, float fmax, float* in, float* out) +FTOV* FTOV::create_ftov (int run, int size, int rate, int rsize, double fmax, float* in, float* out) { FTOV *a = new FTOV; a->run = run; @@ -92,7 +92,7 @@ void FTOV::xftov (FTOV *a) a->rcount++; // increment the count } if (++a->rptr == a->rsize) a->rptr = 0; // increment and wrap the pointer as needed - a->out[0] = std::min (1.0f, (float)a->rcount / a->div); // calculate the output sample + a->out[0] = std::min (1.0, (double)a->rcount / a->div); // calculate the output sample a->inlast = a->in[a->size - 1]; // save the last input sample for next buffer for (int i = 1; i < a->size; i++) { @@ -108,7 +108,7 @@ void FTOV::xftov (FTOV *a) a->rcount++; // increment the count } if (++a->rptr == a->rsize) a->rptr = 0; // increment and wrap the pointer as needed - a->out[i] = std::min(1.0f, (float)a->rcount / a->div); // calculate the output sample + a->out[i] = std::min(1.0, (double)a->rcount / a->div); // calculate the output sample } } } @@ -120,15 +120,15 @@ void FTOV::xftov (FTOV *a) void SSQL::compute_ssql_slews(SSQL *a) { int i; - float delta, theta; - delta = PI / (float)a->ntup; + double delta, theta; + delta = PI / (double)a->ntup; theta = 0.0; for (i = 0; i <= a->ntup; i++) { a->cup[i] = a->muted_gain + (1.0 - a->muted_gain) * 0.5 * (1.0 - cos(theta)); theta += delta; } - delta = PI / (float)a->ntdown; + delta = PI / (double)a->ntdown; theta = 0.0; for (i = 0; i <= a->ntdown; i++) { @@ -187,15 +187,15 @@ SSQL* SSQL::create_ssql ( float* in, float* out, int rate, - float tup, - float tdown, - float muted_gain, - float tau_mute, - float tau_unmute, - float wthresh, - float tr_thresh, + double tup, + double tdown, + double muted_gain, + double tau_mute, + double tau_unmute, + double wthresh, + double tr_thresh, int rsize, - float fmax + double fmax ) { SSQL *a = new SSQL; @@ -355,7 +355,7 @@ void SSQL::SetSSQLRun (RXA& rxa, int run) rxa.csDSP.unlock(); } -void SSQL::SetSSQLThreshold (RXA& rxa, float threshold) +void SSQL::SetSSQLThreshold (RXA& rxa, double threshold) { // 'threshold' should be between 0.0 and 1.0 // WU2O testing: 0.16 is a good default for 'threshold'; => 0.08 for 'wthresh' @@ -364,7 +364,7 @@ void SSQL::SetSSQLThreshold (RXA& rxa, float threshold) rxa.csDSP.unlock(); } -void SSQL::SetSSQLTauMute (RXA& rxa, float tau_mute) +void SSQL::SetSSQLTauMute (RXA& rxa, double tau_mute) { // reasonable (wide) range is 0.1 to 2.0 // WU2O testing: 0.1 is good default value @@ -375,7 +375,7 @@ void SSQL::SetSSQLTauMute (RXA& rxa, float tau_mute) rxa.csDSP.unlock(); } -void SSQL::SetSSQLTauUnMute (RXA& rxa, float tau_unmute) +void SSQL::SetSSQLTauUnMute (RXA& rxa, double tau_unmute) { // reasonable (wide) range is 0.1 to 1.0 // WU2O testing: 0.1 is good default value diff --git a/wdsp/ssql.hpp b/wdsp/ssql.hpp index 2fac05bcc..1927957d1 100644 --- a/wdsp/ssql.hpp +++ b/wdsp/ssql.hpp @@ -39,17 +39,17 @@ public: int size; // buffer size int rate; // sample-rate int rsize; // rate * time_to_fill_ring, e.g., 48K/s * 50ms = 2400 - float fmax; // frequency (Hz) for full output, e.g., 2000 (Hz) + double fmax; // frequency (Hz) for full output, e.g., 2000 (Hz) float* in; // pointer to the intput buffer for ftov float* out; // pointer to the output buffer for ftov int* ring; // pointer to the base of the ring int rptr; // index into the ring - float inlast; // holds last sample from previous buffer + double inlast; // holds last sample from previous buffer int rcount; // count of zero-crossings currently in the ring - float div; // divisor for 'rcount' to produce output of 1.0 at 'fmax' - float eps; // minimum input change to count as a signal edge transition + double div; // divisor for 'rcount' to produce output of 1.0 at 'fmax' + double eps; // minimum input change to count as a signal edge transition - static FTOV* create_ftov (int run, int size, int rate, int rsize, float fmax, float* in, float* out); + static FTOV* create_ftov (int run, int size, int rate, int rsize, double fmax, float* in, float* out); static void destroy_ftov (FTOV *a); static void flush_ftov (FTOV *a); static void xftov (FTOV *a); @@ -70,13 +70,13 @@ public: int rate; // sample rate int state; // state machine control int count; // count variable for raised cosine transitions - float tup; // time for turn-on transition - float tdown; // time for turn-off transition + double tup; // time for turn-on transition + double tdown; // time for turn-off transition int ntup; // number of samples for turn-on transition int ntdown; // number of samples for turn-off transition float* cup; // coefficients for up-slew float* cdown; // coefficients for down-slew - float muted_gain; // audio gain while muted; 0.0 for complete silence + double muted_gain; // audio gain while muted; 0.0 for complete silence float* b1; // buffer to hold output of dc-block function float* ibuff; // buffer containing only 'I' component @@ -87,21 +87,21 @@ public: FTOV *cvtr; // pointer to F to V Converter data structure BQLP *filt; // pointer to Bi-Quad Low-Pass Filter data structure int ftov_rsize; // ring size for f_to_v converter - float ftov_fmax; // fmax for f_to_v converter + double ftov_fmax; // fmax for f_to_v converter // window detector - float wdtau; // window detector time constant - float wdmult; // window detector time constant multiplier - float wdaverage; // average signal value - float wthresh; // window threshold above/below average + double wdtau; // window detector time constant + double wdmult; // window detector time constant multiplier + double wdaverage; // average signal value + double wthresh; // window threshold above/below average // trigger - float tr_thresh; // trigger threshold: 100K/(100K+22K)=0.8197 - float tr_tau_unmute; // trigger unmute time-constant: (100K||220K)*10uF = 0.6875 - float tr_ss_unmute; // trigger steady-state level for unmute: 100K/(100K+220K)=0.3125 - float tr_tau_mute; // trigger mute time-constant: 220K*10uF = 2.2 - float tr_ss_mute; // trigger steady-state level for mute: 1.0 - float tr_voltage; // trigger voltage - float mute_mult; // multiplier for successive voltage calcs when muted - float unmute_mult; // multiplier for successive voltage calcs when unmuted + double tr_thresh; // trigger threshold: 100K/(100K+22K)=0.8197 + double tr_tau_unmute; // trigger unmute time-constant: (100K||220K)*10uF = 0.6875 + double tr_ss_unmute; // trigger steady-state level for unmute: 100K/(100K+220K)=0.3125 + double tr_tau_mute; // trigger mute time-constant: 220K*10uF = 2.2 + double tr_ss_mute; // trigger steady-state level for mute: 1.0 + double tr_voltage; // trigger voltage + double mute_mult; // multiplier for successive voltage calcs when muted + double unmute_mult; // multiplier for successive voltage calcs when unmuted int* tr_signal; // trigger signal, 0 or 1 static SSQL* create_ssql ( @@ -110,15 +110,15 @@ public: float* in, float* out, int rate, - float tup, - float tdown, - float muted_gain, - float tau_mute, - float tau_unmute, - float wthresh, - float tr_thresh, + double tup, + double tdown, + double muted_gain, + double tau_mute, + double tau_unmute, + double wthresh, + double tr_thresh, int rsize, - float fmax + double fmax ); static void destroy_ssql (SSQL *a); static void flush_ssql (SSQL *a); @@ -128,9 +128,9 @@ public: static void setSize_ssql (SSQL *a, int size); // RXA Properties static void SetSSQLRun (RXA& rxa, int run); - static void SetSSQLThreshold (RXA& rxa, float threshold); - static void SetSSQLTauMute (RXA& rxa, float tau_mute); - static void SetSSQLTauUnMute (RXA& rxa, float tau_unmute); + static void SetSSQLThreshold (RXA& rxa, double threshold); + static void SetSSQLTauMute (RXA& rxa, double tau_mute); + static void SetSSQLTauUnMute (RXA& rxa, double tau_unmute); private: static void compute_ssql_slews(SSQL *a);