From a4f08dc210bdc6c5514245854f2190c3424881dc Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 8 Jul 2024 23:44:10 +0200 Subject: [PATCH] WDSP receiver: fixed FM demod amd implement equalizer --- .github/workflows/sdrangel.yml | 1 + CMakeLists.txt | 2 +- plugins/channelrx/wdsprx/CMakeLists.txt | 3 + plugins/channelrx/wdsprx/wdsprxeqdialog.cpp | 252 +++++ plugins/channelrx/wdsprx/wdsprxeqdialog.h | 79 ++ plugins/channelrx/wdsprx/wdsprxeqdialog.ui | 889 ++++++++++++++++++ plugins/channelrx/wdsprx/wdsprxfmdialog.ui | 26 +- plugins/channelrx/wdsprx/wdsprxgui.cpp | 56 +- plugins/channelrx/wdsprx/wdsprxgui.h | 5 + plugins/channelrx/wdsprx/wdsprxgui.ui | 13 + plugins/channelrx/wdsprx/wdsprxsettings.cpp | 112 ++- .../channelrx/wdsprx/wdsprxsettings.cpp.orig | 422 --------- .../channelrx/wdsprx/wdsprxsettings.cpp.rej | 18 - plugins/channelrx/wdsprx/wdsprxsettings.h | 19 +- plugins/channelrx/wdsprx/wdsprxsink.cpp | 13 + .../morsedecoder/morsedecodersettings.cpp | 1 + wdsp/eq.cpp | 4 +- wdsp/eq.hpp | 4 +- wdsp/fmd.cpp | 4 +- 19 files changed, 1462 insertions(+), 461 deletions(-) create mode 100644 plugins/channelrx/wdsprx/wdsprxeqdialog.cpp create mode 100644 plugins/channelrx/wdsprx/wdsprxeqdialog.h create mode 100644 plugins/channelrx/wdsprx/wdsprxeqdialog.ui delete mode 100644 plugins/channelrx/wdsprx/wdsprxsettings.cpp.orig delete mode 100644 plugins/channelrx/wdsprx/wdsprxsettings.cpp.rej diff --git a/.github/workflows/sdrangel.yml b/.github/workflows/sdrangel.yml index c468e7399..d2fb392e2 100644 --- a/.github/workflows/sdrangel.yml +++ b/.github/workflows/sdrangel.yml @@ -6,6 +6,7 @@ on: push: branches: - master + - feature-* - mac_ci tags: - 'v*' diff --git a/CMakeLists.txt b/CMakeLists.txt index a7e6e50b9..92af1b54a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -860,7 +860,7 @@ if (FFTW3F_FOUND) set(FT8_SUPPORT ON CACHE INTERNAL "") endif() -if (FFTW3F_FOUND AND LINUX) +if (FFTW3F_FOUND) add_subdirectory(wdsp) add_definitions(-DHAS_WDSP) set(WDSP_SUPPORT ON CACHE INTERNAL "") diff --git a/plugins/channelrx/wdsprx/CMakeLists.txt b/plugins/channelrx/wdsprx/CMakeLists.txt index 84898fa74..bd0e99220 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 + wdsprxeqdialog.cpp + wdsprxeqdialog.ui wdsprxfmdialog.cpp wdsprxfmdialog.ui wdsprxsquelchdialog.cpp @@ -51,6 +53,7 @@ if(NOT SERVER_MODE) wdsprxcwpeakdialog.h wdsprxdnbdialog.h wdsprxdnrdialog.h + wdsprxeqdialog.h wdsprxfmdialog.h wdsprxsquelchdialog.h ) diff --git a/plugins/channelrx/wdsprx/wdsprxeqdialog.cpp b/plugins/channelrx/wdsprx/wdsprxeqdialog.cpp new file mode 100644 index 000000000..9d7468e4d --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxeqdialog.cpp @@ -0,0 +1,252 @@ +/////////////////////////////////////////////////////////////////////////////////////// +// 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 "wdsprxeqdialog.h" +#include "ui_wdsprxeqdialog.h" + +WDSPRxEqDialog::WDSPRxEqDialog(QWidget* parent) : + QDialog(parent), + ui(new Ui::WDSPRxEqDialog) +{ + ui->setupUi(this); +} + +WDSPRxEqDialog::~WDSPRxEqDialog() +{ + delete ui; +} + +void WDSPRxEqDialog::setEqF(const std::array& eqF) +{ + m_eqF = eqF; + ui->f1->blockSignals(true); + ui->f2->blockSignals(true); + ui->f3->blockSignals(true); + ui->f4->blockSignals(true); + ui->f5->blockSignals(true); + ui->f6->blockSignals(true); + ui->f7->blockSignals(true); + ui->f8->blockSignals(true); + ui->f9->blockSignals(true); + ui->f10->blockSignals(true); + ui->f1->setValue((int) m_eqF[1]); + ui->f2->setValue((int) m_eqF[2]); + ui->f3->setValue((int) m_eqF[3]); + ui->f4->setValue((int) m_eqF[4]); + ui->f5->setValue((int) m_eqF[5]); + ui->f6->setValue((int) m_eqF[6]); + ui->f7->setValue((int) m_eqF[7]); + ui->f8->setValue((int) m_eqF[8]); + ui->f9->setValue((int) m_eqF[9]); + ui->f10->setValue((int) m_eqF[10]); + ui->f1->blockSignals(false); + ui->f2->blockSignals(false); + ui->f3->blockSignals(false); + ui->f4->blockSignals(false); + ui->f5->blockSignals(false); + ui->f6->blockSignals(false); + ui->f7->blockSignals(false); + ui->f8->blockSignals(false); + ui->f9->blockSignals(false); + ui->f10->blockSignals(false); +} + +void WDSPRxEqDialog::setEqG(const std::array& eqG) +{ + m_eqG = eqG; + ui->preampGain->blockSignals(true); + ui->f1Gain->blockSignals(true); + ui->f2Gain->blockSignals(true); + ui->f3Gain->blockSignals(true); + ui->f4Gain->blockSignals(true); + ui->f5Gain->blockSignals(true); + ui->f6Gain->blockSignals(true); + ui->f7Gain->blockSignals(true); + ui->f8Gain->blockSignals(true); + ui->f9Gain->blockSignals(true); + ui->f10Gain->blockSignals(true); + ui->preampGain->setValue((int) m_eqG[0]); + ui->f1Gain->setValue((int) m_eqG[1]); + ui->f2Gain->setValue((int) m_eqG[2]); + ui->f3Gain->setValue((int) m_eqG[3]); + ui->f4Gain->setValue((int) m_eqG[4]); + ui->f5Gain->setValue((int) m_eqG[5]); + ui->f6Gain->setValue((int) m_eqG[6]); + ui->f7Gain->setValue((int) m_eqG[7]); + ui->f8Gain->setValue((int) m_eqG[8]); + ui->f9Gain->setValue((int) m_eqG[9]); + ui->f10Gain->setValue((int) m_eqG[10]); + ui->preampGain->blockSignals(false); + ui->f1Gain->blockSignals(false); + ui->f2Gain->blockSignals(false); + ui->f3Gain->blockSignals(false); + ui->f4Gain->blockSignals(false); + ui->f5Gain->blockSignals(false); + ui->f6Gain->blockSignals(false); + ui->f7Gain->blockSignals(false); + ui->f8Gain->blockSignals(false); + ui->f9Gain->blockSignals(false); + ui->f10Gain->blockSignals(false); + ui->preampGainText->setText(tr("%1 dB").arg((int) m_eqG[0])); + ui->f1GainText->setText(tr("%1 dB").arg((int) m_eqG[1])); + ui->f2GainText->setText(tr("%1 dB").arg((int) m_eqG[2])); + ui->f3GainText->setText(tr("%1 dB").arg((int) m_eqG[3])); + ui->f4GainText->setText(tr("%1 dB").arg((int) m_eqG[4])); + ui->f5GainText->setText(tr("%1 dB").arg((int) m_eqG[5])); + ui->f6GainText->setText(tr("%1 dB").arg((int) m_eqG[6])); + ui->f7GainText->setText(tr("%1 dB").arg((int) m_eqG[7])); + ui->f8GainText->setText(tr("%1 dB").arg((int) m_eqG[8])); + ui->f9GainText->setText(tr("%1 dB").arg((int) m_eqG[9])); + ui->f10GainText->setText(tr("%1 dB").arg((int) m_eqG[10])); +} + +void WDSPRxEqDialog::on_f1_valueChanged(int value) +{ + m_eqF[1] = (float) value; + emit valueChanged(ChangedFrequency); +} + +void WDSPRxEqDialog::on_f2_valueChanged(int value) +{ + m_eqF[2] = (float) value; + emit valueChanged(ChangedFrequency); +} + +void WDSPRxEqDialog::on_f3_valueChanged(int value) +{ + m_eqF[3] = (float) value; + emit valueChanged(ChangedFrequency); +} + +void WDSPRxEqDialog::on_f4_valueChanged(int value) +{ + m_eqF[4] = (float) value; + emit valueChanged(ChangedFrequency); +} + +void WDSPRxEqDialog::on_f5_valueChanged(int value) +{ + m_eqF[5] = (float) value; + emit valueChanged(ChangedFrequency); +} + +void WDSPRxEqDialog::on_f6_valueChanged(int value) +{ + m_eqF[6] = (float) value; + emit valueChanged(ChangedFrequency); +} + +void WDSPRxEqDialog::on_f7_valueChanged(int value) +{ + m_eqF[7] = (float) value; + emit valueChanged(ChangedFrequency); +} + +void WDSPRxEqDialog::on_f8_valueChanged(int value) +{ + m_eqF[8] = (float) value; + emit valueChanged(ChangedFrequency); +} + +void WDSPRxEqDialog::on_f9_valueChanged(int value) +{ + m_eqF[9] = (float) value; + emit valueChanged(ChangedFrequency); +} + +void WDSPRxEqDialog::on_f10_valueChanged(int value) +{ + m_eqF[10] = (float) value; + emit valueChanged(ChangedFrequency); +} + +void WDSPRxEqDialog::on_preampGain_valueChanged(int value) +{ + m_eqG[0] = (float) value; + ui->preampGainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + +void WDSPRxEqDialog::on_f1Gain_valueChanged(int value) +{ + m_eqG[1] = (float) value; + ui->f1GainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + +void WDSPRxEqDialog::on_f2Gain_valueChanged(int value) +{ + m_eqG[2] = (float) value; + ui->f2GainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + +void WDSPRxEqDialog::on_f3Gain_valueChanged(int value) +{ + m_eqG[3] = (float) value; + ui->f3GainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + +void WDSPRxEqDialog::on_f4Gain_valueChanged(int value) +{ + m_eqG[4] = (float) value; + ui->f4GainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + +void WDSPRxEqDialog::on_f5Gain_valueChanged(int value) +{ + m_eqG[5] = (float) value; + ui->f5GainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + +void WDSPRxEqDialog::on_f6Gain_valueChanged(int value) +{ + m_eqG[6] = (float) value; + ui->f6GainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + +void WDSPRxEqDialog::on_f7Gain_valueChanged(int value) +{ + m_eqG[7] = (float) value; + ui->f7GainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + +void WDSPRxEqDialog::on_f8Gain_valueChanged(int value) +{ + m_eqG[8] = (float) value; + ui->f8GainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + +void WDSPRxEqDialog::on_f9Gain_valueChanged(int value) +{ + m_eqG[9] = (float) value; + ui->f9GainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + +void WDSPRxEqDialog::on_f10Gain_valueChanged(int value) +{ + m_eqG[10] = (float) value; + ui->f10GainText->setText(tr("%1 dB").arg(value)); + emit valueChanged(ChangedGain); +} + diff --git a/plugins/channelrx/wdsprx/wdsprxeqdialog.h b/plugins/channelrx/wdsprx/wdsprxeqdialog.h new file mode 100644 index 000000000..85dac72ab --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxeqdialog.h @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////////////////// +// 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_WDSPRXEQDIALOG_H +#define INCLUDE_WDSPRXEQDIALOG_H + +#include +#include + +#include "export.h" +#include "wdsprxsettings.h" + +namespace Ui { + class WDSPRxEqDialog; +} + +class SDRGUI_API WDSPRxEqDialog : public QDialog { + Q_OBJECT +public: + enum ValueChanged { + ChangedFrequency, + ChangedGain, + }; + + explicit WDSPRxEqDialog(QWidget* parent = nullptr); + ~WDSPRxEqDialog(); + + void setEqF(const std::array& eqF); + void setEqG(const std::array& eqG); + + const std::array& getEqF() const { return m_eqF; } + const std::array& getEqG() const { return m_eqG; } + +signals: + void valueChanged(int valueChanged); + +private: + Ui::WDSPRxEqDialog *ui; + std::array m_eqF; + std::array m_eqG; + +private slots: + void on_f1_valueChanged(int value); + void on_f2_valueChanged(int value); + void on_f3_valueChanged(int value); + void on_f4_valueChanged(int value); + void on_f5_valueChanged(int value); + void on_f6_valueChanged(int value); + void on_f7_valueChanged(int value); + void on_f8_valueChanged(int value); + void on_f9_valueChanged(int value); + void on_f10_valueChanged(int value); + void on_preampGain_valueChanged(int value); + void on_f1Gain_valueChanged(int value); + void on_f2Gain_valueChanged(int value); + void on_f3Gain_valueChanged(int value); + void on_f4Gain_valueChanged(int value); + void on_f5Gain_valueChanged(int value); + void on_f6Gain_valueChanged(int value); + void on_f7Gain_valueChanged(int value); + void on_f8Gain_valueChanged(int value); + void on_f9Gain_valueChanged(int value); + void on_f10Gain_valueChanged(int value); +}; + +#endif diff --git a/plugins/channelrx/wdsprx/wdsprxeqdialog.ui b/plugins/channelrx/wdsprx/wdsprxeqdialog.ui new file mode 100644 index 000000000..290ead8ad --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxeqdialog.ui @@ -0,0 +1,889 @@ + + + WDSPRxEqDialog + + + + 0 + 0 + 410 + 440 + + + + Equalizer settings + + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Frequency point #3 (Hz) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 95 + + + 187 + + + 125 + + + + + + + Frequency point #6 (Hz) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 751 + + + 1500 + + + 1000 + + + + + + + f5 (Hz) + + + + + + + Frequency point #7 (Hz) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1501 + + + 3000 + + + 2000 + + + + + + + f7 (Hz) + + + + + + + + 16777215 + 16 + + + + Frequency point #4 gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + f4 (Hz) + + + + + + + Frequency point #5 (Hz) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 376 + + + 750 + + + 500 + + + + + + + + 16777215 + 16 + + + + Preamp gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + Frequency point #8 (Hz) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 3001 + + + 6000 + + + 4000 + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Preamp + + + + + + + + 16777215 + 16 + + + + Frequency point #1 gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + f2 (Hz) + + + + + + + + 16777215 + 16 + + + + Frequency point #7 gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + + 16777215 + 16 + + + + Frequency point #5 gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + + 16777215 + 16 + + + + Frequency point #8 gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + f6 (Hz) + + + + + + + Frequency point #2 (Hz) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 49 + + + 94 + + + 63 + + + + + + + f9 (Hz) + + + + + + + f8 (Hz) + + + + + + + Frequency point #1 (Hz) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 48 + + + 32 + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + f3 (Hz) + + + + + + + + 16777215 + 16 + + + + Frequency point #2 gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16777215 + 16 + + + + Frequency point #9 gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Frequency point #4 (Hz) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 188 + + + 375 + + + 250 + + + + + + + Frequency point #9 (Hz) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 6001 + + + 12000 + + + 8000 + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16777215 + 16 + + + + Frequency point #3 gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16777215 + 16 + + + + Frequency point #6 gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + f1 (Hz) + + + + + + + f10 (Hz) + + + + + + + Frequency point #10 (Hz) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 12001 + + + 20000 + + + 16000 + + + + + + + + 16777215 + 16 + + + + Frequency point #10 gain (dB) + + + -15 + + + 15 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + + 50 + 0 + + + + 00 dB + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + TickedSlider + QSlider +
gui/tickedslider.h
+
+
+ + + + buttonBox + accepted() + WDSPRxEqDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + WDSPRxEqDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/plugins/channelrx/wdsprx/wdsprxfmdialog.ui b/plugins/channelrx/wdsprx/wdsprxfmdialog.ui index ce505318c..a56dc0f10 100644 --- a/plugins/channelrx/wdsprx/wdsprxfmdialog.ui +++ b/plugins/channelrx/wdsprx/wdsprxfmdialog.ui @@ -50,9 +50,18 @@ + + + 32 + 0 + + 20.0 + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + @@ -262,23 +271,32 @@ AF volume limter gain (dB) - -30 + -80 - 30 + 0 1 - 0 + -40 + + + 24 + 0 + + - 20 + -40 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter diff --git a/plugins/channelrx/wdsprx/wdsprxgui.cpp b/plugins/channelrx/wdsprx/wdsprxgui.cpp index 2543e76f8..ec5935ff1 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.cpp +++ b/plugins/channelrx/wdsprx/wdsprxgui.cpp @@ -44,6 +44,7 @@ #include "wdsprxfmdialog.h" #include "wdsprxcwpeakdialog.h" #include "wdsprxsquelchdialog.h" +#include "wdsprxeqdialog.h" WDSPRxGUI* WDSPRxGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel) { @@ -341,17 +342,28 @@ void WDSPRxGUI::on_profileIndex_valueChanged(int value) 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_squelchThreshold = m_settings.m_profiles[m_settings.m_profileIndex].m_squelchThreshold; 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; + // Equalizer + m_settings.m_equalizer = m_settings.m_profiles[m_settings.m_profileIndex].m_equalizer; + m_settings.m_eqF = m_settings.m_profiles[m_settings.m_profileIndex].m_eqF; + m_settings.m_eqG = m_settings.m_profiles[m_settings.m_profileIndex].m_eqG; displaySettings(); applyBandwidths(m_settings.m_profiles[m_settings.m_profileIndex].m_spanLog2, true); // does applySettings(true) } void WDSPRxGUI::on_demod_currentIndexChanged(int index) { - m_settings.m_demod = (WDSPRxProfile::WDSPRxDemod) index; + WDSPRxProfile::WDSPRxDemod demod = (WDSPRxProfile::WDSPRxDemod) index; + + if ((m_settings.m_demod != WDSPRxProfile::DemodSSB) && (demod == WDSPRxProfile::DemodSSB)) { + m_settings.m_dsb = false; + } + + m_settings.m_demod = demod; m_settings.m_profiles[m_settings.m_profileIndex].m_demod = m_settings.m_demod; switch(m_settings.m_demod) @@ -482,6 +494,9 @@ WDSPRxGUI::WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam CRightClickEnabler *squelchRightClickEnabler = new CRightClickEnabler(ui->squelch); connect(squelchRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(squelchSetupDialog(const QPoint &))); + CRightClickEnabler *equalizerRightClickEnabler = new CRightClickEnabler(ui->equalizer); + connect(equalizerRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(equalizerSetupDialog(const QPoint &))); + CRightClickEnabler *demodRightClickEnabler = new CRightClickEnabler(ui->demod); connect(demodRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(demodSetupDialog(const QPoint &))); @@ -757,6 +772,7 @@ void WDSPRxGUI::displaySettings() 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->equalizer->setChecked(m_settings.m_equalizer); ui->audioBinaural->setChecked(m_settings.m_audioBinaural); ui->audioFlipChannels->setChecked(m_settings.m_audioFlipChannels); ui->audioMute->setChecked(m_settings.m_audioMute); @@ -1208,6 +1224,44 @@ void WDSPRxGUI::squelchSetup(int iValueChanged) } } +void WDSPRxGUI::equalizerSetupDialog(const QPoint& p) +{ + m_equalizerDialog = new WDSPRxEqDialog(); + m_equalizerDialog->move(p); + m_equalizerDialog->setEqF(m_settings.m_eqF); + m_equalizerDialog->setEqG(m_settings.m_eqG); + QObject::connect(m_equalizerDialog, &WDSPRxEqDialog::valueChanged, this, &WDSPRxGUI::equalizerSetup); + m_equalizerDialog->exec(); + QObject::disconnect(m_equalizerDialog, &WDSPRxEqDialog::valueChanged, this, &WDSPRxGUI::equalizerSetup); + m_equalizerDialog->deleteLater(); + m_equalizerDialog = nullptr; +} + +void WDSPRxGUI::equalizerSetup(int iValueChanged) +{ + if (!m_equalizerDialog) { + return; + } + + WDSPRxEqDialog::ValueChanged valueChanged = (WDSPRxEqDialog::ValueChanged) iValueChanged; + + switch (valueChanged) + { + case WDSPRxEqDialog::ChangedFrequency: + m_settings.m_eqF = m_equalizerDialog->getEqF(); + m_settings.m_profiles[m_settings.m_profileIndex].m_eqF = m_settings.m_eqF; + applySettings(); + break; + case WDSPRxEqDialog::ChangedGain: + m_settings.m_eqG = m_equalizerDialog->getEqG(); + m_settings.m_profiles[m_settings.m_profileIndex].m_eqG = m_settings.m_eqG; + 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 9c8bc9c80..d80d168a0 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.h +++ b/plugins/channelrx/wdsprx/wdsprxgui.h @@ -41,6 +41,7 @@ class WDSPRxAMDialog; class WDSPRxFMDialog; class WDSPRxCWPeakDialog; class WDSPRxSquelchDialog; +class WDSPRxEqDialog; class SpectrumVis; class BasebandSampleSink; @@ -103,6 +104,7 @@ private: WDSPRxFMDialog* m_fmDialog; WDSPRxCWPeakDialog* m_cwPeakDialog; WDSPRxSquelchDialog* m_squelchDialog; + WDSPRxEqDialog* m_equalizerDialog; QIcon m_iconDSBUSB; QIcon m_iconDSBLSB; @@ -144,6 +146,7 @@ private slots: void on_cwPeaking_toggled(bool checked); void on_squelch_toggled(bool checked); void on_squelchThreshold_valueChanged(int value); + void on_equalizer_toggled(bool checked); void onWidgetRolled(QWidget* widget, bool rollDown); void onMenuDialogCalled(const QPoint& p); void handleInputMessages(); @@ -161,6 +164,8 @@ private slots: void fmSetup(int valueChanged); void squelchSetupDialog(const QPoint& p); void squelchSetup(int valueChanged); + void equalizerSetupDialog(const QPoint& p); + void equalizerSetup(int valueChanged); void tick(); }; diff --git a/plugins/channelrx/wdsprx/wdsprxgui.ui b/plugins/channelrx/wdsprx/wdsprxgui.ui index 0f1d01047..3a2916937 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.ui +++ b/plugins/channelrx/wdsprx/wdsprxgui.ui @@ -993,6 +993,19 @@ + + + + Toggle equalizer (righ-click for options) + + + EQ + + + true + + + diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.cpp b/plugins/channelrx/wdsprx/wdsprxsettings.cpp index 3ba15c2bd..c285d425f 100644 --- a/plugins/channelrx/wdsprx/wdsprxsettings.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsettings.cpp @@ -79,8 +79,8 @@ void WDSPRxSettings::resetToDefaults() m_fmDeviation = 2500.0; m_fmAFLow = 300.0; m_fmAFHigh = 3000.0; - m_fmAFLimiter = false; - m_fmAFLimiterGain = 10.0; + m_fmAFLimiter = true; + m_fmAFLimiterGain = -40.0; m_fmCTCSSNotch = false; m_fmCTCSSNotchFrequency = 67.0; // Squelch @@ -90,6 +90,10 @@ void WDSPRxSettings::resetToDefaults() m_ssqlTauMute = 0.1; m_ssqlTauUnmute = 0.1; m_amsqMaxTail = 1.5; + // Equalizer + m_equalizer = false; + m_eqF = {0.0, 32.0, 63.0, 125.0, 250.0, 500.0, 1000.0, 2000.0, 4000.0, 8000.0, 16000.0}; + m_eqG = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // m_volume = 1.0; m_inputFrequencyOffset = 0; @@ -166,6 +170,30 @@ QByteArray WDSPRxSettings::serialize() const s.writeDouble(63, m_ssqlTauMute); s.writeDouble(64, m_ssqlTauUnmute); s.writeDouble(65, m_amsqMaxTail); + // Equalizer + s.writeBool( 90, m_equalizer); + s.writeFloat(4000, m_eqF[0]); + s.writeFloat(4001, m_eqF[1]); + s.writeFloat(4002, m_eqF[2]); + s.writeFloat(4003, m_eqF[3]); + s.writeFloat(4004, m_eqF[4]); + s.writeFloat(4005, m_eqF[5]); + s.writeFloat(4006, m_eqF[6]); + s.writeFloat(4007, m_eqF[7]); + s.writeFloat(4008, m_eqF[8]); + s.writeFloat(4009, m_eqF[9]); + s.writeFloat(4010, m_eqF[10]); + s.writeFloat(4020, m_eqG[0]); + s.writeFloat(4021, m_eqG[1]); + s.writeFloat(4022, m_eqG[2]); + s.writeFloat(4023, m_eqG[3]); + s.writeFloat(4024, m_eqG[4]); + s.writeFloat(4025, m_eqG[5]); + s.writeFloat(4026, m_eqG[6]); + s.writeFloat(4027, m_eqG[7]); + s.writeFloat(4028, m_eqG[8]); + s.writeFloat(4029, m_eqG[9]); + s.writeFloat(4030, m_eqG[10]); // s.writeString(70, m_title); s.writeString(71, m_audioDeviceName); @@ -237,6 +265,30 @@ QByteArray WDSPRxSettings::serialize() const s.writeDouble(163 + 100*i, m_profiles[i].m_ssqlTauMute); s.writeDouble(164 + 100*i, m_profiles[i].m_ssqlTauUnmute); s.writeDouble(165 + 100*i, m_profiles[i].m_amsqMaxTail); + // Equalizer + s.writeBool( 190 + 100*i, m_profiles[i].m_equalizer); + s.writeFloat(4100 + 100*i, m_profiles[i].m_eqF[0]); + s.writeFloat(4101 + 100*i, m_profiles[i].m_eqF[1]); + s.writeFloat(4102 + 100*i, m_profiles[i].m_eqF[2]); + s.writeFloat(4103 + 100*i, m_profiles[i].m_eqF[3]); + s.writeFloat(4104 + 100*i, m_profiles[i].m_eqF[4]); + s.writeFloat(4105 + 100*i, m_profiles[i].m_eqF[5]); + s.writeFloat(4106 + 100*i, m_profiles[i].m_eqF[6]); + s.writeFloat(4107 + 100*i, m_profiles[i].m_eqF[7]); + s.writeFloat(4108 + 100*i, m_profiles[i].m_eqF[8]); + s.writeFloat(4109 + 100*i, m_profiles[i].m_eqF[9]); + s.writeFloat(4110 + 100*i, m_profiles[i].m_eqF[10]); + s.writeFloat(4120 + 100*i, m_profiles[i].m_eqG[0]); + s.writeFloat(4121 + 100*i, m_profiles[i].m_eqG[1]); + s.writeFloat(4122 + 100*i, m_profiles[i].m_eqG[2]); + s.writeFloat(4123 + 100*i, m_profiles[i].m_eqG[3]); + s.writeFloat(4124 + 100*i, m_profiles[i].m_eqG[4]); + s.writeFloat(4125 + 100*i, m_profiles[i].m_eqG[5]); + s.writeFloat(4126 + 100*i, m_profiles[i].m_eqG[6]); + s.writeFloat(4127 + 100*i, m_profiles[i].m_eqG[7]); + s.writeFloat(4128 + 100*i, m_profiles[i].m_eqG[8]); + s.writeFloat(4129 + 100*i, m_profiles[i].m_eqG[9]); + s.writeFloat(4130 + 100*i, m_profiles[i].m_eqG[10]); } return s.final(); @@ -315,8 +367,8 @@ bool WDSPRxSettings::deserialize(const QByteArray& data) 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( 48, &m_fmAFLimiter, true); + d.readDouble(49, &m_fmAFLimiterGain, -40.0); d.readBool( 50, &m_fmCTCSSNotch, false); d.readDouble(51, &m_fmCTCSSNotchFrequency, 67.0); // Squelch @@ -358,6 +410,30 @@ bool WDSPRxSettings::deserialize(const QByteArray& data) d.readU32( 82, &utmp, 0); m_profileIndex = utmp < 10 ? utmp : 0; + d.readBool( 90, &m_equalizer, false); + d.readFloat(4000, &m_eqF[0], 0.0); + d.readFloat(4001, &m_eqF[1], 32.0); + d.readFloat(4002, &m_eqF[2], 63.0); + d.readFloat(4003, &m_eqF[3], 125.0); + d.readFloat(4004, &m_eqF[4], 250.0); + d.readFloat(4005, &m_eqF[5], 500.0); + d.readFloat(4006, &m_eqF[6], 1000.0); + d.readFloat(4007, &m_eqF[7], 2000.0); + d.readFloat(4008, &m_eqF[8], 4000.0); + d.readFloat(4009, &m_eqF[9], 8000.0); + d.readFloat(4010, &m_eqF[10], 16000.0); + d.readFloat(4020, &m_eqG[0], 0); + d.readFloat(4021, &m_eqG[1], 0); + d.readFloat(4022, &m_eqG[2], 0); + d.readFloat(4023, &m_eqG[3], 0); + d.readFloat(4024, &m_eqG[4], 0); + d.readFloat(4025, &m_eqG[5], 0); + d.readFloat(4026, &m_eqG[6], 0); + d.readFloat(4027, &m_eqG[7], 0); + d.readFloat(4028, &m_eqG[8], 0); + d.readFloat(4029, &m_eqG[9], 0); + d.readFloat(4030, &m_eqG[10], 0); + for (unsigned int i = 0; (i < 10); i++) { d.readS32 (104 + 100*i, &tmp, 9); @@ -409,8 +485,8 @@ bool WDSPRxSettings::deserialize(const QByteArray& data) 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( 148 + 100*i, &m_profiles[i].m_fmAFLimiter, true); + d.readDouble(149 + 100*i, &m_profiles[i].m_fmAFLimiterGain, -40.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 @@ -421,6 +497,30 @@ bool WDSPRxSettings::deserialize(const QByteArray& data) d.readDouble(163 + 100*i, &m_profiles[i].m_ssqlTauMute, 0.1); d.readDouble(164 + 100*i, &m_profiles[i].m_ssqlTauUnmute, 0.1); d.readDouble(165 + 100*i, &m_profiles[i].m_amsqMaxTail, 1.5); + // Equalizer + d.readBool( 190 + 100*i, &m_profiles[i].m_equalizer, false); + d.readFloat(4100 + 100*i, &m_profiles[i].m_eqF[0], 0.0); + d.readFloat(4101 + 100*i, &m_profiles[i].m_eqF[1], 32.0); + d.readFloat(4102 + 100*i, &m_profiles[i].m_eqF[2], 63.0); + d.readFloat(4103 + 100*i, &m_profiles[i].m_eqF[3], 125.0); + d.readFloat(4104 + 100*i, &m_profiles[i].m_eqF[4], 250.0); + d.readFloat(4105 + 100*i, &m_profiles[i].m_eqF[5], 500.0); + d.readFloat(4106 + 100*i, &m_profiles[i].m_eqF[6], 1000.0); + d.readFloat(4107 + 100*i, &m_profiles[i].m_eqF[7], 2000.0); + d.readFloat(4108 + 100*i, &m_profiles[i].m_eqF[8], 4000.0); + d.readFloat(4109 + 100*i, &m_profiles[i].m_eqF[9], 8000.0); + d.readFloat(4110 + 100*i, &m_profiles[i].m_eqF[10], 16000.0); + d.readFloat(4120 + 100*i, &m_profiles[i].m_eqG[0], 0.0); + d.readFloat(4121 + 100*i, &m_profiles[i].m_eqG[1], 0.0); + d.readFloat(4122 + 100*i, &m_profiles[i].m_eqG[2], 0.0); + d.readFloat(4123 + 100*i, &m_profiles[i].m_eqG[3], 0.0); + d.readFloat(4124 + 100*i, &m_profiles[i].m_eqG[4], 0.0); + d.readFloat(4125 + 100*i, &m_profiles[i].m_eqG[5], 0.0); + d.readFloat(4126 + 100*i, &m_profiles[i].m_eqG[6], 0.0); + d.readFloat(4127 + 100*i, &m_profiles[i].m_eqG[7], 0.0); + d.readFloat(4128 + 100*i, &m_profiles[i].m_eqG[8], 0.0); + d.readFloat(4129 + 100*i, &m_profiles[i].m_eqG[9], 0.0); + d.readFloat(4130 + 100*i, &m_profiles[i].m_eqG[10], 0.0); } return true; diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.cpp.orig b/plugins/channelrx/wdsprx/wdsprxsettings.cpp.orig deleted file mode 100644 index 850e3b75e..000000000 --- a/plugins/channelrx/wdsprx/wdsprxsettings.cpp.orig +++ /dev/null @@ -1,422 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// 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 - -#include "audio/audiodevicemanager.h" -#include "util/simpleserializer.h" -#include "settings/serializable.h" -#include "wdsprxsettings.h" - -#ifdef SDR_RX_SAMPLE_24BIT -const int WDSPRxSettings::m_minPowerThresholdDB = -120; -const float WDSPRxSettings::m_mminPowerThresholdDBf = 120.0f; -#else -const int WDSPRxSettings::m_minPowerThresholdDB = -100; -const float WDSPRxSettings::m_mminPowerThresholdDBf = 100.0f; -#endif - -WDSPRxSettings::WDSPRxSettings() : - m_channelMarker(nullptr), - m_spectrumGUI(nullptr), - m_rollupState(nullptr) -{ - m_profiles.resize(10); - resetToDefaults(); -} - -void WDSPRxSettings::resetToDefaults() -{ - m_demod = WDSPRxProfile::DemodSSB; - m_audioBinaural = false; - m_audioFlipChannels = false; - m_dsb = false; - m_audioMute = false; - // AGC - m_agc = false; - m_agcMode = WDSPRxProfile::AGCMedium; - m_agcGain = 80; - m_agcSlope = 35; // 3.5 dB - m_agcHangThreshold = 0; - // Noise blanker - m_dnb = false; - m_nbScheme = WDSPRxProfile::WDSPRxNBScheme::NBSchemeNB; - m_nb2Mode = WDSPRxProfile::WDSPRxNB2Mode::NB2ModeZero; - m_nbSlewTime = 0.1; - m_nbLeadTime = 0.1; - m_nbLagTime = 0.1; - m_nbThreshold = 30; - m_nbAvgTime = 50.0; - // Noise reduction - m_dnr = false; - m_anf = false; - m_nrScheme = WDSPRxProfile::NRSchemeNR; - m_nr2Gain = WDSPRxProfile::NR2GainGamma; - m_nr2NPE = WDSPRxProfile::NR2NPEOSMS; - m_nrPosition = WDSPRxProfile::NRPositionPreAGC; - m_nr2ArtifactReduction = true; - // Demods - m_amFadeLevel = false; - m_cwPeaking = false; - 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; - // 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, 196).rgb(); - m_title = "WDSP Receiver"; - m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; - m_streamIndex = 0; - m_useReverseAPI = false; - m_reverseAPIAddress = "127.0.0.1"; - m_reverseAPIPort = 8888; - m_reverseAPIDeviceIndex = 0; - m_reverseAPIChannelIndex = 0; - m_workspaceIndex = 0; - m_hidden = false; - m_profileIndex = 0; -} - -QByteArray WDSPRxSettings::serialize() const -{ - SimpleSerializer s(1); - s.writeS32( 1, m_inputFrequencyOffset); - s.writeS32( 2, (int) m_demod); - s.writeS32( 3, m_volume * 10.0); - - if (m_spectrumGUI) { - s.writeBlob(4, m_spectrumGUI->serialize()); - } - - s.writeU32( 5, m_rgbColor); - s.writeBool( 8, m_audioBinaural); - s.writeBool( 9, m_audioFlipChannels); - s.writeBool( 10, m_dsb); - // AGC - s.writeBool( 11, m_agc); - s.writeS32( 12, (int) m_agcMode); - s.writeS32( 13, m_agcGain); - s.writeS32( 14, m_agcSlope); - s.writeS32( 15, m_agcHangThreshold); - // Noise blanker - s.writeBool( 20, m_dnb); - s.writeS32( 21, (int) m_nbScheme); - s.writeS32( 22, (int) m_nb2Mode); - s.writeDouble(23, m_nbSlewTime); - s.writeDouble(24, m_nbLeadTime); - s.writeDouble(25, m_nbLagTime); - s.writeS32( 26, m_nbThreshold); - s.writeDouble(27, m_nbAvgTime); - // Noise reduction - s.writeBool( 30, m_dnr); - s.writeBool( 32, m_anf); - s.writeS32( 33, (int) m_nrScheme); - s.writeS32( 34, (int) m_nr2Gain); - s.writeS32( 35, (int) m_nr2NPE); - s.writeS32( 36, (int) m_nrPosition); - s.writeBool( 37, m_nr2ArtifactReduction); - // Demods - s.writeBool( 40, m_amFadeLevel); - s.writeBool( 41, m_cwPeaking); - 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); - // 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); - s.writeBool( 72, m_useReverseAPI); - s.writeString(73, m_reverseAPIAddress); - s.writeU32( 74, m_reverseAPIPort); - s.writeU32( 75, m_reverseAPIDeviceIndex); - s.writeU32( 76, m_reverseAPIChannelIndex); - s.writeS32( 77, m_streamIndex); - - if (m_rollupState) { - s.writeBlob(78, m_rollupState->serialize()); - } - - s.writeS32( 79, m_workspaceIndex); - s.writeBlob( 80, m_geometryBytes); - s.writeBool( 81, m_hidden); - s.writeU32( 82, m_profileIndex); - - for (unsigned int i = 0; i < 10; i++) - { - s.writeS32 (104 + 100*i, (int) m_profiles[i].m_demod); - // Filter - 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 + 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 + 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 + 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 + 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); - // 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(); -} - -bool WDSPRxSettings::deserialize(const QByteArray& data) -{ - SimpleDeserializer d(data); - - if(!d.isValid()) - { - resetToDefaults(); - return false; - } - - if(d.getVersion() == 1) - { - QByteArray bytetmp; - qint32 tmp; - uint32_t utmp; - QString strtmp; - - d.readS32( 1, &m_inputFrequencyOffset, 0); - d.readS32( 2, &tmp, 0); - m_demod = (WDSPRxProfile::WDSPRxDemod) tmp; - d.readS32( 3, &tmp, 30); - m_volume = tmp / 10.0; - - if (m_spectrumGUI) - { - d.readBlob(4, &bytetmp); - m_spectrumGUI->deserialize(bytetmp); - } - - d.readU32( 5, &m_rgbColor); - d.readBool( 8, &m_audioBinaural, false); - d.readBool( 9, &m_audioFlipChannels, false); - d.readBool( 10, &m_dsb, false); - // AGC - d.readBool( 11, &m_agc, true); - d.readS32( 12, &tmp, 2); - m_agcMode = (WDSPRxProfile::WDSPRxAGCMode) tmp; - d.readS32( 13, &m_agcGain, 80); - d.readS32( 14, &m_agcSlope, 35); - d.readS32( 15, &m_agcHangThreshold, 0); - // Noise blanker - d.readBool( 20, &m_dnb, false); - d.readS32( 21, &tmp, 2); - m_nbScheme = (WDSPRxProfile::WDSPRxNBScheme) tmp; - d.readS32( 22, &tmp, 2); - m_nb2Mode = (WDSPRxProfile::WDSPRxNB2Mode) tmp; - d.readDouble(23, &m_nbSlewTime, 0.1); - d.readDouble(24, &m_nbLeadTime, 0.1); - d.readDouble(25, &m_nbLagTime, 0.1); - d.readS32( 26, &m_nbThreshold, 30); - d.readDouble(27, &m_nbAvgTime, 50.0); - // Nosie reduction - d.readBool( 30, &m_dnr, false); - d.readBool( 32, &m_anf, false); - d.readS32( 33, &tmp, 2); - m_nrScheme = (WDSPRxProfile::WDSPRxNRScheme) tmp; - d.readS32( 34, &tmp, 2); - m_nr2Gain = (WDSPRxProfile::WDSPRxNR2Gain) tmp; - d.readS32( 35, &tmp, 2); - m_nr2NPE = (WDSPRxProfile::WDSPRxNR2NPE) tmp; - d.readS32( 36, &tmp, 2); - m_nrPosition = (WDSPRxProfile::WDSPRxNRPosition) tmp; - d.readBool( 37, &m_nr2ArtifactReduction, true); - // Demods - 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); - // 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); - d.readBool( 72, &m_useReverseAPI, false); - d.readString(73, &m_reverseAPIAddress, "127.0.0.1"); - d.readU32( 74, &utmp, 0); - - if ((utmp > 1023) && (utmp < 65535)) { - m_reverseAPIPort = utmp; - } else { - m_reverseAPIPort = 8888; - } - - d.readU32( 75, &utmp, 0); - m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp; - d.readU32( 76, &utmp, 0); - m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp; - d.readS32( 77, &m_streamIndex, 0); - - if (m_rollupState) - { - d.readBlob(78, &bytetmp); - m_rollupState->deserialize(bytetmp); - } - - d.readS32( 79, &m_workspaceIndex, 0); - d.readBlob( 80, &m_geometryBytes); - d.readBool( 81, &m_hidden, false); - d.readU32( 82, &utmp, 0); - m_profileIndex = utmp < 10 ? utmp : 0; - - for (unsigned int i = 0; (i < 10); i++) - { - d.readS32 (104 + 100*i, &tmp, 9); - m_profiles[i].m_demod = (WDSPRxProfile::WDSPRxDemod) tmp; - // Filter - 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 + 100*i, &tmp, 3); - m_profiles[i].m_lowCutoff = tmp * 100.0; - d.readS32 (103 + 100*i, &m_profiles[i].m_fftWindow, 0); - // AGC - 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 + 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 + 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 + 100*i, &tmp); - m_profiles[i].m_nb2Mode = (WDSPRxProfile::WDSPRxNB2Mode) tmp; - 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 + 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 + 100*i, &tmp); - m_profiles[i].m_nr2Gain = (WDSPRxProfile::WDSPRxNR2Gain) tmp; - d.readS32 (135 + 100*i, &tmp); - m_profiles[i].m_nr2NPE = (WDSPRxProfile::WDSPRxNR2NPE) tmp; - d.readS32 (136 + 100*i, &tmp); - m_profiles[i].m_nrPosition = (WDSPRxProfile::WDSPRxNRPosition) tmp; - d.readBool (137 + 100*i, &m_profiles[i].m_nr2ArtifactReduction); - // Demods - 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; - } - else - { - resetToDefaults(); - return false; - } -} diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.cpp.rej b/plugins/channelrx/wdsprx/wdsprxsettings.cpp.rej deleted file mode 100644 index 484c3fdab..000000000 --- a/plugins/channelrx/wdsprx/wdsprxsettings.cpp.rej +++ /dev/null @@ -1,18 +0,0 @@ ---- plugins/channelrx/wdsprx/wdsprxsettings.cpp -+++ plugins/channelrx/wdsprx/wdsprxsettings.cpp -@@ -182,6 +184,7 @@ QByteArray WDSPRxSettings::serialize() const - s.writeDouble(127 + 50*i, m_profiles[i].m_nbAvgTime); - // Noise reduction - s.writeBool (130 + 50*i, m_profiles[i].m_dnr); -+ s.writeBool (131 + 50*i, m_profiles[i].m_snb); - 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); -@@ -329,6 +333,7 @@ bool WDSPRxSettings::deserialize(const QByteArray& data) - d.readDouble(127 + 50*i, &m_profiles[i].m_nbAvgTime, 50.0); - // Noise reduction - d.readBool (130 + 50*i, &m_profiles[i].m_dnr, false); -+ d.readBool (131 + 50*i, &m_profiles[i].m_snb, false); - d.readBool (132 + 50*i, &m_profiles[i].m_anf, false); - d.readS32 (133 + 50*i, &tmp); - m_profiles[i].m_nrScheme = (WDSPRxProfile::WDSPRxNRScheme) tmp; diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.h b/plugins/channelrx/wdsprx/wdsprxsettings.h index 5e0c00539..35ab65deb 100644 --- a/plugins/channelrx/wdsprx/wdsprxsettings.h +++ b/plugins/channelrx/wdsprx/wdsprxsettings.h @@ -18,6 +18,8 @@ #ifndef PLUGINS_CHANNELRX_WDSPRX_WDSPRXSETTINGS_H_ #define PLUGINS_CHANNELRX_WDSPRX_WDSPRXSETTINGS_H_ +#include + #include #include @@ -133,6 +135,10 @@ struct WDSPRxProfile double m_ssqlTauMute; //!< Voice squelch tau mute double m_ssqlTauUnmute; //!< Voice squelch tau unmute double m_amsqMaxTail; + // Equalizer + bool m_equalizer; + std::array m_eqF; //!< Frequencies vector. Index 0 is always 0 as this is the preamp position + std::array m_eqG; //!< Gains vector (dB). Index 0 is the preamp (common) gain WDSPRxProfile() : m_demod(DemodSSB), @@ -169,8 +175,8 @@ struct WDSPRxProfile m_fmDeviation(2500.0), m_fmAFLow(300.0), m_fmAFHigh(3000.0), - m_fmAFLimiter(false), - m_fmAFLimiterGain(10.0), + m_fmAFLimiter(true), + m_fmAFLimiterGain(-40.0), m_fmCTCSSNotch(false), m_fmCTCSSNotchFrequency(67.0), m_squelch(false), @@ -178,7 +184,10 @@ struct WDSPRxProfile m_squelchMode(SquelchModeVoice), m_ssqlTauMute(0.1), m_ssqlTauUnmute(0.1), - m_amsqMaxTail(1.5) + m_amsqMaxTail(1.5), + m_equalizer(false), + m_eqF{0.0, 32.0, 63.0, 125.0, 250.0, 500.0, 1000.0, 2000.0, 4000.0, 8000.0, 16000.0}, + m_eqG{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} {} }; @@ -238,6 +247,10 @@ struct WDSPRxSettings double m_ssqlTauMute; //!< Voice squelch tau mute double m_ssqlTauUnmute; //!< Voice squelch tau unmute double m_amsqMaxTail; + // Equalizer + bool m_equalizer; + std::array m_eqF = {0.0, 32.0, 63.0, 125.0, 250.0, 500.0, 1000.0, 2000.0, 4000.0, 8000.0, 16000.0}; //!< Frequencies vector. Index 0 is always 0 as this is the preamp position + std::array m_eqG = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; //!< Gains vector (dB). Index 0 is the preamp (common) gain quint32 m_rgbColor; QString m_title; diff --git a/plugins/channelrx/wdsprx/wdsprxsink.cpp b/plugins/channelrx/wdsprx/wdsprxsink.cpp index 48080be7e..acae5e8fc 100644 --- a/plugins/channelrx/wdsprx/wdsprxsink.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsink.cpp @@ -42,6 +42,7 @@ #include "ssql.hpp" #include "amsq.hpp" #include "fmsq.hpp" +#include "eq.hpp" #include "wdsprxsink.h" @@ -716,6 +717,18 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force) WDSP::AMSQ::SetAMSQMaxTail(*m_rxa, settings.m_amsqMaxTail); } + // Equalizer + + if ((m_settings.m_equalizer != settings.m_equalizer) || force) { + WDSP::EQP::SetEQRun(*m_rxa, settings.m_equalizer ? 1 : 0); + } + + if ((m_settings.m_eqF != settings.m_eqF) + || (m_settings.m_eqG != settings.m_eqG) || force) + { + WDSP::EQP::SetEQProfile(*m_rxa, 10, settings.m_eqF.data(), settings.m_eqG.data()); + } + // Audio panel if ((m_settings.m_volume != settings.m_volume) || force) { diff --git a/plugins/feature/morsedecoder/morsedecodersettings.cpp b/plugins/feature/morsedecoder/morsedecodersettings.cpp index c07d07979..e62a0b67f 100644 --- a/plugins/feature/morsedecoder/morsedecodersettings.cpp +++ b/plugins/feature/morsedecoder/morsedecodersettings.cpp @@ -28,6 +28,7 @@ const QStringList MorseDecoderSettings::m_channelURIs = { QStringLiteral("sdrangel.channel.nfmdemod"), QStringLiteral("sdrangel.channel.ssbdemod"), QStringLiteral("sdrangel.channel.wfmdemod"), + QStringLiteral("sdrangel.channel.wdsprx"), }; MorseDecoderSettings::MorseDecoderSettings() : diff --git a/wdsp/eq.cpp b/wdsp/eq.cpp index cf6037fa1..f627484e5 100644 --- a/wdsp/eq.cpp +++ b/wdsp/eq.cpp @@ -294,7 +294,7 @@ void EQP::SetEQMP (RXA& rxa, int mp) } } -void EQP::SetEQProfile (RXA& rxa, int nfreqs, float* F, float* G) +void EQP::SetEQProfile (RXA& rxa, int nfreqs, const float* F, const float* G) { EQP *a; float* impulse; @@ -429,7 +429,7 @@ void EQP::SetEQMP (TXA& txa, int mp) } } -void EQP::SetEQProfile (TXA& txa, int nfreqs, float* F, float* G) +void EQP::SetEQProfile (TXA& txa, int nfreqs, const float* F, const float* G) { EQP *a; float* impulse; diff --git a/wdsp/eq.hpp b/wdsp/eq.hpp index 87024cdd7..410c3e20b 100644 --- a/wdsp/eq.hpp +++ b/wdsp/eq.hpp @@ -84,7 +84,7 @@ public: static void SetEQRun (RXA& rxa, int run); static void SetEQNC (RXA& rxa, int nc); static void SetEQMP (RXA& rxa, int mp); - static void SetEQProfile (RXA& rxa, int nfreqs, float* F, float* G); + static void SetEQProfile (RXA& rxa, int nfreqs, const float* F, const float* G); static void SetEQCtfmode (RXA& rxa, int mode); static void SetEQWintype (RXA& rxa, int wintype); static void SetGrphEQ (RXA& rxa, int *rxeq); @@ -93,7 +93,7 @@ public: static void SetEQRun (TXA& txa, int run); static void SetEQNC (TXA& txa, int nc); static void SetEQMP (TXA& txa, int mp); - static void SetEQProfile (TXA& txa, int nfreqs, float* F, float* G); + static void SetEQProfile (TXA& txa, int nfreqs, const float* F, const float* G); static void SetEQCtfmode (TXA& txa, int mode); static void SetEQWintype (TXA& txa, int wintype); static void SetGrphEQ (TXA& txa, int *txeq); diff --git a/wdsp/fmd.cpp b/wdsp/fmd.cpp index 3151f7823..2b4ca47ff 100644 --- a/wdsp/fmd.cpp +++ b/wdsp/fmd.cpp @@ -134,8 +134,8 @@ FMD* FMD::create_fmd( a->nc_aud = nc_aud; a->mp_aud = mp_aud; a->lim_run = 0; - a->lim_pre_gain = 0.4; - a->lim_gain = 2.5; + a->lim_pre_gain = 0.01; // 0.4 + a->lim_gain = 0.0001; // 2.5 calc_fmd (a); // de-emphasis filter a->audio = new float[a->size * 2]; // (float *) malloc0 (a->size * sizeof (complex));