From ffef9ab48f81cd8020ddc8fb0346fbd8b0c46c9f Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 4 Jul 2024 21:37:56 +0200 Subject: [PATCH] WDSP receiver: FM options --- plugins/channelrx/wdsprx/CMakeLists.txt | 3 + plugins/channelrx/wdsprx/wdsprxfmdialog.cpp | 153 ++++++++ plugins/channelrx/wdsprx/wdsprxfmdialog.h | 83 ++++ plugins/channelrx/wdsprx/wdsprxfmdialog.ui | 395 ++++++++++++++++++++ plugins/channelrx/wdsprx/wdsprxgui.cpp | 77 ++++ plugins/channelrx/wdsprx/wdsprxgui.h | 3 + plugins/channelrx/wdsprx/wdsprxgui.ui | 70 ++-- plugins/channelrx/wdsprx/wdsprxsettings.cpp | 90 +++-- plugins/channelrx/wdsprx/wdsprxsettings.h | 23 +- plugins/channelrx/wdsprx/wdsprxsink.cpp | 29 ++ wdsp/RXA.cpp | 1 - 11 files changed, 860 insertions(+), 67 deletions(-) create mode 100644 plugins/channelrx/wdsprx/wdsprxfmdialog.cpp create mode 100644 plugins/channelrx/wdsprx/wdsprxfmdialog.h create mode 100644 plugins/channelrx/wdsprx/wdsprxfmdialog.ui diff --git a/plugins/channelrx/wdsprx/CMakeLists.txt b/plugins/channelrx/wdsprx/CMakeLists.txt index a411d3ddd..ea4ce5d61 100644 --- a/plugins/channelrx/wdsprx/CMakeLists.txt +++ b/plugins/channelrx/wdsprx/CMakeLists.txt @@ -36,6 +36,8 @@ if(NOT SERVER_MODE) wdsprxdnbdialog.ui wdsprxdnrdialog.cpp wdsprxdnrdialog.ui + wdsprxfmdialog.cpp + wdsprxfmdialog.ui wdsprxgui.cpp wdsprxgui.ui ) @@ -47,6 +49,7 @@ if(NOT SERVER_MODE) wdsprxcwpeakdialog.h wdsprxdnbdialog.h wdsprxdnrdialog.h + wdsprxfmdialog.h ) set(TARGET_NAME wdsprx) set(TARGET_LIB "Qt::Widgets") diff --git a/plugins/channelrx/wdsprx/wdsprxfmdialog.cpp b/plugins/channelrx/wdsprx/wdsprxfmdialog.cpp new file mode 100644 index 000000000..73a0aa358 --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxfmdialog.cpp @@ -0,0 +1,153 @@ +/////////////////////////////////////////////////////////////////////////////////////// +// 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 "dsp/ctcssfrequencies.h" +#include "wdsprxfmdialog.h" +#include "ui_wdsprxfmdialog.h" + +WDSPRxFMDialog::WDSPRxFMDialog(QWidget* parent) : + QDialog(parent), + ui(new Ui::WDSPRxFMDialog) +{ + ui->setupUi(this); + + for (int i = 0; i < CTCSSFrequencies::m_nbFreqs; i++) { + ui->ctcssNotchFrequency->addItem(QString("%1").arg((double) CTCSSFrequencies::m_Freqs[i], 0, 'f', 1)); + } +} + +WDSPRxFMDialog::~WDSPRxFMDialog() +{ + delete ui; +} + +void WDSPRxFMDialog::setDeviation(double deviation) +{ + ui->deviation->blockSignals(true); + ui->deviation->setValue((int) round(deviation/100.0)); + ui->deviationText->setText(QString("%1").arg(deviation/1000.0, 0, 'f', 1)); + ui->deviation->blockSignals(false); + m_deviation = deviation; +} + +void WDSPRxFMDialog::setAFLow(double afLow) +{ + ui->afLow->blockSignals(true); + ui->afLow->setValue((int) round(afLow/100.0)); + ui->afLowText->setText(QString("%1").arg(afLow/1000.0, 0, 'f', 1)); + ui->afLow->blockSignals(false); + m_afLow = afLow; +} + +void WDSPRxFMDialog::setAFHigh(double afHigh) +{ + ui->afHigh->blockSignals(true); + ui->afHigh->setValue((int) round(afHigh/100.0)); + ui->afHighText->setText(QString("%1").arg(afHigh/1000.0, 0, 'f', 1)); + ui->afHigh->blockSignals(false); + m_afHigh = afHigh; +} + +void WDSPRxFMDialog::setAFLimiter(bool afLimiter) +{ + ui->afLimiter->blockSignals(true); + ui->afLimiter->setChecked(afLimiter); + ui->afLimiter->blockSignals(false); + m_afLimiter = afLimiter; +} + +void WDSPRxFMDialog::setAFLimiterGain(double gain) +{ + ui->afLimiterGain->blockSignals(true); + ui->afLimiterGain->setValue((int) gain); + ui->afLimiterGainText->setText(QString("%1").arg(gain, 0, 'f', 0)); + ui->afLimiterGain->blockSignals(false); + m_afLimiterGain = gain; +} + +void WDSPRxFMDialog::setCTCSSNotch(bool notch) +{ + ui->ctcssNotch->blockSignals(true); + ui->ctcssNotch->setChecked(notch); + ui->ctcssNotch->blockSignals(false); + m_ctcssNotch = notch; +} + +void WDSPRxFMDialog::setCTCSSNotchFrequency(double frequency) +{ + int i = 0; + + for (; i < CTCSSFrequencies::m_nbFreqs; i++) + { + if (frequency <= CTCSSFrequencies::m_Freqs[i]) { + break; + } + } + + ui->ctcssNotchFrequency->blockSignals(true); + ui->ctcssNotchFrequency->setCurrentIndex(i); + ui->ctcssNotchFrequency->blockSignals(false); + m_ctcssNotchFrequency = CTCSSFrequencies::m_Freqs[i]; +} + +void WDSPRxFMDialog::on_deviation_valueChanged(int value) +{ + m_deviation = value * 100.0; + ui->deviationText->setText(QString("%1").arg(value/10.0, 0, 'f', 1)); + emit valueChanged(ChangedDeviation); +} + +void WDSPRxFMDialog::on_afLow_valueChanged(int value) +{ + m_afLow = value * 100.0; + ui->afLowText->setText(QString("%1").arg(value/10.0, 0, 'f', 1)); + emit valueChanged(ChangedAFLow); +} +void WDSPRxFMDialog::on_afHigh_valueChanged(int value) +{ + m_afHigh = value * 100.0; + ui->afHighText->setText(QString("%1").arg(value/10.0, 0, 'f', 1)); + emit valueChanged(ChangedAFHigh); +} + +void WDSPRxFMDialog::on_afLimiter_clicked(bool checked) +{ + m_afLimiter = checked; + emit valueChanged(ChangedAFLimiter); +} + +void WDSPRxFMDialog::on_afLimiterGain_valueChanged(int value) +{ + m_afLimiterGain = (double) value; + ui->afLimiterGainText->setText(QString("%1").arg(value)); + emit valueChanged(ChangedAFLimiterGain); +} + +void WDSPRxFMDialog::on_ctcssNotch_clicked(bool checked) +{ + m_ctcssNotch = checked; + emit valueChanged(ChangedCTCSSNotch); +} + +void WDSPRxFMDialog::on_ctcssNotchFrequency_valueChanged(int value) +{ + if (value > CTCSSFrequencies::m_nbFreqs) { + return; + } + + m_ctcssNotchFrequency = CTCSSFrequencies::m_Freqs[value]; + emit valueChanged(ChangedCTCSSNotchFrequency); +} diff --git a/plugins/channelrx/wdsprx/wdsprxfmdialog.h b/plugins/channelrx/wdsprx/wdsprxfmdialog.h new file mode 100644 index 000000000..2a695f489 --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxfmdialog.h @@ -0,0 +1,83 @@ +/////////////////////////////////////////////////////////////////////////////////////// +// 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_WDSPRXFMDIALOG_H +#define INCLUDE_WDSPRXFMDIALOG_H + +#include + +#include "export.h" +#include "wdsprxsettings.h" + +namespace Ui { + class WDSPRxFMDialog; +} + +class SDRGUI_API WDSPRxFMDialog : public QDialog { + Q_OBJECT +public: + enum ValueChanged { + ChangedDeviation, + ChangedAFLow, + ChangedAFHigh, + ChangedAFLimiter, + ChangedAFLimiterGain, + ChangedCTCSSNotch, + ChangedCTCSSNotchFrequency, + }; + + explicit WDSPRxFMDialog(QWidget* parent = nullptr); + ~WDSPRxFMDialog(); + + void setDeviation(double deviation); + void setAFLow(double afLow); + void setAFHigh(double afHigh); + void setAFLimiter(bool afLimiter); + void setAFLimiterGain(double gain); + void setCTCSSNotch(bool notch); + void setCTCSSNotchFrequency(double frequency); + + double getDeviation() const { return m_deviation; } + double getAFLow() const { return m_afLow; } + double getAFHigh() const { return m_afHigh; } + bool getAFLimiter() const { return m_afLimiter; } + double getAFLimiterGain() const { return m_afLimiterGain; } + bool getCTCSSNotch() const { return m_ctcssNotch; } + double getCTCSSNotchFrequency() { return m_ctcssNotchFrequency; } + +signals: + void valueChanged(int valueChanged); + +private: + Ui::WDSPRxFMDialog *ui; + double m_deviation; + double m_afLow; + double m_afHigh; + bool m_afLimiter; + double m_afLimiterGain; + bool m_ctcssNotch; + double m_ctcssNotchFrequency; + +private slots: + void on_deviation_valueChanged(int value); + void on_afLow_valueChanged(int value); + void on_afHigh_valueChanged(int value); + void on_afLimiter_clicked(bool checked); + void on_afLimiterGain_valueChanged(int value); + void on_ctcssNotch_clicked(bool checked); + void on_ctcssNotchFrequency_valueChanged(int value); +}; +#endif diff --git a/plugins/channelrx/wdsprx/wdsprxfmdialog.ui b/plugins/channelrx/wdsprx/wdsprxfmdialog.ui new file mode 100644 index 000000000..4e0d8f684 --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxfmdialog.ui @@ -0,0 +1,395 @@ + + + WDSPRxFMDialog + + + + 0 + 0 + 304 + 198 + + + + FM Options + + + + + + + + Dev (kHz) + + + + + + + + 24 + 24 + + + + FM deviation (kHz) + + + 0 + + + 200 + + + 1 + + + 35 + + + + + + + 20.0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 60 + 0 + + + + + 50 + 16777215 + + + + AF low + + + + + + + + 16777215 + 16 + + + + AF low pass filter cutoff frequency (kHz) + + + 0 + + + 50 + + + 1 + + + 3 + + + Qt::Horizontal + + + false + + + QSlider::NoTicks + + + 5 + + + + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + 0.3k + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + 60 + 0 + + + + + 80 + 16777215 + + + + AF High + + + + + + + + 16777215 + 16 + + + + AF high pass filter cutoff frequency (kHz) + + + 0 + + + 50 + + + 1 + + + 30 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + 3.0k + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + AF volume limiter + + + AF Limiter + + + + + + + Gain (dB) + + + + + + + + 24 + 24 + + + + AF volume limter gain (dB) + + + 0 + + + 30 + + + 1 + + + 10 + + + + + + + 20 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + CTCSS Notch filter + + + CTCSS Notch + + + + + + + Freq (Hz) + + + + + + + CTCSS Notch frequency (Hz) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + TickedSlider + QSlider +
gui/tickedslider.h
+
+
+ + + + buttonBox + accepted() + WDSPRxFMDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + WDSPRxFMDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/plugins/channelrx/wdsprx/wdsprxgui.cpp b/plugins/channelrx/wdsprx/wdsprxgui.cpp index 9bc7c030b..e69474c76 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.cpp +++ b/plugins/channelrx/wdsprx/wdsprxgui.cpp @@ -41,6 +41,7 @@ #include "wdsprxdnbdialog.h" #include "wdsprxdnrdialog.h" #include "wdsprxamdialog.h" +#include "wdsprxfmdialog.h" #include "wdsprxcwpeakdialog.h" WDSPRxGUI* WDSPRxGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel) @@ -309,10 +310,18 @@ void WDSPRxGUI::on_profileIndex_valueChanged(int value) m_settings.m_nr2ArtifactReduction = m_settings.m_profiles[m_settings.m_profileIndex].m_nr2ArtifactReduction; // demod m_settings.m_demod = m_settings.m_profiles[m_settings.m_profileIndex].m_demod; + m_settings.m_amFadeLevel = m_settings.m_profiles[m_settings.m_profileIndex].m_amFadeLevel; m_settings.m_cwPeaking = m_settings.m_profiles[m_settings.m_profileIndex].m_cwPeaking; m_settings.m_cwPeakFrequency = m_settings.m_profiles[m_settings.m_profileIndex].m_cwPeakFrequency; m_settings.m_cwBandwidth = m_settings.m_profiles[m_settings.m_profileIndex].m_cwBandwidth; m_settings.m_cwGain = m_settings.m_profiles[m_settings.m_profileIndex].m_cwGain; + m_settings.m_fmDeviation = m_settings.m_profiles[m_settings.m_profileIndex].m_fmDeviation; + m_settings.m_fmAFLow = m_settings.m_profiles[m_settings.m_profileIndex].m_fmAFLow; + m_settings.m_fmAFHigh = m_settings.m_profiles[m_settings.m_profileIndex].m_fmAFHigh; + m_settings.m_fmAFLimiter = m_settings.m_profiles[m_settings.m_profileIndex].m_fmAFLimiter; + 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; displaySettings(); applyBandwidths(m_settings.m_profiles[m_settings.m_profileIndex].m_spanLog2, true); // does applySettings(true) } @@ -414,6 +423,7 @@ WDSPRxGUI::WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam m_dnbDialog(nullptr), m_dnrDialog(nullptr), m_amDialog(nullptr), + m_fmDialog(nullptr), m_cwPeakDialog(nullptr) { setAttribute(Qt::WA_DeleteOnClose, true); @@ -1023,6 +1033,23 @@ void WDSPRxGUI::demodSetupDialog(const QPoint& p) m_amDialog->deleteLater(); m_amDialog = nullptr; } + else if (m_settings.m_demod == WDSPRxProfile::DemodFMN) + { + m_fmDialog = new WDSPRxFMDialog(); + m_fmDialog->move(p); + m_fmDialog->setDeviation(m_settings.m_fmDeviation); + m_fmDialog->setAFLow(m_settings.m_fmAFLow); + m_fmDialog->setAFHigh(m_settings.m_fmAFHigh); + m_fmDialog->setAFLimiter(m_settings.m_fmAFLimiter); + m_fmDialog->setAFLimiterGain(m_settings.m_fmAFLimiterGain); + m_fmDialog->setCTCSSNotch(m_settings.m_fmCTCSSNotch); + m_fmDialog->setCTCSSNotchFrequency(m_settings.m_fmCTCSSNotchFrequency); + QObject::connect(m_fmDialog, &WDSPRxFMDialog::valueChanged, this, &WDSPRxGUI::fmSetup); + m_fmDialog->exec(); + QObject::disconnect(m_fmDialog, &WDSPRxFMDialog::valueChanged, this, &WDSPRxGUI::fmSetup); + m_fmDialog->deleteLater(); + m_fmDialog = nullptr; + } } void WDSPRxGUI::amSetup(int iValueChanged) @@ -1045,6 +1072,56 @@ void WDSPRxGUI::amSetup(int iValueChanged) } } +void WDSPRxGUI::fmSetup(int iValueChanged) +{ + if (!m_fmDialog) { + return; + } + + WDSPRxFMDialog::ValueChanged valueChanged = (WDSPRxFMDialog::ValueChanged) iValueChanged; + + switch (valueChanged) + { + case WDSPRxFMDialog::ChangedDeviation: + m_settings.m_fmDeviation = m_fmDialog->getDeviation(); + m_settings.m_profiles[m_settings.m_profileIndex].m_fmDeviation = m_settings.m_fmDeviation; + applySettings(); + break; + case WDSPRxFMDialog::ChangedAFLow: + m_settings.m_fmAFLow = m_fmDialog->getAFLow(); + m_settings.m_profiles[m_settings.m_profileIndex].m_fmAFLow = m_settings.m_fmAFLow; + applySettings(); + break; + case WDSPRxFMDialog::ChangedAFHigh: + m_settings.m_fmAFHigh = m_fmDialog->getAFHigh(); + m_settings.m_profiles[m_settings.m_profileIndex].m_fmAFHigh = m_settings.m_fmAFHigh; + applySettings(); + break; + case WDSPRxFMDialog::ChangedAFLimiter: + m_settings.m_fmAFLimiter = m_fmDialog->getAFLimiter(); + m_settings.m_profiles[m_settings.m_profileIndex].m_fmAFLimiter = m_settings.m_fmAFLimiter; + applySettings(); + break; + case WDSPRxFMDialog::ChangedAFLimiterGain: + m_settings.m_fmAFLimiterGain = m_fmDialog->getAFLimiterGain(); + m_settings.m_profiles[m_settings.m_profileIndex].m_fmAFLimiterGain = m_settings.m_fmAFLimiterGain; + applySettings(); + break; + case WDSPRxFMDialog::ChangedCTCSSNotch: + m_settings.m_fmCTCSSNotch = m_fmDialog->getCTCSSNotch(); + m_settings.m_profiles[m_settings.m_profileIndex].m_fmCTCSSNotch = m_settings.m_fmCTCSSNotch; + applySettings(); + break; + case WDSPRxFMDialog::ChangedCTCSSNotchFrequency: + m_settings.m_fmCTCSSNotchFrequency = m_fmDialog->getCTCSSNotchFrequency(); + m_settings.m_profiles[m_settings.m_profileIndex].m_fmCTCSSNotchFrequency = m_settings.m_fmCTCSSNotchFrequency; + applySettings(); + break; + default: + break; + } +} + void WDSPRxGUI::tick() { double powDbAvg, powDbPeak; diff --git a/plugins/channelrx/wdsprx/wdsprxgui.h b/plugins/channelrx/wdsprx/wdsprxgui.h index 8971b9214..92e945a14 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.h +++ b/plugins/channelrx/wdsprx/wdsprxgui.h @@ -38,6 +38,7 @@ class WDSPRxAGCDialog; class WDSPRxDNBDialog; class WDSPRxDNRDialog; class WDSPRxAMDialog; +class WDSPRxFMDialog; class WDSPRxCWPeakDialog; class SpectrumVis; class BasebandSampleSink; @@ -98,6 +99,7 @@ private: WDSPRxDNBDialog* m_dnbDialog; WDSPRxDNRDialog* m_dnrDialog; WDSPRxAMDialog* m_amDialog; + WDSPRxFMDialog* m_fmDialog; WDSPRxCWPeakDialog* m_cwPeakDialog; QIcon m_iconDSBUSB; @@ -152,6 +154,7 @@ private slots: void cwPeakSetup(int valueChanged); void demodSetupDialog(const QPoint& p); void amSetup(int valueChanged); + void fmSetup(int valueChanged); void tick(); }; diff --git a/plugins/channelrx/wdsprx/wdsprxgui.ui b/plugins/channelrx/wdsprx/wdsprxgui.ui index d070e015b..04044f7d2 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.ui +++ b/plugins/channelrx/wdsprx/wdsprxgui.ui @@ -6,7 +6,7 @@ 0 0 - 452 + 514 179 @@ -36,7 +36,7 @@ 0 0 - 450 + 501 181 @@ -212,6 +212,39 @@ + + + + + 60 + 16777215 + + + + Modulation (right click for options) + + + + SSB + + + + + AM + + + + + SAM + + + + + FM + + + + @@ -752,39 +785,6 @@ - - - - - 60 - 16777215 - - - - Modulation (right click for options) - - - - SSB - - - - - AM - - - - - SAM - - - - - FM - - - - diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.cpp b/plugins/channelrx/wdsprx/wdsprxsettings.cpp index 3d58f3430..ddd347551 100644 --- a/plugins/channelrx/wdsprx/wdsprxsettings.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsettings.cpp @@ -75,6 +75,13 @@ void WDSPRxSettings::resetToDefaults() m_cwPeakFrequency = 600.0; m_cwBandwidth = 100.0; m_cwGain = 2.0; + m_fmDeviation = 2500.0; + m_fmAFLow = 300.0; + m_fmAFHigh = 3000.0; + m_fmAFLimiter = false; + m_fmAFLimiterGain = 10.0; + m_fmCTCSSNotch = false; + m_fmCTCSSNotchFrequency = 67.0; // m_volume = 1.0; m_inputFrequencyOffset = 0; @@ -136,6 +143,13 @@ QByteArray WDSPRxSettings::serialize() const s.writeDouble(42, m_cwPeakFrequency); s.writeDouble(43, m_cwBandwidth); s.writeDouble(44, m_cwGain); + s.writeDouble(45, m_fmDeviation); + s.writeDouble(46, m_fmAFLow); + s.writeDouble(47, m_fmAFHigh); + s.writeBool( 48, m_fmAFLimiter); + s.writeDouble(49, m_fmAFLimiterGain); + s.writeBool( 50, m_fmCTCSSNotch); + s.writeDouble(51, m_fmCTCSSNotchFrequency); // s.writeString(70, m_title); s.writeString(71, m_audioDeviceName); @@ -157,41 +171,48 @@ QByteArray WDSPRxSettings::serialize() const for (unsigned int i = 0; i < 10; i++) { - s.writeS32 (104 + 50*i, (int) m_profiles[i].m_demod); + s.writeS32 (104 + 100*i, (int) m_profiles[i].m_demod); // Filter - s.writeS32 (100 + 50*i, m_profiles[i].m_spanLog2); - s.writeS32 (101 + 50*i, m_profiles[i].m_highCutoff / 100.0); - s.writeS32 (102 + 50*i, m_profiles[i].m_lowCutoff / 100.0); - s.writeS32 (103 + 50*i, m_profiles[i].m_fftWindow); + s.writeS32 (100 + 100*i, m_profiles[i].m_spanLog2); + s.writeS32 (101 + 100*i, m_profiles[i].m_highCutoff / 100.0); + s.writeS32 (102 + 100*i, m_profiles[i].m_lowCutoff / 100.0); + s.writeS32 (103 + 100*i, m_profiles[i].m_fftWindow); // AGC - s.writeBool (110 + 50*i, m_profiles[i].m_agc); - s.writeS32 (111 + 50*i, (int) m_profiles[i].m_agcMode); - s.writeS32 (112 + 50*i, m_profiles[i].m_agcGain); - s.writeS32 (113 + 50*i, m_profiles[i].m_agcSlope); - s.writeS32 (114 + 50*i, m_profiles[i].m_agcHangThreshold); + s.writeBool (110 + 100*i, m_profiles[i].m_agc); + s.writeS32 (111 + 100*i, (int) m_profiles[i].m_agcMode); + s.writeS32 (112 + 100*i, m_profiles[i].m_agcGain); + s.writeS32 (113 + 100*i, m_profiles[i].m_agcSlope); + s.writeS32 (114 + 100*i, m_profiles[i].m_agcHangThreshold); // Noise blanjer - s.writeBool (120 + 50*i, m_profiles[i].m_dnb); - s.writeS32 (121 + 50*i, (int) m_profiles[i].m_nbScheme); - s.writeS32 (122 + 50*i, (int) m_profiles[i].m_nb2Mode); - s.writeDouble(123 + 50*i, m_profiles[i].m_nbSlewTime); - s.writeDouble(124 + 50*i, m_profiles[i].m_nbLeadTime); - s.writeDouble(125 + 50*i, m_profiles[i].m_nbLagTime); - s.writeS32 (126 + 50*i, m_profiles[i].m_nbThreshold); - s.writeDouble(127 + 50*i, m_profiles[i].m_nbAvgTime); + s.writeBool (120 + 100*i, m_profiles[i].m_dnb); + s.writeS32 (121 + 100*i, (int) m_profiles[i].m_nbScheme); + s.writeS32 (122 + 100*i, (int) m_profiles[i].m_nb2Mode); + s.writeDouble(123 + 100*i, m_profiles[i].m_nbSlewTime); + s.writeDouble(124 + 100*i, m_profiles[i].m_nbLeadTime); + s.writeDouble(125 + 100*i, m_profiles[i].m_nbLagTime); + s.writeS32 (126 + 100*i, m_profiles[i].m_nbThreshold); + s.writeDouble(127 + 100*i, m_profiles[i].m_nbAvgTime); // Noise reduction - s.writeBool (130 + 50*i, m_profiles[i].m_dnr); - s.writeBool (132 + 50*i, m_profiles[i].m_anf); - s.writeS32 (133 + 50*i, (int) m_profiles[i].m_nrScheme); - s.writeS32 (134 + 50*i, (int) m_profiles[i].m_nr2Gain); - s.writeS32 (135 + 50*i, (int) m_profiles[i].m_nr2NPE); - s.writeS32 (136 + 50*i, (int) m_profiles[i].m_nrPosition); - s.writeBool (137 + 50*i, m_profiles[i].m_nr2ArtifactReduction); + s.writeBool (130 + 100*i, m_profiles[i].m_dnr); + s.writeBool (132 + 100*i, m_profiles[i].m_anf); + s.writeS32 (133 + 100*i, (int) m_profiles[i].m_nrScheme); + s.writeS32 (134 + 100*i, (int) m_profiles[i].m_nr2Gain); + s.writeS32 (135 + 100*i, (int) m_profiles[i].m_nr2NPE); + s.writeS32 (136 + 100*i, (int) m_profiles[i].m_nrPosition); + s.writeBool (137 + 100*i, m_profiles[i].m_nr2ArtifactReduction); // Demods - s.writeBool (140 + 50*i, m_profiles[i].m_amFadeLevel); - s.writeBool (141 + 50*i, m_profiles[i].m_cwPeaking); - s.writeDouble(142 + 50*i, m_profiles[i].m_cwPeakFrequency); - s.writeDouble(143 + 50*i, m_profiles[i].m_cwBandwidth); - s.writeDouble(144 + 50*i, m_profiles[i].m_cwGain); + s.writeBool (140 + 100*i, m_profiles[i].m_amFadeLevel); + s.writeBool (141 + 100*i, m_profiles[i].m_cwPeaking); + s.writeDouble(142 + 100*i, m_profiles[i].m_cwPeakFrequency); + s.writeDouble(143 + 100*i, m_profiles[i].m_cwBandwidth); + s.writeDouble(144 + 100*i, m_profiles[i].m_cwGain); + s.writeDouble(145 + 100*i, m_profiles[i].m_fmDeviation); + s.writeDouble(146 + 100*i, m_profiles[i].m_fmAFLow); + s.writeDouble(147 + 100*i, m_profiles[i].m_fmAFHigh); + s.writeBool( 148 + 100*i, m_profiles[i].m_fmAFLimiter); + 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); } return s.final(); @@ -264,6 +285,15 @@ bool WDSPRxSettings::deserialize(const QByteArray& data) d.readBool( 40, &m_amFadeLevel, false); d.readBool( 41, &m_cwPeaking, false); d.readDouble(42, &m_cwPeakFrequency, 600.0); + d.readDouble(43, &m_cwBandwidth, 100.0); + d.readDouble(44, &m_cwGain, 2.0); + d.readDouble(45, &m_fmDeviation, 2500.0); + d.readDouble(46, &m_fmAFLow, 300.0); + d.readDouble(47, &m_fmAFHigh, 3000.0); + d.readBool( 48, &m_fmAFLimiter, false); + d.readDouble(49, &m_fmAFLimiterGain, 10.0); + d.readBool( 50, &m_fmCTCSSNotch, false); + d.readDouble(51, &m_fmCTCSSNotchFrequency, 67.0); // d.readString(70, &m_title, "WDSP Receiver"); d.readString(71, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName); diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.h b/plugins/channelrx/wdsprx/wdsprxsettings.h index 9b77855a1..67938990b 100644 --- a/plugins/channelrx/wdsprx/wdsprxsettings.h +++ b/plugins/channelrx/wdsprx/wdsprxsettings.h @@ -112,6 +112,13 @@ struct WDSPRxProfile double m_cwPeakFrequency; double m_cwBandwidth; double m_cwGain; + double m_fmDeviation; + double m_fmAFLow; + double m_fmAFHigh; + bool m_fmAFLimiter; + double m_fmAFLimiterGain; + bool m_fmCTCSSNotch; + double m_fmCTCSSNotchFrequency; WDSPRxProfile() : m_demod(DemodSSB), @@ -143,7 +150,14 @@ struct WDSPRxProfile m_cwPeaking(false), m_cwPeakFrequency(600.0), m_cwBandwidth(100.0), - m_cwGain(2.0) + m_cwGain(2.0), + m_fmDeviation(2500.0), + m_fmAFLow(300.0), + m_fmAFHigh(3000.0), + m_fmAFLimiter(false), + m_fmAFLimiterGain(10.0), + m_fmCTCSSNotch(false), + m_fmCTCSSNotchFrequency(67.0) {} }; @@ -188,6 +202,13 @@ struct WDSPRxSettings double m_cwPeakFrequency; double m_cwBandwidth; double m_cwGain; + double m_fmDeviation; + double m_fmAFLow; + double m_fmAFHigh; + bool m_fmAFLimiter; + double m_fmAFLimiterGain; + bool m_fmCTCSSNotch; + double m_fmCTCSSNotchFrequency; quint32 m_rgbColor; QString m_title; diff --git a/plugins/channelrx/wdsprx/wdsprxsink.cpp b/plugins/channelrx/wdsprx/wdsprxsink.cpp index 7c9108763..50b4a44cb 100644 --- a/plugins/channelrx/wdsprx/wdsprxsink.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsink.cpp @@ -37,6 +37,7 @@ #include "anb.hpp" #include "nob.hpp" #include "amd.hpp" +#include "fmd.hpp" #include "iir.cpp" #include "wdsprxsink.h" @@ -627,6 +628,34 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force) WDSP::AMD::SetAMDFadeLevel(*m_rxa, settings.m_amFadeLevel); } + // FM options + + if ((m_settings.m_fmDeviation != settings.m_fmDeviation) || force) { + WDSP::FMD::SetFMDeviation(*m_rxa, settings.m_fmDeviation); + } + + if ((m_settings.m_fmAFLow != settings.m_fmAFLow) + || (m_settings.m_fmAFHigh != settings.m_fmAFHigh) || force) + { + WDSP::FMD::SetFMAFFilter(*m_rxa, settings.m_fmAFLow, settings.m_fmAFHigh); + } + + if ((m_settings.m_fmAFLimiter != settings.m_fmAFLimiter) || force) { + WDSP::FMD::SetFMLimRun(*m_rxa, settings.m_fmAFLimiter ? 1 : 0); + } + + if ((m_settings.m_fmAFLimiterGain != settings.m_fmAFLimiterGain) || force) { + WDSP::FMD::SetFMLimGain(*m_rxa, settings.m_fmAFLimiterGain); + } + + if ((m_settings.m_fmCTCSSNotch != settings.m_fmCTCSSNotch) || force) { + WDSP::FMD::SetCTCSSRun(*m_rxa, settings.m_fmCTCSSNotch ? 1 : 0); + } + + if ((m_settings.m_fmCTCSSNotchFrequency != settings.m_fmCTCSSNotchFrequency) || force) { + WDSP::FMD::SetCTCSSFreq(*m_rxa, settings.m_fmCTCSSNotchFrequency); + } + // Audio panel if ((m_settings.m_volume != settings.m_volume) || force) { diff --git a/wdsp/RXA.cpp b/wdsp/RXA.cpp index 4952b9e43..742218a85 100644 --- a/wdsp/RXA.cpp +++ b/wdsp/RXA.cpp @@ -932,7 +932,6 @@ void RXA::SetMode (RXA& rxa, int mode) break; case RXA_FM: rxa.fmd.p->run = 1; - rxa.agc.p->run = 0; break; default: