diff --git a/plugins/channelrx/wdsprx/CMakeLists.txt b/plugins/channelrx/wdsprx/CMakeLists.txt index 0903740d1..9af100082 100644 --- a/plugins/channelrx/wdsprx/CMakeLists.txt +++ b/plugins/channelrx/wdsprx/CMakeLists.txt @@ -41,6 +41,8 @@ if(NOT SERVER_MODE) wdsprxeqdialog.ui wdsprxfmdialog.cpp wdsprxfmdialog.ui + wdsprxpandialog.cpp + wdsprxpandialog.ui wdsprxsquelchdialog.cpp wdsprxsquelchdialog.ui wdsprxgui.cpp @@ -56,6 +58,7 @@ if(NOT SERVER_MODE) wdsprxdnrdialog.h wdsprxeqdialog.h wdsprxfmdialog.h + wdsprxpandialog.h wdsprxsquelchdialog.h ) set(TARGET_NAME wdsprx) diff --git a/plugins/channelrx/wdsprx/wdsprxdnrdialog.cpp b/plugins/channelrx/wdsprx/wdsprxdnrdialog.cpp index 6d118a4af..da4ae0d45 100644 --- a/plugins/channelrx/wdsprx/wdsprxdnrdialog.cpp +++ b/plugins/channelrx/wdsprx/wdsprxdnrdialog.cpp @@ -38,14 +38,6 @@ void WDSPRxDNRDialog::setSNB(bool snb) m_snb = snb; } -void WDSPRxDNRDialog::setANF(bool anf) -{ - ui->anf->blockSignals(true); - ui->anf->setChecked(anf); - ui->anf->blockSignals(false); - m_anf = anf; -} - void WDSPRxDNRDialog::setNRScheme(WDSPRxProfile::WDSPRxNRScheme scheme) { ui->nr->blockSignals(true); @@ -92,12 +84,6 @@ void WDSPRxDNRDialog::on_snb_clicked(bool checked) emit valueChanged(ChangedSNB); } -void WDSPRxDNRDialog::on_anf_clicked(bool checked) -{ - m_anf = checked; - emit valueChanged(ChangedANF); -} - void WDSPRxDNRDialog::on_nr_currentIndexChanged(int index) { m_nrScheme = (WDSPRxProfile::WDSPRxNRScheme) index; diff --git a/plugins/channelrx/wdsprx/wdsprxdnrdialog.h b/plugins/channelrx/wdsprx/wdsprxdnrdialog.h index a0a8d7641..4e2fef336 100644 --- a/plugins/channelrx/wdsprx/wdsprxdnrdialog.h +++ b/plugins/channelrx/wdsprx/wdsprxdnrdialog.h @@ -30,7 +30,6 @@ class WDSPRxDNRDialog : public QDialog { public: enum ValueChanged { ChangedSNB, - ChangedANF, ChangedNR, ChangedNR2Gain, ChangedNR2NPE, @@ -42,7 +41,6 @@ public: ~WDSPRxDNRDialog(); void setSNB(bool snb); - void setANF(bool anf); void setNRScheme(WDSPRxProfile::WDSPRxNRScheme scheme); void setNR2Gain(WDSPRxProfile::WDSPRxNR2Gain gain); void setNR2NPE(WDSPRxProfile::WDSPRxNR2NPE nr2NPE); @@ -50,7 +48,6 @@ public: void setNR2ArtifactReduction(bool nr2ArtifactReducion); bool getSNB() const { return m_snb; } - bool getANF() const { return m_anf; } WDSPRxProfile::WDSPRxNRScheme getNRScheme() const { return m_nrScheme; } WDSPRxProfile::WDSPRxNR2Gain getNR2Gain() const { return m_nr2Gain; } WDSPRxProfile::WDSPRxNR2NPE getNR2NPE() const { return m_nr2NPE; } @@ -63,7 +60,6 @@ signals: private: Ui::WDSPRxDNRDialog *ui; bool m_snb; - bool m_anf; WDSPRxProfile::WDSPRxNRScheme m_nrScheme; WDSPRxProfile::WDSPRxNR2Gain m_nr2Gain; WDSPRxProfile::WDSPRxNR2NPE m_nr2NPE; @@ -72,7 +68,6 @@ private: private slots: void on_snb_clicked(bool checked); - void on_anf_clicked(bool checked); void on_nr_currentIndexChanged(int index); void on_nr2Gain_currentIndexChanged(int index); void on_nr2NPE_currentIndexChanged(int index); diff --git a/plugins/channelrx/wdsprx/wdsprxdnrdialog.ui b/plugins/channelrx/wdsprx/wdsprxdnrdialog.ui index 51a4f546b..4494fd2b5 100644 --- a/plugins/channelrx/wdsprx/wdsprxdnrdialog.ui +++ b/plugins/channelrx/wdsprx/wdsprxdnrdialog.ui @@ -53,16 +53,6 @@ - - - - Automatic Notch Filter - - - ANF - - - diff --git a/plugins/channelrx/wdsprx/wdsprxgui.cpp b/plugins/channelrx/wdsprx/wdsprxgui.cpp index 8198bbe0b..3ff8640e5 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.cpp +++ b/plugins/channelrx/wdsprx/wdsprxgui.cpp @@ -45,6 +45,7 @@ #include "wdsprxcwpeakdialog.h" #include "wdsprxsquelchdialog.h" #include "wdsprxeqdialog.h" +#include "wdsprxpandialog.h" WDSPRxGUI* WDSPRxGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel) { @@ -238,6 +239,13 @@ void WDSPRxGUI::on_dnb_toggled(bool checked) applySettings(); } +void WDSPRxGUI::on_anf_toggled(bool checked) +{ + m_settings.m_anf = checked; + m_settings.m_profiles[m_settings.m_profileIndex].m_anf = m_settings.m_anf; + applySettings(); +} + void WDSPRxGUI::on_cwPeaking_toggled(bool checked) { m_settings.m_cwPeaking = checked; @@ -538,6 +546,9 @@ WDSPRxGUI::WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam CRightClickEnabler *equalizerRightClickEnabler = new CRightClickEnabler(ui->equalizer); connect(equalizerRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(equalizerSetupDialog(const QPoint &))); + CRightClickEnabler *panRightClickEnabler = new CRightClickEnabler(ui->audioBinaural); + connect(panRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(panSetupDialog(const QPoint &))); + CRightClickEnabler *demodRightClickEnabler = new CRightClickEnabler(ui->demod); connect(demodRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(demodSetupDialog(const QPoint &))); @@ -816,6 +827,7 @@ void WDSPRxGUI::displaySettings() ui->agcGainText->setText(s); ui->dnr->setChecked(m_settings.m_dnr); ui->dnb->setChecked(m_settings.m_dnb); + ui->anf->setChecked(m_settings.m_anf); ui->cwPeaking->setChecked(m_settings.m_cwPeaking); ui->squelch->setChecked(m_settings.m_squelch); ui->squelchThreshold->setValue(m_settings.m_squelchThreshold); @@ -1035,7 +1047,6 @@ void WDSPRxGUI::dnrSetupDialog(const QPoint& p) m_dnrDialog = new WDSPRxDNRDialog(); m_dnrDialog->move(p); m_dnrDialog->setSNB(m_settings.m_snb); - m_dnrDialog->setANF(m_settings.m_anf); m_dnrDialog->setNRScheme(m_settings.m_nrScheme); m_dnrDialog->setNR2Gain(m_settings.m_nr2Gain); m_dnrDialog->setNR2NPE(m_settings.m_nr2NPE); @@ -1063,11 +1074,6 @@ void WDSPRxGUI::dnrSetup(int32_t iValueChanged) m_settings.m_profiles[m_settings.m_profileIndex].m_snb = m_settings.m_snb; applySettings(); break; - case WDSPRxDNRDialog::ValueChanged::ChangedANF: - m_settings.m_anf = m_dnrDialog->getANF(); - m_settings.m_profiles[m_settings.m_profileIndex].m_anf = m_settings.m_anf; - applySettings(); - break; case WDSPRxDNRDialog::ValueChanged::ChangedNR: m_settings.m_nrScheme = m_dnrDialog->getNRScheme(); m_settings.m_profiles[m_settings.m_profileIndex].m_nrScheme = m_settings.m_nrScheme; @@ -1333,6 +1339,38 @@ void WDSPRxGUI::equalizerSetup(int iValueChanged) } } +void WDSPRxGUI::panSetupDialog(const QPoint& p) +{ + m_panDialog = new WDSPRxPanDialog(); + m_panDialog->move(p); + m_panDialog->setPan(m_settings.m_audioPan); + QObject::connect(m_panDialog, &WDSPRxPanDialog::valueChanged, this, &WDSPRxGUI::panSetup); + m_panDialog->exec(); + QObject::disconnect(m_panDialog, &WDSPRxPanDialog::valueChanged, this, &WDSPRxGUI::panSetup); + m_panDialog->deleteLater(); + m_panDialog = nullptr; +} + +void WDSPRxGUI::panSetup(int iValueChanged) +{ + if (!m_panDialog) { + return; + } + + WDSPRxPanDialog::ValueChanged valueChanged = (WDSPRxPanDialog::ValueChanged) iValueChanged; + + switch (valueChanged) + { + case WDSPRxPanDialog::ChangedPan: + m_settings.m_audioPan = m_panDialog->getPan(); + m_settings.m_profiles[m_settings.m_profileIndex].m_audioPan = m_settings.m_audioPan; + applySettings(); + break; + default: + break; + } +} + void WDSPRxGUI::tick() { double powDbAvg, powDbPeak; @@ -1379,6 +1417,8 @@ void WDSPRxGUI::makeUIConnections() QObject::connect(ui->volume, &QDial::valueChanged, this, &WDSPRxGUI::on_volume_valueChanged); QObject::connect(ui->agc, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_agc_toggled); QObject::connect(ui->dnr, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_dnr_toggled); + QObject::connect(ui->dnb, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_dnb_toggled); + QObject::connect(ui->anf, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_anf_toggled); QObject::connect(ui->agcGain, &QDial::valueChanged, this, &WDSPRxGUI::on_agcGain_valueChanged); QObject::connect(ui->audioMute, &QToolButton::toggled, this, &WDSPRxGUI::on_audioMute_toggled); QObject::connect(ui->spanLog2, &QSlider::valueChanged, this, &WDSPRxGUI::on_spanLog2_valueChanged); diff --git a/plugins/channelrx/wdsprx/wdsprxgui.h b/plugins/channelrx/wdsprx/wdsprxgui.h index ebc44fb8c..96dcc892f 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.h +++ b/plugins/channelrx/wdsprx/wdsprxgui.h @@ -42,6 +42,7 @@ class WDSPRxFMDialog; class WDSPRxCWPeakDialog; class WDSPRxSquelchDialog; class WDSPRxEqDialog; +class WDSPRxPanDialog; class SpectrumVis; class BasebandSampleSink; @@ -105,6 +106,7 @@ private: WDSPRxCWPeakDialog* m_cwPeakDialog; WDSPRxSquelchDialog* m_squelchDialog; WDSPRxEqDialog* m_equalizerDialog; + WDSPRxPanDialog* m_panDialog; QIcon m_iconDSBUSB; QIcon m_iconDSBLSB; @@ -136,6 +138,7 @@ private slots: void on_agc_toggled(bool checked); void on_dnr_toggled(bool checked); void on_dnb_toggled(bool checked); + void on_anf_toggled(bool checked); void on_agcGain_valueChanged(int value); void on_audioMute_toggled(bool checked); void on_spanLog2_valueChanged(int value); @@ -169,6 +172,8 @@ private slots: void squelchSetup(int valueChanged); void equalizerSetupDialog(const QPoint& p); void equalizerSetup(int valueChanged); + void panSetupDialog(const QPoint& p); + void panSetup(int valueChanged); void tick(); }; diff --git a/plugins/channelrx/wdsprx/wdsprxgui.ui b/plugins/channelrx/wdsprx/wdsprxgui.ui index 1b09b804a..af38871ef 100644 --- a/plugins/channelrx/wdsprx/wdsprxgui.ui +++ b/plugins/channelrx/wdsprx/wdsprxgui.ui @@ -559,7 +559,7 @@ - Highpass filter cutoff frequency (SSB) + Bandpass filter near (to 0) cutoff frequency (SSB) -60 @@ -641,7 +641,7 @@ - Lowpass filter cutoff frequency + Bandpass filter far (from 0) cutoff frequency -60 @@ -989,6 +989,19 @@ + + + + Toggle Automatic Notch Filter + + + ANF + + + true + + + diff --git a/plugins/channelrx/wdsprx/wdsprxpandialog.cpp b/plugins/channelrx/wdsprx/wdsprxpandialog.cpp new file mode 100644 index 000000000..f2978ad23 --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxpandialog.cpp @@ -0,0 +1,55 @@ +/////////////////////////////////////////////////////////////////////////////////////// +// 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 "wdsprxpandialog.h" +#include "ui_wdsprxpandialog.h" + +WDSPRxPanDialog::WDSPRxPanDialog(QWidget* parent) : + QDialog(parent), + ui(new Ui::WDSPRxPanDialog) +{ + ui->setupUi(this); +} + +WDSPRxPanDialog::~WDSPRxPanDialog() +{ + delete ui; +} + +void WDSPRxPanDialog::setPan(double pan) +{ + ui->pan->blockSignals(true); + ui->pan->setValue((int) ((pan - 0.5)*200.0)); + ui->pan->blockSignals(false); + ui->panText->setText(tr("%1").arg(ui->pan->value())); + m_pan = pan; +} + +void WDSPRxPanDialog::on_zero_clicked() +{ + ui->pan->setValue(0); + ui->panText->setText(tr("%1").arg(ui->pan->value())); + m_pan = 0.5; + emit valueChanged(ChangedPan); +} + +void WDSPRxPanDialog::on_pan_valueChanged(int value) +{ + ui->panText->setText(tr("%1").arg(ui->pan->value())); + m_pan = 0.5 + (value / 200.0); + emit valueChanged(ChangedPan); +} diff --git a/plugins/channelrx/wdsprx/wdsprxpandialog.h b/plugins/channelrx/wdsprx/wdsprxpandialog.h new file mode 100644 index 000000000..95b7694dc --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxpandialog.h @@ -0,0 +1,53 @@ +/////////////////////////////////////////////////////////////////////////////////////// +// 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_WDSPRXPANDIALOG_H +#define INCLUDE_WDSPRXPANDIALOG_H + +#include + +#include "wdsprxsettings.h" + +namespace Ui { + class WDSPRxPanDialog; +} + +class WDSPRxPanDialog : public QDialog { + Q_OBJECT +public: + enum ValueChanged { + ChangedPan, + }; + + explicit WDSPRxPanDialog(QWidget* parent = nullptr); + ~WDSPRxPanDialog(); + + void setPan(double pan); + double getPan() const { return m_pan; } + +signals: + void valueChanged(int valueChanged); + +private: + Ui::WDSPRxPanDialog *ui; + double m_pan; + +private slots: + void on_zero_clicked(); + void on_pan_valueChanged(int value); +}; + +#endif diff --git a/plugins/channelrx/wdsprx/wdsprxpandialog.ui b/plugins/channelrx/wdsprx/wdsprxpandialog.ui new file mode 100644 index 000000000..f7cbbc5b5 --- /dev/null +++ b/plugins/channelrx/wdsprx/wdsprxpandialog.ui @@ -0,0 +1,210 @@ + + + WDSPRxPanDialog + + + + 0 + 0 + 385 + 111 + + + + Audio Pan + + + + + + + + + 30 + 16777215 + + + + Reset to 0 (center) + + + 0 + + + + + + + Pan value (%) negative: left positive: right + + + -100 + + + 100 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 5 + + + + + + + + 32 + 0 + + + + -100 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + + + + L + + + + + + + + 12 + 16777215 + + + + 0 + + + Qt::AlignCenter + + + + + + + R + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 32 + 0 + + + + + 32 + 16777215 + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + TickedSlider + QSlider +
gui/tickedslider.h
+
+
+ + + + buttonBox + accepted() + WDSPRxPanDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + WDSPRxPanDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.cpp b/plugins/channelrx/wdsprx/wdsprxsettings.cpp index c0a0098d9..335415faf 100644 --- a/plugins/channelrx/wdsprx/wdsprxsettings.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsettings.cpp @@ -44,6 +44,7 @@ void WDSPRxSettings::resetToDefaults() m_demod = WDSPRxProfile::DemodSSB; m_audioBinaural = false; m_audioFlipChannels = false; + m_audioPan = 0.5; m_dsb = false; m_audioMute = false; m_dbOrS = true; @@ -127,6 +128,7 @@ QByteArray WDSPRxSettings::serialize() const } s.writeU32( 5, m_rgbColor); + s.writeDouble( 6, m_audioPan); s.writeBool( 7, m_dbOrS); s.writeBool( 8, m_audioBinaural); s.writeBool( 9, m_audioFlipChannels); @@ -227,6 +229,7 @@ QByteArray WDSPRxSettings::serialize() const s.writeBool (106 + 100*i, (int) m_profiles[i].m_audioFlipChannels); s.writeBool (107 + 100*i, (int) m_profiles[i].m_dsb); s.writeBool (108 + 100*i, (int) m_profiles[i].m_dbOrS); + s.writeDouble(109 + 100*i, m_profiles[i].m_audioPan); // Filter s.writeS32 (100 + 100*i, m_profiles[i].m_spanLog2); s.writeS32 (101 + 100*i, m_profiles[i].m_highCutoff / 100.0); @@ -335,6 +338,7 @@ bool WDSPRxSettings::deserialize(const QByteArray& data) } d.readU32( 5, &m_rgbColor); + d.readDouble( 6, &m_audioPan, 0.5); d.readBool( 7, &m_dbOrS, true); d.readBool( 8, &m_audioBinaural, false); d.readBool( 9, &m_audioFlipChannels, false); @@ -456,6 +460,7 @@ bool WDSPRxSettings::deserialize(const QByteArray& data) d.readBool( 106 + 100*i, &m_profiles[i].m_audioFlipChannels, false); d.readBool( 107 + 100*i, &m_profiles[i].m_dsb, false); d.readBool( 108 + 100*i, &m_profiles[i].m_dbOrS, true); + d.readDouble(109 + 100*i, &m_profiles[i].m_audioPan, 0.5); // Filter d.readS32 (100 + 100*i, &m_profiles[i].m_spanLog2, 3); d.readS32 (101 + 100*i, &tmp, 30); diff --git a/plugins/channelrx/wdsprx/wdsprxsettings.h b/plugins/channelrx/wdsprx/wdsprxsettings.h index 80052b24a..737adedbe 100644 --- a/plugins/channelrx/wdsprx/wdsprxsettings.h +++ b/plugins/channelrx/wdsprx/wdsprxsettings.h @@ -88,6 +88,7 @@ struct WDSPRxProfile WDSPRxDemod m_demod; bool m_audioBinaural; bool m_audioFlipChannels; + double m_audioPan; bool m_dsb; bool m_dbOrS; // Filter @@ -151,6 +152,7 @@ struct WDSPRxProfile m_demod(DemodSSB), m_audioBinaural(false), m_audioFlipChannels(false), + m_audioPan(0.5), m_dsb(false), m_dbOrS(true), m_spanLog2(3), @@ -214,6 +216,7 @@ struct WDSPRxSettings // int m_spanLog2; bool m_audioBinaural; bool m_audioFlipChannels; + double m_audioPan; bool m_dsb; bool m_audioMute; bool m_dbOrS; diff --git a/plugins/channelrx/wdsprx/wdsprxsink.cpp b/plugins/channelrx/wdsprx/wdsprxsink.cpp index 4cfc42634..cdcbc66fb 100644 --- a/plugins/channelrx/wdsprx/wdsprxsink.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsink.cpp @@ -747,12 +747,18 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force) } if ((m_settings.m_audioBinaural != settings.m_audioBinaural) + || (m_settings.m_audioPan != settings.m_audioPan) || (m_settings.m_audioFlipChannels != settings.m_audioFlipChannels) || force) { - if (settings.m_audioBinaural) { + if (settings.m_audioBinaural) + { WDSP::PANEL::SetPanelCopy(*m_rxa, settings.m_audioFlipChannels ? 3 : 0); - } else { + WDSP::PANEL::SetPanelPan(*m_rxa, settings.m_audioPan); + } + else + { WDSP::PANEL::SetPanelCopy(*m_rxa, settings.m_audioFlipChannels ? 2 : 1); + WDSP::PANEL::SetPanelPan(*m_rxa, 0.5); } }