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/wdsprxcwpeakdialog.h b/plugins/channelrx/wdsprx/wdsprxcwpeakdialog.h
index f8dbd89bb..67cd41ae6 100644
--- a/plugins/channelrx/wdsprx/wdsprxcwpeakdialog.h
+++ b/plugins/channelrx/wdsprx/wdsprxcwpeakdialog.h
@@ -35,7 +35,7 @@ public:
};
explicit WDSPRxCWPeakDialog(QWidget* parent = nullptr);
- ~WDSPRxCWPeakDialog();
+ ~WDSPRxCWPeakDialog() override;
void setCWPeakFrequency(double cwPeakFrequency);
void setCWBandwidth(double cwBandwidth);
diff --git a/plugins/channelrx/wdsprx/wdsprxdnbdialog.h b/plugins/channelrx/wdsprx/wdsprxdnbdialog.h
index 9a811de9b..b0c6c6e86 100644
--- a/plugins/channelrx/wdsprx/wdsprxdnbdialog.h
+++ b/plugins/channelrx/wdsprx/wdsprxdnbdialog.h
@@ -39,7 +39,7 @@ public:
};
explicit WDSPRxDNBDialog(QWidget* parent = nullptr);
- ~WDSPRxDNBDialog();
+ ~WDSPRxDNBDialog() override;
void setNBScheme(WDSPRxProfile::WDSPRxNBScheme scheme);
void setNB2Mode(WDSPRxProfile::WDSPRxNB2Mode mode);
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..359026f44 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,
@@ -39,10 +38,9 @@ public:
};
explicit WDSPRxDNRDialog(QWidget* parent = nullptr);
- ~WDSPRxDNRDialog();
+ ~WDSPRxDNRDialog() override;
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/wdsprxeqdialog.h b/plugins/channelrx/wdsprx/wdsprxeqdialog.h
index 29319c2b0..3a03adae9 100644
--- a/plugins/channelrx/wdsprx/wdsprxeqdialog.h
+++ b/plugins/channelrx/wdsprx/wdsprxeqdialog.h
@@ -35,7 +35,7 @@ public:
};
explicit WDSPRxEqDialog(QWidget* parent = nullptr);
- ~WDSPRxEqDialog();
+ ~WDSPRxEqDialog() override;
void setEqF(const std::array& eqF);
void setEqG(const std::array& eqG);
diff --git a/plugins/channelrx/wdsprx/wdsprxfmdialog.h b/plugins/channelrx/wdsprx/wdsprxfmdialog.h
index ec9ae1140..bcbd2c6f8 100644
--- a/plugins/channelrx/wdsprx/wdsprxfmdialog.h
+++ b/plugins/channelrx/wdsprx/wdsprxfmdialog.h
@@ -39,7 +39,7 @@ public:
};
explicit WDSPRxFMDialog(QWidget* parent = nullptr);
- ~WDSPRxFMDialog();
+ ~WDSPRxFMDialog() override;
void setDeviation(double deviation);
void setAFLow(double afLow);
diff --git a/plugins/channelrx/wdsprx/wdsprxgui.cpp b/plugins/channelrx/wdsprx/wdsprxgui.cpp
index 8198bbe0b..b648c9c4b 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;
@@ -278,6 +286,7 @@ void WDSPRxGUI::on_rit_toggled(bool checked)
void WDSPRxGUI::on_ritFrequency_valueChanged(int value)
{
m_settings.m_ritFrequency = value;
+ m_settings.m_profiles[m_settings.m_profileIndex].m_ritFrequency = m_settings.m_ritFrequency;
ui->ritFrequencyText->setText(tr("%1").arg(value));
m_channelMarker.setShift(m_settings.m_rit ? value: 0);
applySettings();
@@ -330,7 +339,7 @@ void WDSPRxGUI::on_profileIndex_valueChanged(int value)
return;
}
- ui->filterIndexText->setText(tr("%1").arg(value));
+ ui->profileIndexText->setText(tr("%1").arg(value));
m_settings.m_profileIndex = value;
// Bandwidth setup
ui->BW->setMaximum(480);
@@ -517,29 +526,32 @@ WDSPRxGUI::WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
m_spectrumVis->setGLSpectrum(ui->glSpectrum);
m_wdspRx->setMessageQueueToGUI(getInputMessageQueue());
- CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute);
- connect(audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect(const QPoint &)));
+ m_audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute);
+ connect(m_audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect(const QPoint &)));
- CRightClickEnabler *agcRightClickEnabler = new CRightClickEnabler(ui->agc);
- connect(agcRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(agcSetupDialog(const QPoint &)));
+ m_agcRightClickEnabler = new CRightClickEnabler(ui->agc);
+ connect(m_agcRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(agcSetupDialog(const QPoint &)));
- CRightClickEnabler *dnbRightClickEnabler = new CRightClickEnabler(ui->dnb);
- connect(dnbRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(dnbSetupDialog(const QPoint &)));
+ m_dnbRightClickEnabler = new CRightClickEnabler(ui->dnb);
+ connect(m_dnbRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(dnbSetupDialog(const QPoint &)));
- CRightClickEnabler *dnrRightClickEnabler = new CRightClickEnabler(ui->dnr);
- connect(dnrRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(dnrSetupDialog(const QPoint &)));
+ m_dnrRightClickEnabler = new CRightClickEnabler(ui->dnr);
+ connect(m_dnrRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(dnrSetupDialog(const QPoint &)));
- CRightClickEnabler *cwPeakRightClickEnabler = new CRightClickEnabler(ui->cwPeaking);
- connect(cwPeakRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(cwPeakSetupDialog(const QPoint &)));
+ m_cwPeakRightClickEnabler = new CRightClickEnabler(ui->cwPeaking);
+ connect(m_cwPeakRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(cwPeakSetupDialog(const QPoint &)));
- CRightClickEnabler *squelchRightClickEnabler = new CRightClickEnabler(ui->squelch);
- connect(squelchRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(squelchSetupDialog(const QPoint &)));
+ m_squelchRightClickEnabler = new CRightClickEnabler(ui->squelch);
+ connect(m_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 &)));
+ m_equalizerRightClickEnabler = new CRightClickEnabler(ui->equalizer);
+ connect(m_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 &)));
+ m_panRightClickEnabler = new CRightClickEnabler(ui->audioBinaural);
+ connect(m_panRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(panSetupDialog(const QPoint &)));
+
+ m_demodRightClickEnabler = new CRightClickEnabler(ui->demod);
+ connect(m_demodRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(demodSetupDialog(const QPoint &)));
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
@@ -599,6 +611,15 @@ WDSPRxGUI::WDSPRxGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
WDSPRxGUI::~WDSPRxGUI()
{
delete ui;
+ delete m_audioMuteRightClickEnabler;
+ delete m_agcRightClickEnabler;
+ delete m_dnbRightClickEnabler;
+ delete m_dnrRightClickEnabler;
+ delete m_cwPeakRightClickEnabler;
+ delete m_squelchRightClickEnabler;
+ delete m_equalizerRightClickEnabler;
+ delete m_panRightClickEnabler;
+ delete m_demodRightClickEnabler;
}
bool WDSPRxGUI::blockApplySettings(bool block)
@@ -816,6 +837,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);
@@ -850,10 +872,10 @@ void WDSPRxGUI::displaySettings()
ui->spanLog2->blockSignals(true);
ui->dsb->blockSignals(true);
ui->BW->blockSignals(true);
- ui->filterIndex->blockSignals(true);
+ ui->profileIndex->blockSignals(true);
- ui->filterIndex->setValue(m_settings.m_profileIndex);
- ui->filterIndexText->setText(tr("%1").arg(m_settings.m_profileIndex));
+ ui->profileIndex->setValue(m_settings.m_profileIndex);
+ ui->profileIndexText->setText(tr("%1").arg(m_settings.m_profileIndex));
ui->dsb->setChecked(m_settings.m_dsb);
ui->spanLog2->setValue(1 + ui->spanLog2->maximum() - m_settings.m_profiles[m_settings.m_profileIndex].m_spanLog2);
@@ -873,7 +895,7 @@ void WDSPRxGUI::displaySettings()
ui->spanLog2->blockSignals(false);
ui->dsb->blockSignals(false);
ui->BW->blockSignals(false);
- ui->filterIndex->blockSignals(false);
+ ui->profileIndex->blockSignals(false);
// The only one of the four signals triggering applyBandwidths will trigger it once only with all other values
// set correctly and therefore validate the settings and apply them to dependent widgets
@@ -938,7 +960,7 @@ void WDSPRxGUI::agcSetup(int iValueChanged)
return;
}
- WDSPRxAGCDialog::ValueChanged valueChanged = (WDSPRxAGCDialog::ValueChanged) iValueChanged;
+ auto valueChanged = (WDSPRxAGCDialog::ValueChanged) iValueChanged;
switch (valueChanged)
{
@@ -986,7 +1008,7 @@ void WDSPRxGUI::dnbSetup(int32_t iValueChanged)
return;
}
- WDSPRxDNBDialog::ValueChanged valueChanged = (WDSPRxDNBDialog::ValueChanged) iValueChanged;
+ auto valueChanged = (WDSPRxDNBDialog::ValueChanged) iValueChanged;
switch (valueChanged)
{
@@ -1035,7 +1057,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);
@@ -1054,7 +1075,7 @@ void WDSPRxGUI::dnrSetup(int32_t iValueChanged)
return;
}
- WDSPRxDNRDialog::ValueChanged valueChanged = (WDSPRxDNRDialog::ValueChanged) iValueChanged;
+ auto valueChanged = (WDSPRxDNRDialog::ValueChanged) iValueChanged;
switch (valueChanged)
{
@@ -1063,11 +1084,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;
@@ -1118,7 +1134,7 @@ void WDSPRxGUI::cwPeakSetup(int iValueChanged)
return;
}
- WDSPRxCWPeakDialog::ValueChanged valueChanged = (WDSPRxCWPeakDialog::ValueChanged) iValueChanged;
+ auto valueChanged = (WDSPRxCWPeakDialog::ValueChanged) iValueChanged;
switch (valueChanged)
{
@@ -1181,7 +1197,7 @@ void WDSPRxGUI::amSetup(int iValueChanged)
return;
}
- WDSPRxAMDialog::ValueChanged valueChanged = (WDSPRxAMDialog::ValueChanged) iValueChanged;
+ auto valueChanged = (WDSPRxAMDialog::ValueChanged) iValueChanged;
switch (valueChanged)
{
@@ -1201,7 +1217,7 @@ void WDSPRxGUI::fmSetup(int iValueChanged)
return;
}
- WDSPRxFMDialog::ValueChanged valueChanged = (WDSPRxFMDialog::ValueChanged) iValueChanged;
+ auto valueChanged = (WDSPRxFMDialog::ValueChanged) iValueChanged;
switch (valueChanged)
{
@@ -1266,7 +1282,7 @@ void WDSPRxGUI::squelchSetup(int iValueChanged)
return;
}
- WDSPRxSquelchDialog::ValueChanged valueChanged = (WDSPRxSquelchDialog::ValueChanged) iValueChanged;
+ auto valueChanged = (WDSPRxSquelchDialog::ValueChanged) iValueChanged;
switch (valueChanged)
{
@@ -1314,7 +1330,7 @@ void WDSPRxGUI::equalizerSetup(int iValueChanged)
return;
}
- WDSPRxEqDialog::ValueChanged valueChanged = (WDSPRxEqDialog::ValueChanged) iValueChanged;
+ auto valueChanged = (WDSPRxEqDialog::ValueChanged) iValueChanged;
switch (valueChanged)
{
@@ -1333,6 +1349,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;
+ }
+
+ auto 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,12 +1427,14 @@ 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);
QObject::connect(ui->flipSidebands, &QPushButton::clicked, this, &WDSPRxGUI::on_flipSidebands_clicked);
QObject::connect(ui->fftWindow, QOverload::of(&QComboBox::currentIndexChanged), this, &WDSPRxGUI::on_fftWindow_currentIndexChanged);
- QObject::connect(ui->filterIndex, &QDial::valueChanged, this, &WDSPRxGUI::on_profileIndex_valueChanged);
+ QObject::connect(ui->profileIndex, &QDial::valueChanged, this, &WDSPRxGUI::on_profileIndex_valueChanged);
QObject::connect(ui->demod, QOverload::of(&QComboBox::currentIndexChanged), this, &WDSPRxGUI::on_demod_currentIndexChanged);
QObject::connect(ui->cwPeaking, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_cwPeaking_toggled);
QObject::connect(ui->squelch, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_squelch_toggled);
diff --git a/plugins/channelrx/wdsprx/wdsprxgui.h b/plugins/channelrx/wdsprx/wdsprxgui.h
index ebc44fb8c..c89c3cc15 100644
--- a/plugins/channelrx/wdsprx/wdsprxgui.h
+++ b/plugins/channelrx/wdsprx/wdsprxgui.h
@@ -42,8 +42,10 @@ class WDSPRxFMDialog;
class WDSPRxCWPeakDialog;
class WDSPRxSquelchDialog;
class WDSPRxEqDialog;
+class WDSPRxPanDialog;
class SpectrumVis;
class BasebandSampleSink;
+class CRightClickEnabler;
namespace Ui {
class WDSPRxGUI;
@@ -105,6 +107,17 @@ private:
WDSPRxCWPeakDialog* m_cwPeakDialog;
WDSPRxSquelchDialog* m_squelchDialog;
WDSPRxEqDialog* m_equalizerDialog;
+ WDSPRxPanDialog* m_panDialog;
+
+ CRightClickEnabler *m_audioMuteRightClickEnabler;
+ CRightClickEnabler *m_agcRightClickEnabler;
+ CRightClickEnabler *m_dnbRightClickEnabler;
+ CRightClickEnabler *m_dnrRightClickEnabler;
+ CRightClickEnabler *m_cwPeakRightClickEnabler;
+ CRightClickEnabler *m_squelchRightClickEnabler;
+ CRightClickEnabler *m_equalizerRightClickEnabler;
+ CRightClickEnabler *m_panRightClickEnabler;
+ CRightClickEnabler *m_demodRightClickEnabler;
QIcon m_iconDSBUSB;
QIcon m_iconDSBLSB;
@@ -136,6 +149,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 +183,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..bd3233c9a 100644
--- a/plugins/channelrx/wdsprx/wdsprxgui.ui
+++ b/plugins/channelrx/wdsprx/wdsprxgui.ui
@@ -278,7 +278,7 @@
-
-
+
24
@@ -303,7 +303,7 @@
-
-
+
10
@@ -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..56363443a
--- /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() override;
+
+ 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
+
+
+
+
+
+
+ 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);
}
}
diff --git a/plugins/channelrx/wdsprx/wdsprxsquelchdialog.h b/plugins/channelrx/wdsprx/wdsprxsquelchdialog.h
index cbd611f5d..8e72ee47f 100644
--- a/plugins/channelrx/wdsprx/wdsprxsquelchdialog.h
+++ b/plugins/channelrx/wdsprx/wdsprxsquelchdialog.h
@@ -36,7 +36,7 @@ public:
};
explicit WDSPRxSquelchDialog(QWidget* parent = nullptr);
- ~WDSPRxSquelchDialog();
+ ~WDSPRxSquelchDialog() override;
void setMode(WDSPRxProfile::WDSPRxSquelchMode mode);
void setSSQLTauMute(double value);
diff --git a/wdsp/CMakeLists.txt b/wdsp/CMakeLists.txt
index 9202b11bf..02e2909ba 100644
--- a/wdsp/CMakeLists.txt
+++ b/wdsp/CMakeLists.txt
@@ -134,14 +134,3 @@ if (MSVC)
endif()
install(TARGETS wdsp DESTINATION ${INSTALL_LIB_DIR})
-
-if (LINUX)
- add_executable(wdsp_make_interface
- make_interface.cpp
- )
-
- add_executable(wdsp_make_calculus
- make_calculus.cpp
- )
- install(TARGETS wdsp_make_interface wdsp_make_calculus DESTINATION ${INSTALL_BIN_DIR})
-endif()
diff --git a/wdsp/cfcomp.cpp b/wdsp/cfcomp.cpp
index 8eea1283a..ea6efd4db 100644
--- a/wdsp/cfcomp.cpp
+++ b/wdsp/cfcomp.cpp
@@ -437,7 +437,7 @@ void CFCOMP::SetCFCOMPPosition (TXA& txa, int pos)
void CFCOMP::SetCFCOMPprofile (TXA& txa, int nfreqs, float* F, float* G, float *E)
{
CFCOMP *a = txa.cfcomp.p;
- a->nfreqs = nfreqs;
+ a->nfreqs = nfreqs < 1 ? 1 : nfreqs;
delete[] (a->E);
delete[] (a->F);
delete[] (a->G);
@@ -450,9 +450,9 @@ void CFCOMP::SetCFCOMPprofile (TXA& txa, int nfreqs, float* F, float* G, float *
delete[] (a->ep);
delete[] (a->gp);
delete[] (a->fp);
- a->fp = new float[a->nfreqs]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float));
- a->gp = new float[a->nfreqs]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float));
- a->ep = new float[a->nfreqs]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float));
+ a->fp = new float[a->nfreqs + 2]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float));
+ a->gp = new float[a->nfreqs + 2]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float));
+ a->ep = new float[a->nfreqs + 2]; // (float *) malloc0 ((a->nfreqs + 2) * sizeof (float));
calc_comp(a);
}
diff --git a/wdsp/cfir.cpp b/wdsp/cfir.cpp
index e258a6637..1cbd13525 100644
--- a/wdsp/cfir.cpp
+++ b/wdsp/cfir.cpp
@@ -46,8 +46,23 @@ void CFIR::decalc_cfir (CFIR *a)
FIRCORE::destroy_fircore (a->p);
}
-CFIR* CFIR::create_cfir (int run, int size, int nc, int mp, float* in, float* out, int runrate, int cicrate,
- int DD, int R, int Pairs, float cutoff, int xtype, float xbw, int wintype)
+CFIR* CFIR::create_cfir (
+ int run,
+ int size,
+ int nc,
+ int mp,
+ float* in,
+ float* out,
+ int runrate,
+ int cicrate,
+ int DD,
+ int R,
+ int Pairs,
+ double cutoff,
+ int xtype,
+ double xbw,
+ int wintype
+)
// run: 0 - no action; 1 - operate
// size: number of complex samples in an input buffer to the CFIR filter
// nc: number of filter coefficients
@@ -130,7 +145,20 @@ void CFIR::setOutRate_cfir (CFIR *a, int rate)
calc_cfir (a);
}
-float* CFIR::cfir_impulse (int N, int DD, int R, int Pairs, float runrate, float cicrate, float cutoff, int xtype, float xbw, int rtype, float scale, int wintype)
+float* CFIR::cfir_impulse (
+ int N,
+ int DD,
+ int R,
+ int Pairs,
+ double runrate,
+ double cicrate,
+ double cutoff,
+ int xtype,
+ double xbw,
+ int rtype,
+ double scale,
+ int wintype
+)
{
// N: number of impulse response samples
// DD: differential delay used in the CIC filter
@@ -144,18 +172,18 @@ float* CFIR::cfir_impulse (int N, int DD, int R, int Pairs, float runrate, float
// rtype: 0 for real output, 1 for complex output
// scale: scale factor to be applied to the output
int i, j;
- float tmp, local_scale, ri, mag, fn;
+ double tmp, local_scale, ri, mag, fn;
float* impulse;
float* A = new float[N]; // (float *) malloc0 (N * sizeof (float));
- float ft = cutoff / cicrate; // normalized cutoff frequency
+ double ft = cutoff / cicrate; // normalized cutoff frequency
int u_samps = (N + 1) / 2; // number of unique samples, OK for odd or even N
int c_samps = (int)(cutoff / runrate * N) + (N + 1) / 2 - N / 2; // number of unique samples within bandpass, OK for odd or even N
int x_samps = (int)(xbw / runrate * N); // number of unique samples in transition region, OK for odd or even N
- float offset = 0.5 - 0.5 * (float)((N + 1) / 2 - N / 2); // sample offset from center, OK for odd or even N
- float* xistion = new float[x_samps + 1]; // (float *) malloc0 ((x_samps + 1) * sizeof (float));
- float delta = PI / (float)x_samps;
- float L = cicrate / runrate;
- float phs = 0.0;
+ double offset = 0.5 - 0.5 * (float)((N + 1) / 2 - N / 2); // sample offset from center, OK for odd or even N
+ double* xistion = new double[x_samps + 1]; // (float *) malloc0 ((x_samps + 1) * sizeof (float));
+ double delta = PI / (float)x_samps;
+ double L = cicrate / runrate;
+ double phs = 0.0;
for (i = 0; i <= x_samps; i++)
{
xistion[i] = 0.5 * (cos (phs) + 1.0);
@@ -171,7 +199,8 @@ float* CFIR::cfir_impulse (int N, int DD, int R, int Pairs, float runrate, float
fn = ri / (L * (float)N);
if (fn <= ft)
{
- if (fn == 0.0) tmp = 1.0;
+ if (fn == 0.0)
+ tmp = 1.0;
else if ((tmp = DD * R * sin (PI * fn / R) / sin (PI * DD * fn)) < 0.0)
tmp = -tmp;
mag = pow (tmp, Pairs) * local_scale;
@@ -225,7 +254,8 @@ float* CFIR::cfir_impulse (int N, int DD, int R, int Pairs, float runrate, float
A[i] = A[u_samps - j];
impulse = FIR::fir_fsamp (N, A, rtype, 1.0, wintype);
// print_impulse ("cfirImpulse.txt", N, impulse, 1, 0);
- delete[] (A);
+ delete[] A;
+ delete[] xistion;
return impulse;
}
diff --git a/wdsp/cfir.hpp b/wdsp/cfir.hpp
index 77d807960..ebd3c027e 100644
--- a/wdsp/cfir.hpp
+++ b/wdsp/cfir.hpp
@@ -49,10 +49,10 @@ public:
int DD;
int R;
int Pairs;
- float cutoff;
- float scale;
+ double cutoff;
+ double scale;
int xtype;
- float xbw;
+ double xbw;
int wintype;
FIRCORE *p;
@@ -68,9 +68,9 @@ public:
int DD,
int R,
int Pairs,
- float cutoff,
+ double cutoff,
int xtype,
- float xbw,
+ double xbw,
int wintype
);
static void destroy_cfir (CFIR *a);
@@ -85,13 +85,13 @@ public:
int DD,
int R,
int Pairs,
- float runrate,
- float cicrate,
- float cutoff,
+ double runrate,
+ double cicrate,
+ double cutoff,
int xtype,
- float xbw,
+ double xbw,
int rtype,
- float scale,
+ double scale,
int wintype
);
// TXA Properties
diff --git a/wdsp/channel.hpp b/wdsp/channel.hpp
deleted file mode 100644
index ae04cd4ae..000000000
--- a/wdsp/channel.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/* channel.h
-
-This file is part of a program that implements a Software-Defined Radio.
-
-Copyright (C) 2013 Warren Pratt, NR0V
-Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel
-
-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; either version 2
-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 for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-The author can be reached by email at
-
-warren@wpratt.com
-
-*/
-
-#ifndef wdsp_channel_h
-#define wdsp_channel_h
-
-#include
-
-#include "export.h"
-
-class WDSP_API Channel
-{
-public:
- int type;
- bool run; // thread running
- int in_rate; // input samplerate
- int out_rate; // output samplerate
- int in_size; // input buffsize (complex samples) in a fexchange() operation
- int dsp_rate; // sample rate for mainstream dsp processing
- int dsp_size; // number complex samples processed per buffer in mainstream dsp processing
- int dsp_insize; // size (complex samples) of the output of the r1 (input) buffer
- int dsp_outsize; // size (complex samples) of the input of the r2 (output) buffer
- int out_size; // output buffsize (complex samples) in a fexchange() operation
- int state; // 0 for channel OFF; 1 for channel ON
- float tdelayup;
- float tslewup;
- float tdelaydown;
- float tslewdown;
- int bfo; // 'block_for_output', block fexchange until output is available
- volatile long flushflag;
- QThread channelThread;
- long upslew;
- // struct //io buffers
- // {
- // IOB pc, pd, pe, pf; // copies for console calls, dsp, exchange, and flush thread
- // volatile long ch_upslew;
- // } iob;
-
- static void create_channel (
- int channel,
- int in_size,
- int dsp_size,
- int input_samplerate,
- int dsp_rate,
- int output_samplerate,
- int type,
- int state,
- float tdelayup,
- float tslewup,
- float tdelaydown,
- float tslewdown,
- int bfo
- );
- static void destroy_channel (int channel);
- static void flush_channel (int channel);
- // static void set_type (int channel, int type);
- // static void SetInputBuffsize (int channel, int in_size);
- // static void SetDSPBuffsize (int channel, int dsp_size);
- // static void SetInputSamplerate (int channel, int samplerate);
- // static void SetDSPSamplerate (int channel, int samplerate);
- // static void SetOutputSamplerate (int channel, int samplerate);
- // static void SetAllRates (int channel, int in_rate, int dsp_rate, int out_rate);
- // static int SetChannelState (int channel, int state, int dmode);
-};
-
-#endif
diff --git a/wdsp/emnr.cpp b/wdsp/emnr.cpp
index a4d86dc6d..14d9d2388 100644
--- a/wdsp/emnr.cpp
+++ b/wdsp/emnr.cpp
@@ -233,7 +233,7 @@ void EMNR::interpM (double* res, double x, int nvals, double* xvals, double* yva
int idx = 0;
double xllow, xlhigh, frac;
- while (x >= xvals[idx])
+ while ((x >= xvals[idx]) && (idx < nvals - 1))
idx++;
xllow = log10 (xvals[idx - 1]);
diff --git a/wdsp/eq.cpp b/wdsp/eq.cpp
index a10158e07..3fa82b4d6 100644
--- a/wdsp/eq.cpp
+++ b/wdsp/eq.cpp
@@ -44,46 +44,60 @@ int EQP::fEQcompare (const void * a, const void * b)
return 1;
}
-float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, float samplerate, float scale, int ctfmode, int wintype)
+float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, double samplerate, double scale, int ctfmode, int wintype)
{
float* fp = new float[nfreqs + 2]; // (float *) malloc0 ((nfreqs + 2) * sizeof (float));
float* gp = new float[nfreqs + 2]; // (float *) malloc0 ((nfreqs + 2) * sizeof (float));
float* A = new float[N / 2 + 1]; // (float *) malloc0 ((N / 2 + 1) * sizeof (float));
float* sary = new float[2 * nfreqs]; // (float *) malloc0 (2 * nfreqs * sizeof (float));
- float gpreamp, f, frac;
+ double gpreamp, f, frac;
float* impulse;
int i, j, mid;
fp[0] = 0.0;
fp[nfreqs + 1] = 1.0;
gpreamp = G[0];
+
for (i = 1; i <= nfreqs; i++)
{
fp[i] = 2.0 * F[i] / samplerate;
- if (fp[i] < 0.0) fp[i] = 0.0;
- if (fp[i] > 1.0) fp[i] = 1.0;
+
+ if (fp[i] < 0.0)
+ fp[i] = 0.0;
+
+ if (fp[i] > 1.0)
+ fp[i] = 1.0;
+
gp[i] = G[i];
}
+
for (i = 1, j = 0; i <= nfreqs; i++, j+=2)
{
sary[j + 0] = fp[i];
sary[j + 1] = gp[i];
}
+
qsort (sary, nfreqs, 2 * sizeof (float), fEQcompare);
+
for (i = 1, j = 0; i <= nfreqs; i++, j+=2)
{
fp[i] = sary[j + 0];
gp[i] = sary[j + 1];
}
+
gp[0] = gp[1];
gp[nfreqs + 1] = gp[nfreqs];
mid = N / 2;
j = 0;
+
if (N & 1)
{
for (i = 0; i <= mid; i++)
{
- f = (float)i / (float)mid;
- while (f > fp[j + 1]) j++;
+ f = (double)i / (double)mid;
+
+ while ((f > fp[j + 1]) && (j < nfreqs))
+ j++;
+
frac = (f - fp[j]) / (fp[j + 1] - fp[j]);
A[i] = pow (10.0, 0.05 * (frac * gp[j + 1] + (1.0 - frac) * gp[j] + gpreamp)) * scale;
}
@@ -92,36 +106,44 @@ float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, float samplerate,
{
for (i = 0; i < mid; i++)
{
- f = ((float)i + 0.5) / (float)mid;
- while (f > fp[j + 1]) j++;
+ f = ((double)i + 0.5) / (double)mid;
+
+ while ((f > fp[j + 1]) && (j < nfreqs))
+ j++;
+
frac = (f - fp[j]) / (fp[j + 1] - fp[j]);
A[i] = pow (10.0, 0.05 * (frac * gp[j + 1] + (1.0 - frac) * gp[j] + gpreamp)) * scale;
}
}
+
if (ctfmode == 0)
{
int k, low, high;
- float lowmag, highmag, flow4, fhigh4;
+ double lowmag, highmag, flow4, fhigh4;
+
if (N & 1)
{
low = (int)(fp[1] * mid);
high = (int)(fp[nfreqs] * mid + 0.5);
lowmag = A[low];
highmag = A[high];
- flow4 = pow((float)low / (float)mid, 4.0);
- fhigh4 = pow((float)high / (float)mid, 4.0);
+ flow4 = pow((double)low / (double)mid, 4.0);
+ fhigh4 = pow((double)high / (double)mid, 4.0);
k = low;
+
while (--k >= 0)
{
- f = (float)k / (float)mid;
+ f = (double)k / (double)mid;
lowmag *= (f * f * f * f) / flow4;
if (lowmag < 1.0e-20) lowmag = 1.0e-20;
A[k] = lowmag;
}
+
k = high;
+
while (++k <= mid)
{
- f = (float)k / (float)mid;
+ f = (double)k / (double)mid;
highmag *= fhigh4 / (f * f * f * f);
if (highmag < 1.0e-20) highmag = 1.0e-20;
A[k] = highmag;
@@ -133,30 +155,35 @@ float* EQP::eq_impulse (int N, int nfreqs, float* F, float* G, float samplerate,
high = (int)(fp[nfreqs] * mid - 0.5);
lowmag = A[low];
highmag = A[high];
- flow4 = pow((float)low / (float)mid, 4.0);
- fhigh4 = pow((float)high / (float)mid, 4.0);
+ flow4 = pow((double)low / (double)mid, 4.0);
+ fhigh4 = pow((double)high / (double)mid, 4.0);
k = low;
+
while (--k >= 0)
{
- f = (float)k / (float)mid;
+ f = (double)k / (double)mid;
lowmag *= (f * f * f * f) / flow4;
if (lowmag < 1.0e-20) lowmag = 1.0e-20;
A[k] = lowmag;
}
+
k = high;
+
while (++k < mid)
{
- f = (float)k / (float)mid;
+ f = (double)k / (double)mid;
highmag *= fhigh4 / (f * f * f * f);
if (highmag < 1.0e-20) highmag = 1.0e-20;
A[k] = highmag;
}
}
}
+
if (N & 1)
impulse = FIR::fir_fsamp_odd(N, A, 1, 1.0, wintype);
else
impulse = FIR::fir_fsamp(N, A, 1, 1.0, wintype);
+
// print_impulse("eq.txt", N, impulse, 1, 0);
delete[] (sary);
delete[] (A);
diff --git a/wdsp/eq.hpp b/wdsp/eq.hpp
index 410c3e20b..f2cc5ec62 100644
--- a/wdsp/eq.hpp
+++ b/wdsp/eq.hpp
@@ -56,7 +56,7 @@ public:
float* G;
int ctfmode;
int wintype;
- float samplerate;
+ double samplerate;
FIRCORE *p;
static EQP* create_eqp (
@@ -73,7 +73,7 @@ public:
int wintype,
int samplerate
);
- static float* eq_impulse (int N, int nfreqs, float* F, float* G, float samplerate, float scale, int ctfmode, int wintype);
+ static float* eq_impulse (int N, int nfreqs, float* F, float* G, double samplerate, double scale, int ctfmode, int wintype);
static void destroy_eqp (EQP *a);
static void flush_eqp (EQP *a);
static void xeqp (EQP *a);
diff --git a/wdsp/fir.cpp b/wdsp/fir.cpp
index 627a8fdc0..e7a404b01 100644
--- a/wdsp/fir.cpp
+++ b/wdsp/fir.cpp
@@ -318,8 +318,8 @@ float *FIR::fir_read (int N, const char *filename, int rtype, float scale)
void FIR::analytic (int N, float* in, float* out)
{
int i;
- float inv_N = 1.0 / (float) N;
- float two_inv_N = 2.0 * inv_N;
+ double inv_N = 1.0 / (double) N;
+ double two_inv_N = 2.0 * inv_N;
float* x = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
fftwf_plan pfor = fftwf_plan_dft_1d (
N,
diff --git a/wdsp/make_calculus.cpp b/wdsp/make_calculus.cpp
deleted file mode 100644
index 0b484c2dd..000000000
--- a/wdsp/make_calculus.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * make_calculus
- *
- * This program reads the contents of the binary WDSP file "calculus"
- * and dumps the data as two arrays of floating-point numbers
- *
- * The output is intended to be part of the file "calculus.c" which
- * initializes these arrays (static data) for use with "memcpy"
- * in emnr.c.
- *
- * Should the WDSP file "calculus" be changed, "calculus.c" should
- * be re-generated using this program.
- *
- * return values of main()
- *
- * 0 all OK
- * -1 sizeof(float) is not 8
- * -2 error opening file "calculus"
- * -3 read error
- */
-
-#include
-#include
-#include
-
-int main() {
- int fd;
- int i,j;
- float d;
-
- if (sizeof(float) != 8) {
- printf("Data type DOUBLE is not 8-byte. Please check!\n");
- return -1;
- }
- fd=open ("calculus", O_RDONLY);
- if (fd < 0) {
- printf("Could not open file 'calculus'\n");
- return -2;
- }
-
- for (j=0; j<2; j++) {
- switch (j) {
- case 0:
- printf("float GG[241*241]={\n");
- break;
- case 1:
- printf("float GGS[241*241]={\n");
- break;
- }
- for (i=0; i< 241*241; i++) {
- if (read(fd, &d, 8) != 8) {
- printf("READ ERROR\n");
- return -3;
- }
- if (i == 241*241 -1) {
- printf("%30.25f};\n", d);
- } else {
- printf("%30.25f,\n", d);
- }
- }
- return 0;
- }
-}
diff --git a/wdsp/make_interface.cpp b/wdsp/make_interface.cpp
deleted file mode 100644
index 755cf354f..000000000
--- a/wdsp/make_interface.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- The purpose of this file is to extract interfaces from the WDSP source code.
- The interfaces have the following form:
-
- PORT blabla
- firstline
- secondline
- {
-
- where there may be an arbitrary number of lines between the line
- containing "PORT" and the line starting with "{". This has to be
- converted to
-
- extern blabla firstline
- secondline;
-
- That is, the first line is prepended by "extern", and the last line is closed
- with a semicolon. Comments starting with '//' are omitted, and lines starting
- with '//' are ignored.
-*/
-
-
-#include
-#include
-#include
-
-void trimm(char *line, size_t maxlen);
-
-int main(int argc, char **argv)
-{
- FILE *infile;
- int i;
- int first_in_file;
- int first_in_decl;
- char line[1000];
- size_t linesize=999;
- char *buffer=line;
-
- for (i=1; i4) {
- printf("extern %s ", line+4);
- } else {
- printf("extern ");
- }
- first_in_decl=1;
-
- for (;;) {
- if (getline(&buffer, &linesize, infile) < 0) {
- fprintf(stderr,"! Found a PORT but found EOF while scanning interface.\n");
- return 8;
- }
- trimm(line, linesize);
- if (line[0] == 0) continue;
- if (line[0] == '{') {
- printf(";\n");
- break;
- } else {
- if (first_in_decl) {
- printf("%s", line);
- first_in_decl=0;
- } else {
- printf("\n%s", line);
- }
- }
- }
- }
- fclose(infile);
- }
- return 0;
-}
-
-void trimm(char *line, size_t maxlen) {
- int len;
-
- //
- // Remove comments starting with '//'
- //
- len=strnlen(line,maxlen);
- for (int i=0; i< len-1; i++) {
- if (line[i] == '/' && line[i+1] == '/') line[i]=0;
- }
-
- //
- // Remove trailing white space and newlines
- //
- len=strnlen(line,maxlen);
- line[len--]=0;
- while (len >= 0 && (line[len] == ' ' || line[len] == '\t' || line[len]== '\n')) line[len--]=0;
-}
diff --git a/wdsp/nbp.cpp b/wdsp/nbp.cpp
index cfc48d70c..6ebe0d723 100644
--- a/wdsp/nbp.cpp
+++ b/wdsp/nbp.cpp
@@ -132,6 +132,7 @@ int NBP::make_nbp (
else
{
nbp = 0;
+ delete[] del;
return nbp;
}
*havnotch = 0;
diff --git a/wdsp/resample.cpp b/wdsp/resample.cpp
index 372ebf31c..ac66017a1 100644
--- a/wdsp/resample.cpp
+++ b/wdsp/resample.cpp
@@ -60,6 +60,9 @@ void RESAMPLE::calc_resample (RESAMPLE *a)
a->L = a->out_rate / x;
a->M = a->in_rate / x;
+ a->L <= 0 ? 1 : a->L;
+ a->M <= 0 ? 1 : a->M;
+
if (a->in_rate < a->out_rate)
min_rate = a->in_rate;
else
diff --git a/wdsp/resamplef.cpp b/wdsp/resamplef.cpp
index 36bc5020d..41624abdc 100644
--- a/wdsp/resamplef.cpp
+++ b/wdsp/resamplef.cpp
@@ -64,6 +64,9 @@ RESAMPLEF* RESAMPLEF::create_resampleF ( int run, int size, float* in, float* ou
a->L = out_rate / x;
a->M = in_rate / x;
+ a->L <= 0 ? 1 : a->L;
+ a->M <= 0 ? 1 : a->M;
+
if (in_rate < out_rate)
min_rate = in_rate;
else