mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-06-28 23:15:28 -04:00
Compare commits
18 Commits
3c337d6cf5
...
02babd5ff8
Author | SHA1 | Date | |
---|---|---|---|
|
02babd5ff8 | ||
|
c0aa1b0358 | ||
|
f6d97efe55 | ||
|
0fd169c008 | ||
|
c32116a330 | ||
|
40f7ecdaa0 | ||
|
37a36532d0 | ||
|
da7b3fbd41 | ||
|
3f800dd0a9 | ||
|
6d3516482e | ||
|
5d68bf73b3 | ||
|
7f1cb0e203 | ||
|
be080f432c | ||
|
3a4981046c | ||
|
0b62856e70 | ||
|
e340517d1c | ||
|
e939c8c246 | ||
|
585077eaef |
.gitignore
plugins/channelrx/wdsprx
CMakeLists.txtwdsprxcwpeakdialog.hwdsprxdnbdialog.hwdsprxdnrdialog.cppwdsprxdnrdialog.hwdsprxdnrdialog.uiwdsprxeqdialog.hwdsprxfmdialog.hwdsprxgui.cppwdsprxgui.hwdsprxgui.uiwdsprxpandialog.cppwdsprxpandialog.hwdsprxpandialog.uiwdsprxsettings.cppwdsprxsettings.hwdsprxsettings.h.origwdsprxsink.cppwdsprxsink.cpp.origwdsprxsquelchdialog.h
sdrbase/resources/webapi/doc
swagger/sdrangel
wdsp
CMakeLists.txtRXA.cppTXA.cppamd.cppammod.cppamsq.cppamsq.hppanb.cppanb.hppanf.cppanf.hppanr.cppanr.hppbandpass.cppbandpass.hppbps.cppbpsnba.cppcblock.cppcblock.hppcfcomp.cppcfir.cppcfir.hppchannel.hppcomm.hppcompress.cppdelay.cppemnr.cppemnr.hppemph.cppeq.cppeq.hppfcurve.cppfir.cppfir.hppfircore.cppfirmin.cppfiropt.cppfmd.cppfmmod.cppfmsq.cppfmsq.hppgain.cppgen.cppicfir.cppiir.cppiir.hppiqc.cppmake_calculus.cppmake_interface.cppmeter.cppnbp.cppnbp.hppnob.cpposctrl.cpppatchpanel.cpppatchpanel.hppresample.cppresample.hppresamplef.cppresamplef.hpprmatch.cppshift.cppshift.hppsiphon.cppslew.cppsnba.cppssql.cppvarsamp.cppwcpAGC.cppwcpAGC.hpp
2
.gitignore
vendored
2
.gitignore
vendored
@ -14,7 +14,9 @@ LOCAL/*
|
||||
.vscode/
|
||||
.settings/
|
||||
*.cs
|
||||
*.orig
|
||||
*.pro.user
|
||||
*.rej
|
||||
.idea/*
|
||||
rescuesdriq/rescuesdriq
|
||||
debian/sdrangel/*
|
||||
|
@ -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)
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
};
|
||||
|
||||
explicit WDSPRxCWPeakDialog(QWidget* parent = nullptr);
|
||||
~WDSPRxCWPeakDialog();
|
||||
~WDSPRxCWPeakDialog() override;
|
||||
|
||||
void setCWPeakFrequency(double cwPeakFrequency);
|
||||
void setCWBandwidth(double cwBandwidth);
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
};
|
||||
|
||||
explicit WDSPRxDNBDialog(QWidget* parent = nullptr);
|
||||
~WDSPRxDNBDialog();
|
||||
~WDSPRxDNBDialog() override;
|
||||
|
||||
void setNBScheme(WDSPRxProfile::WDSPRxNBScheme scheme);
|
||||
void setNB2Mode(WDSPRxProfile::WDSPRxNB2Mode mode);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -53,16 +53,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="anf">
|
||||
<property name="toolTip">
|
||||
<string>Automatic Notch Filter</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ANF</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
};
|
||||
|
||||
explicit WDSPRxEqDialog(QWidget* parent = nullptr);
|
||||
~WDSPRxEqDialog();
|
||||
~WDSPRxEqDialog() override;
|
||||
|
||||
void setEqF(const std::array<float, 11>& eqF);
|
||||
void setEqG(const std::array<float, 11>& eqG);
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
};
|
||||
|
||||
explicit WDSPRxFMDialog(QWidget* parent = nullptr);
|
||||
~WDSPRxFMDialog();
|
||||
~WDSPRxFMDialog() override;
|
||||
|
||||
void setDeviation(double deviation);
|
||||
void setAFLow(double afLow);
|
||||
|
@ -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<int>::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<int>::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);
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -278,7 +278,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDial" name="filterIndex">
|
||||
<widget class="QDial" name="profileIndex">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
@ -303,7 +303,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="filterIndexText">
|
||||
<widget class="QLabel" name="profileIndexText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>10</width>
|
||||
@ -559,7 +559,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Highpass filter cutoff frequency (SSB)</string>
|
||||
<string>Bandpass filter near (to 0) cutoff frequency (SSB)</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-60</number>
|
||||
@ -641,7 +641,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Lowpass filter cutoff frequency</string>
|
||||
<string>Bandpass filter far (from 0) cutoff frequency</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-60</number>
|
||||
@ -989,6 +989,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="anf">
|
||||
<property name="toolTip">
|
||||
<string>Toggle Automatic Notch Filter</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ANF</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="cwPeaking">
|
||||
<property name="toolTip">
|
||||
|
55
plugins/channelrx/wdsprx/wdsprxpandialog.cpp
Normal file
55
plugins/channelrx/wdsprx/wdsprxpandialog.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2024 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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);
|
||||
}
|
53
plugins/channelrx/wdsprx/wdsprxpandialog.h
Normal file
53
plugins/channelrx/wdsprx/wdsprxpandialog.h
Normal file
@ -0,0 +1,53 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2024 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDE_WDSPRXPANDIALOG_H
|
||||
#define INCLUDE_WDSPRXPANDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#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
|
210
plugins/channelrx/wdsprx/wdsprxpandialog.ui
Normal file
210
plugins/channelrx/wdsprx/wdsprxpandialog.ui
Normal file
@ -0,0 +1,210 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>WDSPRxPanDialog</class>
|
||||
<widget class="QDialog" name="WDSPRxPanDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>385</width>
|
||||
<height>111</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Audio Pan</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="panLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="zero">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Reset to 0 (center)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="TickedSlider" name="pan">
|
||||
<property name="toolTip">
|
||||
<string>Pan value (%) negative: left positive: right</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="panText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-100</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="scaleLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="leftPad">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="leftText">
|
||||
<property name="text">
|
||||
<string>L</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="zeroText">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>12</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="rightText">
|
||||
<property name="text">
|
||||
<string>R</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="rightPad">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>TickedSlider</class>
|
||||
<extends>QSlider</extends>
|
||||
<header>gui/tickedslider.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>WDSPRxPanDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>WDSPRxPanDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -1,271 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2024 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PLUGINS_CHANNELRX_WDSPRX_WDSPRXSETTINGS_H_
|
||||
#define PLUGINS_CHANNELRX_WDSPRX_WDSPRXSETTINGS_H_
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
|
||||
#include "dsp/fftwindow.h"
|
||||
|
||||
class Serializable;
|
||||
|
||||
|
||||
struct WDSPRxProfile
|
||||
{
|
||||
enum WDSPRxDemod
|
||||
{
|
||||
DemodSSB,
|
||||
DemodAM,
|
||||
DemodSAM,
|
||||
DemodFMN,
|
||||
};
|
||||
enum WDSPRxAGCMode
|
||||
{
|
||||
AGCLong,
|
||||
AGCSlow,
|
||||
AGCMedium,
|
||||
AGCFast,
|
||||
};
|
||||
enum WDSPRxNRScheme
|
||||
{
|
||||
NRSchemeNR,
|
||||
NRSchemeNR2,
|
||||
};
|
||||
enum WDSPRxNBScheme
|
||||
{
|
||||
NBSchemeNB, //!< Preemptive Wideband Blanker (ANB)
|
||||
NBSchemeNB2, //!< Interpolating Wideband Blanker (NOB)
|
||||
};
|
||||
enum WDSPRxNR2Gain
|
||||
{
|
||||
NR2GainLinear,
|
||||
NR2GainLog,
|
||||
NR2GainGamma,
|
||||
};
|
||||
enum WDSPRxNR2NPE
|
||||
{
|
||||
NR2NPEOSMS,
|
||||
NR2NPEMMSE,
|
||||
};
|
||||
enum WDSPRxNRPosition
|
||||
{
|
||||
NRPositionPreAGC,
|
||||
NRPositionPostAGC,
|
||||
};
|
||||
enum WDSPRxNB2Mode
|
||||
{
|
||||
NB2ModeZero,
|
||||
NB2ModeSampleAndHold,
|
||||
NB2ModeMeanHold,
|
||||
NB2ModeHoldSample,
|
||||
NB2ModeInterpolate,
|
||||
};
|
||||
enum WDSPRxSquelchMode
|
||||
{
|
||||
SquelchModeVoice,
|
||||
SquelchModeAM,
|
||||
SquelchModeFM,
|
||||
};
|
||||
|
||||
WDSPRxDemod m_demod;
|
||||
// Filter
|
||||
int m_spanLog2;
|
||||
Real m_highCutoff;
|
||||
Real m_lowCutoff;
|
||||
int m_fftWindow; // 0: 4-term Blackman-Harris, 1: 7-term Blackman-Harris
|
||||
// AGC
|
||||
bool m_agc;
|
||||
WDSPRxAGCMode m_agcMode;
|
||||
int m_agcGain; //!< Fixed gain if AGC is off else top gain
|
||||
int m_agcSlope;
|
||||
int m_agcHangThreshold;
|
||||
// Noise blanker
|
||||
bool m_dnb;
|
||||
WDSPRxNBScheme m_nbScheme;
|
||||
WDSPRxNB2Mode m_nb2Mode;
|
||||
double m_nbSlewTime; // a.k.a tau
|
||||
double m_nbLeadTime; // a.k.a adv time
|
||||
double m_nbLagTime; // a.k.a hang time
|
||||
int m_nbThreshold;
|
||||
double m_nbAvgTime; // a.k.a back tau
|
||||
// Noise rediction
|
||||
bool m_dnr;
|
||||
bool m_anf;
|
||||
WDSPRxNRScheme m_nrScheme;
|
||||
WDSPRxNR2Gain m_nr2Gain;
|
||||
WDSPRxNR2NPE m_nr2NPE;
|
||||
WDSPRxNRPosition m_nrPosition;
|
||||
bool m_nr2ArtifactReduction;
|
||||
// Demods
|
||||
bool m_amFadeLevel;
|
||||
bool m_cwPeaking;
|
||||
double m_cwPeakFrequency;
|
||||
double m_cwBandwidth;
|
||||
double m_cwGain;
|
||||
double m_fmDeviation;
|
||||
double m_fmAFLow;
|
||||
double m_fmAFHigh;
|
||||
bool m_fmAFLimiter;
|
||||
double m_fmAFLimiterGain;
|
||||
bool m_fmCTCSSNotch;
|
||||
double m_fmCTCSSNotchFrequency;
|
||||
// Squelch
|
||||
bool m_squelch;
|
||||
int m_squelchThreshold;
|
||||
WDSPRxSquelchMode m_squelchMode;
|
||||
double m_ssqlTauMute; //!< Voice squelch tau mute
|
||||
double m_ssqlTauUnmute; //!< Voice squelch tau unmute
|
||||
double m_amsqMaxTail;
|
||||
|
||||
WDSPRxProfile() :
|
||||
m_demod(DemodSSB),
|
||||
m_spanLog2(3),
|
||||
m_highCutoff(3000),
|
||||
m_lowCutoff(300),
|
||||
m_fftWindow(0),
|
||||
m_agc(false),
|
||||
m_agcMode(AGCMedium),
|
||||
m_agcGain(80),
|
||||
m_agcSlope(35),
|
||||
m_agcHangThreshold(0),
|
||||
m_dnb(false),
|
||||
m_nbScheme(NBSchemeNB),
|
||||
m_nb2Mode(NB2ModeZero),
|
||||
m_nbSlewTime(0.1),
|
||||
m_nbLeadTime(0.1),
|
||||
m_nbLagTime(0.1),
|
||||
m_nbThreshold(30),
|
||||
m_nbAvgTime(50.0),
|
||||
m_dnr(false),
|
||||
m_anf(false),
|
||||
m_nrScheme(NRSchemeNR),
|
||||
m_nr2Gain(NR2GainGamma),
|
||||
m_nr2NPE(NR2NPEOSMS),
|
||||
m_nrPosition(NRPositionPreAGC),
|
||||
m_nr2ArtifactReduction(true),
|
||||
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),
|
||||
m_squelch(false),
|
||||
m_squelchThreshold(3),
|
||||
m_squelchMode(SquelchModeVoice),
|
||||
m_ssqlTauMute(0.1),
|
||||
m_ssqlTauUnmute(0.1),
|
||||
m_amsqMaxTail(1.5)
|
||||
{}
|
||||
};
|
||||
|
||||
struct WDSPRxSettings
|
||||
{
|
||||
WDSPRxProfile::WDSPRxDemod m_demod;
|
||||
qint32 m_inputFrequencyOffset;
|
||||
// Real m_highCutoff;
|
||||
// Real m_lowCutoff;
|
||||
Real m_volume;
|
||||
// int m_spanLog2;
|
||||
bool m_audioBinaural;
|
||||
bool m_audioFlipChannels;
|
||||
bool m_dsb;
|
||||
bool m_audioMute;
|
||||
// AGC
|
||||
bool m_agc;
|
||||
WDSPRxProfile::WDSPRxAGCMode m_agcMode;
|
||||
int m_agcGain; //!< Fixed gain if AGC is off else top gain
|
||||
int m_agcSlope;
|
||||
int m_agcHangThreshold;
|
||||
// Noise blanker
|
||||
bool m_dnb;
|
||||
WDSPRxProfile::WDSPRxNBScheme m_nbScheme;
|
||||
WDSPRxProfile::WDSPRxNB2Mode m_nb2Mode;
|
||||
double m_nbSlewTime;
|
||||
double m_nbLeadTime;
|
||||
double m_nbLagTime;
|
||||
int m_nbThreshold;
|
||||
double m_nbAvgTime;
|
||||
// Noise reduction
|
||||
bool m_dnr;
|
||||
bool m_anf;
|
||||
WDSPRxProfile::WDSPRxNRScheme m_nrScheme;
|
||||
WDSPRxProfile::WDSPRxNR2Gain m_nr2Gain;
|
||||
WDSPRxProfile::WDSPRxNR2NPE m_nr2NPE;
|
||||
WDSPRxProfile::WDSPRxNRPosition m_nrPosition;
|
||||
bool m_nr2ArtifactReduction;
|
||||
// Demods
|
||||
bool m_amFadeLevel;
|
||||
bool m_cwPeaking;
|
||||
double m_cwPeakFrequency;
|
||||
double m_cwBandwidth;
|
||||
double m_cwGain;
|
||||
double m_fmDeviation;
|
||||
double m_fmAFLow;
|
||||
double m_fmAFHigh;
|
||||
bool m_fmAFLimiter;
|
||||
double m_fmAFLimiterGain;
|
||||
bool m_fmCTCSSNotch;
|
||||
double m_fmCTCSSNotchFrequency;
|
||||
// Squelch
|
||||
bool m_squelch;
|
||||
int m_squelchThreshold;
|
||||
WDSPRxProfile::WDSPRxSquelchMode m_squelchMode;
|
||||
double m_ssqlTauMute; //!< Voice squelch tau mute
|
||||
double m_ssqlTauUnmute; //!< Voice squelch tau unmute
|
||||
double m_amsqMaxTail;
|
||||
|
||||
quint32 m_rgbColor;
|
||||
QString m_title;
|
||||
QString m_audioDeviceName;
|
||||
int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
|
||||
bool m_useReverseAPI;
|
||||
QString m_reverseAPIAddress;
|
||||
uint16_t m_reverseAPIPort;
|
||||
uint16_t m_reverseAPIDeviceIndex;
|
||||
uint16_t m_reverseAPIChannelIndex;
|
||||
int m_workspaceIndex;
|
||||
QByteArray m_geometryBytes;
|
||||
bool m_hidden;
|
||||
std::vector<WDSPRxProfile> m_profiles;
|
||||
unsigned int m_profileIndex;
|
||||
|
||||
Serializable *m_channelMarker;
|
||||
Serializable *m_spectrumGUI;
|
||||
Serializable *m_rollupState;
|
||||
|
||||
WDSPRxSettings();
|
||||
void resetToDefaults();
|
||||
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
||||
void setSpectrumGUI(Serializable *spectrumGUI) { m_spectrumGUI = spectrumGUI; }
|
||||
void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; }
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
|
||||
static const int m_minPowerThresholdDB;
|
||||
static const float m_mminPowerThresholdDBf;
|
||||
};
|
||||
|
||||
|
||||
#endif /* PLUGINS_CHANNELRX_WDSPRX_WDSPRXSETTINGS_H_ */
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,782 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2024 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <QTime>
|
||||
#include <QDebug>
|
||||
|
||||
#include "dsp/spectrumvis.h"
|
||||
#include "dsp/datafifo.h"
|
||||
#include "util/db.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "maincore.h"
|
||||
#include "RXA.hpp"
|
||||
#include "nbp.hpp"
|
||||
#include "meter.hpp"
|
||||
#include "patchpanel.hpp"
|
||||
#include "wcpAGC.hpp"
|
||||
#include "anr.hpp"
|
||||
#include "emnr.hpp"
|
||||
#include "snba.hpp"
|
||||
#include "anf.hpp"
|
||||
#include "anb.hpp"
|
||||
#include "nob.hpp"
|
||||
#include "amd.hpp"
|
||||
#include "fmd.hpp"
|
||||
#include "iir.cpp"
|
||||
#include "ssql.hpp"
|
||||
#include "amsq.hpp"
|
||||
#include "fmsq.hpp"
|
||||
|
||||
#include "wdsprxsink.h"
|
||||
|
||||
const int WDSPRxSink::m_ssbFftLen = 2048;
|
||||
const int WDSPRxSink::m_wdspSampleRate = 48000;
|
||||
const int WDSPRxSink::m_wdspBufSize = 512;
|
||||
|
||||
WDSPRxSink::SpectrumProbe::SpectrumProbe(SampleVector& sampleVector) :
|
||||
m_sampleVector(sampleVector),
|
||||
m_spanLog2(0),
|
||||
m_dsb(false),
|
||||
m_usb(true),
|
||||
m_sum(0)
|
||||
{}
|
||||
|
||||
void WDSPRxSink::SpectrumProbe::setSpanLog2(int spanLog2)
|
||||
{
|
||||
m_spanLog2 = spanLog2;
|
||||
}
|
||||
|
||||
void WDSPRxSink::SpectrumProbe::proceed(const float *in, int nb_samples)
|
||||
{
|
||||
int decim = 1<<(m_spanLog2 - 1);
|
||||
unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
|
||||
|
||||
for (int i = 0; i < nb_samples; i++)
|
||||
{
|
||||
float cr = in[2*i+1];
|
||||
float ci = in[2*i];
|
||||
m_sum += std::complex<float>{cr, ci};
|
||||
|
||||
if (decim == 1)
|
||||
{
|
||||
m_sampleVector.push_back(Sample(cr*SDR_RX_SCALEF, ci*SDR_RX_SCALEF));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(m_undersampleCount++ & decim_mask))
|
||||
{
|
||||
float avgr = m_sum.real() / decim;
|
||||
float avgi = m_sum.imag() / decim;
|
||||
|
||||
if (!m_dsb & !m_usb)
|
||||
{ // invert spectrum for LSB
|
||||
m_sampleVector.push_back(Sample(avgi*SDR_RX_SCALEF, avgr*SDR_RX_SCALEF));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sampleVector.push_back(Sample(avgr*SDR_RX_SCALEF, avgi*SDR_RX_SCALEF));
|
||||
}
|
||||
|
||||
m_sum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WDSPRxSink::WDSPRxSink() :
|
||||
m_squelchDelayLine(2*48000),
|
||||
m_audioActive(false),
|
||||
m_spectrumSink(nullptr),
|
||||
m_spectrumProbe(m_sampleBuffer),
|
||||
m_inCount(0),
|
||||
m_audioFifo(24000),
|
||||
m_audioSampleRate(48000)
|
||||
{
|
||||
m_Bandwidth = 5000;
|
||||
m_channelSampleRate = 48000;
|
||||
m_channelFrequencyOffset = 0;
|
||||
|
||||
m_audioBuffer.resize(m_audioSampleRate / 10);
|
||||
m_audioBufferFill = 0;
|
||||
m_undersampleCount = 0;
|
||||
|
||||
m_demodBuffer.resize(1<<12);
|
||||
m_demodBufferFill = 0;
|
||||
|
||||
m_sAvg = 0.0;
|
||||
m_sPeak = 0.0;
|
||||
m_sCount = 1;
|
||||
|
||||
m_rxa = WDSP::RXA::create_rxa(
|
||||
m_wdspSampleRate, // input samplerate
|
||||
m_wdspSampleRate, // output samplerate
|
||||
m_wdspSampleRate, // sample rate for mainstream dsp processing (dsp)
|
||||
m_wdspBufSize // number complex samples processed per buffer in mainstream dsp processing
|
||||
);
|
||||
m_rxa->setSpectrumProbe(&m_spectrumProbe);
|
||||
WDSP::RXA::SetPassband(*m_rxa, 0, m_Bandwidth);
|
||||
WDSP::ANR::SetANRVals(*m_rxa, 64, 16, 16e-4, 10e-7);
|
||||
|
||||
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
|
||||
applySettings(m_settings, true);
|
||||
}
|
||||
|
||||
WDSPRxSink::~WDSPRxSink()
|
||||
{
|
||||
WDSP::RXA::destroy_rxa(m_rxa);
|
||||
}
|
||||
|
||||
void WDSPRxSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
||||
{
|
||||
if (m_channelSampleRate == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Complex ci;
|
||||
|
||||
for(SampleVector::const_iterator it = begin; it < end; ++it)
|
||||
{
|
||||
Complex c(it->real(), it->imag());
|
||||
c *= m_nco.nextIQ();
|
||||
|
||||
if (m_interpolatorDistance < 1.0f) // interpolate
|
||||
{
|
||||
while (!m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci))
|
||||
{
|
||||
processOneSample(ci);
|
||||
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci))
|
||||
{
|
||||
processOneSample(ci);
|
||||
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WDSPRxSink::getMagSqLevels(double& avg, double& peak, int& nbSamples)
|
||||
{
|
||||
avg = m_sAvg;
|
||||
peak = m_sPeak;
|
||||
nbSamples = m_sCount;
|
||||
}
|
||||
|
||||
void WDSPRxSink::processOneSample(Complex &ci)
|
||||
{
|
||||
m_rxa->get_inbuff()[2*m_inCount] = ci.imag() / SDR_RX_SCALEF;
|
||||
m_rxa->get_inbuff()[2*m_inCount+1] = ci.real() / SDR_RX_SCALEF;
|
||||
|
||||
if (++m_inCount == m_rxa->get_insize())
|
||||
{
|
||||
WDSP::RXA::xrxa(m_rxa);
|
||||
|
||||
m_sCount = m_wdspBufSize;
|
||||
m_sAvg = WDSP::METER::GetMeter(*m_rxa, WDSP::RXA::RXA_S_AV);
|
||||
m_sPeak = WDSP::METER::GetMeter(*m_rxa, WDSP::RXA::RXA_S_PK);
|
||||
|
||||
for (int i = 0; i < m_rxa->get_outsize(); i++)
|
||||
{
|
||||
if (m_settings.m_audioMute)
|
||||
{
|
||||
m_audioBuffer[m_audioBufferFill].r = 0;
|
||||
m_audioBuffer[m_audioBufferFill].l = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const double& cr = m_rxa->get_outbuff()[2*i+1];
|
||||
const double& ci = m_rxa->get_outbuff()[2*i];
|
||||
qint16 zr = cr * 32768.0;
|
||||
qint16 zi = ci * 32768.0;
|
||||
m_audioBuffer[m_audioBufferFill].r = zr;
|
||||
m_audioBuffer[m_audioBufferFill].l = zi;
|
||||
|
||||
if (m_settings.m_audioBinaural)
|
||||
{
|
||||
m_demodBuffer[m_demodBufferFill++] = zr;
|
||||
m_demodBuffer[m_demodBufferFill++] = zi;
|
||||
}
|
||||
else
|
||||
{
|
||||
Real demod = (zr + zi) * 0.7;
|
||||
qint16 sample = (qint16)(demod);
|
||||
m_demodBuffer[m_demodBufferFill++] = sample;
|
||||
}
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
fifo->write(
|
||||
(quint8*) &m_demodBuffer[0],
|
||||
m_demodBuffer.size() * sizeof(qint16),
|
||||
m_settings.m_audioBinaural ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_demodBufferFill = 0;
|
||||
}
|
||||
} // audio sample
|
||||
|
||||
if (++m_audioBufferFill == m_audioBuffer.size())
|
||||
{
|
||||
std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], std::min(m_audioBufferFill, m_audioBuffer.size()));
|
||||
|
||||
if (res != m_audioBufferFill) {
|
||||
qDebug("WDSPRxSink::processOneSample: %lu/%lu samples written", res, m_audioBufferFill);
|
||||
}
|
||||
|
||||
m_audioBufferFill = 0;
|
||||
}
|
||||
} // result loop
|
||||
|
||||
if (m_spectrumSink && (m_sampleBuffer.size() != 0))
|
||||
{
|
||||
m_spectrumSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), !m_settings.m_dsb);
|
||||
m_sampleBuffer.clear();
|
||||
}
|
||||
|
||||
m_inCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void WDSPRxSink::applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force)
|
||||
{
|
||||
qDebug() << "WDSPRxSink::applyChannelSettings:"
|
||||
<< " channelSampleRate: " << channelSampleRate
|
||||
<< " channelFrequencyOffset: " << channelFrequencyOffset;
|
||||
|
||||
if ((m_channelFrequencyOffset != channelFrequencyOffset) ||
|
||||
(m_channelSampleRate != channelSampleRate) || force)
|
||||
{
|
||||
m_nco.setFreq(-channelFrequencyOffset, channelSampleRate);
|
||||
}
|
||||
|
||||
if ((m_channelSampleRate != channelSampleRate) || force)
|
||||
{
|
||||
Real interpolatorBandwidth = (m_Bandwidth * 1.5f) > channelSampleRate ? channelSampleRate : (m_Bandwidth * 1.5f);
|
||||
m_interpolator.create(16, channelSampleRate, interpolatorBandwidth, 2.0f);
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorDistance = (Real) channelSampleRate / (Real) m_wdspSampleRate;
|
||||
}
|
||||
|
||||
m_channelSampleRate = channelSampleRate;
|
||||
m_channelFrequencyOffset = channelFrequencyOffset;
|
||||
}
|
||||
|
||||
void WDSPRxSink::applyAudioSampleRate(int sampleRate)
|
||||
{
|
||||
qDebug("WDSPRxSink::applyAudioSampleRate: %d", sampleRate);
|
||||
|
||||
Real interpolatorBandwidth = (m_Bandwidth * 1.5f) > m_channelSampleRate ? m_channelSampleRate : (m_Bandwidth * 1.5f);
|
||||
m_interpolator.create(16, m_channelSampleRate, interpolatorBandwidth, 2.0f);
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorDistance = (Real) m_channelSampleRate / (Real) m_wdspSampleRate;
|
||||
|
||||
WDSP::RXA::setOutputSamplerate(m_rxa, sampleRate);
|
||||
|
||||
m_audioFifo.setSize(sampleRate);
|
||||
m_audioSampleRate = sampleRate;
|
||||
m_audioBuffer.resize(sampleRate / 10);
|
||||
m_audioBufferFill = 0;
|
||||
|
||||
QList<ObjectPipe*> pipes;
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(m_channel, "reportdemod", pipes);
|
||||
|
||||
if (pipes.size() > 0)
|
||||
{
|
||||
for (const auto& pipe : pipes)
|
||||
{
|
||||
MessageQueue* messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
|
||||
if (messageQueue)
|
||||
{
|
||||
MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, sampleRate);
|
||||
messageQueue->push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
|
||||
{
|
||||
qDebug() << "WDSPRxSink::applySettings:"
|
||||
<< " m_demod: " << settings.m_demod
|
||||
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
|
||||
<< " m_profileIndex: " << settings.m_profileIndex
|
||||
<< " m_spanLog2: " << settings.m_profiles[settings.m_profileIndex].m_spanLog2
|
||||
<< " m_highCutoff: " << settings.m_profiles[settings.m_profileIndex].m_highCutoff
|
||||
<< " m_lowCutoff: " << settings.m_profiles[settings.m_profileIndex].m_lowCutoff
|
||||
<< " m_fftWindow: " << settings.m_profiles[settings.m_profileIndex].m_fftWindow << "]"
|
||||
<< " m_volume: " << settings.m_volume
|
||||
<< " m_audioBinaural: " << settings.m_audioBinaural
|
||||
<< " m_audioFlipChannels: " << settings.m_audioFlipChannels
|
||||
<< " m_dsb: " << settings.m_dsb
|
||||
<< " m_audioMute: " << settings.m_audioMute
|
||||
<< " m_agc: " << settings.m_agc
|
||||
<< " m_agcMode: " << settings.m_agcMode
|
||||
<< " m_agcGain: " << settings.m_agcGain
|
||||
<< " m_agcSlope: " << settings.m_agcSlope
|
||||
<< " m_agcHangThreshold: " << settings.m_agcHangThreshold
|
||||
<< " m_audioDeviceName: " << settings.m_audioDeviceName
|
||||
<< " m_anf: "<< settings.m_anf
|
||||
<< " m_dnr: " << settings.m_dnr
|
||||
<< " m_nrScheme: " << settings.m_nrScheme
|
||||
<< " m_nrPosition: "<< settings.m_nrPosition
|
||||
<< " m_nr2Gain: " << settings.m_nr2Gain
|
||||
<< " m_nr2NPE: " << settings.m_nr2NPE
|
||||
<< " m_nr2ArtifactReduction: " << settings.m_nr2ArtifactReduction
|
||||
<< " m_streamIndex: " << settings.m_streamIndex
|
||||
<< " m_useReverseAPI: " << settings.m_useReverseAPI
|
||||
<< " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
|
||||
<< " m_reverseAPIPort: " << settings.m_reverseAPIPort
|
||||
<< " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex
|
||||
<< " m_reverseAPIChannelIndex: " << settings.m_reverseAPIChannelIndex
|
||||
<< " force: " << force;
|
||||
|
||||
// Filter and mode
|
||||
|
||||
if((m_settings.m_profiles[m_settings.m_profileIndex].m_highCutoff != settings.m_profiles[settings.m_profileIndex].m_highCutoff) ||
|
||||
(m_settings.m_profiles[m_settings.m_profileIndex].m_lowCutoff != settings.m_profiles[settings.m_profileIndex].m_lowCutoff) ||
|
||||
(m_settings.m_profiles[m_settings.m_profileIndex].m_fftWindow != settings.m_profiles[settings.m_profileIndex].m_fftWindow) ||
|
||||
(m_settings.m_demod != settings.m_demod) ||
|
||||
(m_settings.m_dsb != settings.m_dsb) || force)
|
||||
{
|
||||
float band, low, high, fLow, fHigh;
|
||||
bool usb, dsb;
|
||||
|
||||
band = settings.m_profiles[settings.m_profileIndex].m_highCutoff;
|
||||
high = band;
|
||||
low = settings.m_profiles[settings.m_profileIndex].m_lowCutoff;
|
||||
|
||||
if (band < 0)
|
||||
{
|
||||
band = -band;
|
||||
m_spectrumProbe.setUSB(false);
|
||||
usb = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spectrumProbe.setUSB(true);
|
||||
usb = true;
|
||||
}
|
||||
|
||||
m_Bandwidth = band;
|
||||
|
||||
if (high < low)
|
||||
{
|
||||
if (settings.m_dsb)
|
||||
{
|
||||
fLow = high;
|
||||
fHigh = -high;
|
||||
m_spectrumProbe.setDSB(true);
|
||||
dsb = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fLow = high;
|
||||
fHigh = low;
|
||||
m_spectrumProbe.setDSB(false);
|
||||
dsb = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (settings.m_dsb)
|
||||
{
|
||||
fLow = -high;
|
||||
fHigh = high;
|
||||
m_spectrumProbe.setDSB(true);
|
||||
dsb = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fLow = low;
|
||||
fHigh = high;
|
||||
m_spectrumProbe.setDSB(false);
|
||||
dsb = false;
|
||||
}
|
||||
}
|
||||
|
||||
Real interpolatorBandwidth = (m_Bandwidth * 1.5f) > m_channelSampleRate ? m_channelSampleRate : (m_Bandwidth * 1.5f);
|
||||
m_interpolator.create(16, m_channelSampleRate, interpolatorBandwidth, 2.0f);
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorDistance = (Real) m_channelSampleRate / (Real) m_audioSampleRate;
|
||||
|
||||
WDSP::RXA::SetPassband(*m_rxa, fLow, fHigh);
|
||||
WDSP::NBP::NBPSetWindow(*m_rxa, m_settings.m_profiles[m_settings.m_profileIndex].m_fftWindow);
|
||||
|
||||
if (settings.m_demod == WDSPRxProfile::DemodSSB)
|
||||
{
|
||||
if (dsb)
|
||||
{
|
||||
WDSP::RXA::SetMode(*m_rxa, WDSP::RXA::RXA_DSB);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (usb) {
|
||||
WDSP::RXA::SetMode(*m_rxa, WDSP::RXA::RXA_USB);
|
||||
} else {
|
||||
WDSP::RXA::SetMode(*m_rxa, WDSP::RXA::RXA_LSB);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (settings.m_demod == WDSPRxProfile::DemodAM)
|
||||
{
|
||||
WDSP::RXA::SetMode(*m_rxa, WDSP::RXA::RXA_AM);
|
||||
}
|
||||
else if (settings.m_demod == WDSPRxProfile::DemodSAM)
|
||||
{
|
||||
WDSP::RXA::SetMode(*m_rxa, WDSP::RXA::RXA_SAM);
|
||||
}
|
||||
else if (settings.m_demod == WDSPRxProfile::DemodFMN)
|
||||
{
|
||||
WDSP::RXA::SetMode(*m_rxa, WDSP::RXA::RXA_FM);
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_profiles[settings.m_profileIndex].m_spanLog2 != settings.m_profiles[settings.m_profileIndex].m_spanLog2) || force) {
|
||||
m_spectrumProbe.setSpanLog2(settings.m_profiles[settings.m_profileIndex].m_spanLog2);
|
||||
}
|
||||
|
||||
// Noise Reduction
|
||||
|
||||
if ((m_settings.m_dnr != settings.m_dnr)
|
||||
|| (m_settings.m_nrScheme != settings.m_nrScheme) || force)
|
||||
{
|
||||
WDSP::ANR::SetANRRun(*m_rxa, 0);
|
||||
WDSP::EMNR::SetEMNRRun(*m_rxa, 0);
|
||||
|
||||
if (settings.m_dnr)
|
||||
{
|
||||
switch (settings.m_nrScheme)
|
||||
{
|
||||
case WDSPRxProfile::NRSchemeNR:
|
||||
WDSP::ANR::SetANRRun(*m_rxa, 1);
|
||||
break;
|
||||
case WDSPRxProfile::NRSchemeNR2:
|
||||
WDSP::EMNR::SetEMNRRun(*m_rxa, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_nrPosition != settings.m_nrPosition) || force)
|
||||
{
|
||||
switch (settings.m_nrPosition)
|
||||
{
|
||||
case WDSPRxProfile::NRPositionPreAGC:
|
||||
WDSP::ANR::SetANRPosition(*m_rxa, 0);
|
||||
WDSP::EMNR::SetEMNRPosition(*m_rxa, 0);
|
||||
break;
|
||||
case WDSPRxProfile::NRPositionPostAGC:
|
||||
WDSP::ANR::SetANRPosition(*m_rxa, 1);
|
||||
WDSP::EMNR::SetEMNRPosition(*m_rxa, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_nr2Gain != settings.m_nr2Gain) || force)
|
||||
{
|
||||
switch (settings.m_nr2Gain)
|
||||
{
|
||||
case WDSPRxProfile::NR2GainLinear:
|
||||
WDSP::EMNR::SetEMNRgainMethod(*m_rxa, 0);
|
||||
break;
|
||||
case WDSPRxProfile::NR2GainLog:
|
||||
WDSP::EMNR::SetEMNRgainMethod(*m_rxa, 1);
|
||||
break;
|
||||
case WDSPRxProfile::NR2GainGamma:
|
||||
WDSP::EMNR::SetEMNRgainMethod(*m_rxa, 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_nr2NPE != settings.m_nr2NPE) || force)
|
||||
{
|
||||
switch (settings.m_nr2NPE)
|
||||
{
|
||||
case WDSPRxProfile::NR2NPEOSMS:
|
||||
WDSP::EMNR::SetEMNRnpeMethod(*m_rxa, 0);
|
||||
break;
|
||||
case WDSPRxProfile::NR2NPEMMSE:
|
||||
WDSP::EMNR::SetEMNRnpeMethod(*m_rxa, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_nr2ArtifactReduction != settings.m_nr2ArtifactReduction) || force) {
|
||||
WDSP::EMNR::SetEMNRaeRun(*m_rxa, settings.m_nr2ArtifactReduction ? 1 : 0);
|
||||
}
|
||||
|
||||
if ((m_settings.m_anf != settings.m_anf) || force) {
|
||||
WDSP::ANF::SetANFRun(*m_rxa, settings.m_anf ? 1 : 0);
|
||||
}
|
||||
|
||||
// CW Peaking
|
||||
|
||||
if ((m_settings.m_cwPeaking != settings.m_cwPeaking) || force) {
|
||||
WDSP::SPEAK::SetSPCWRun(*m_rxa, settings.m_cwPeaking ? 1 : 0);
|
||||
}
|
||||
|
||||
if ((m_settings.m_cwPeakFrequency != settings.m_cwPeakFrequency) || force) {
|
||||
WDSP::SPEAK::SetSPCWFreq(*m_rxa, settings.m_cwPeakFrequency);
|
||||
}
|
||||
|
||||
if ((m_settings.m_cwBandwidth != settings.m_cwBandwidth) || force) {
|
||||
WDSP::SPEAK::SetSPCWBandwidth(*m_rxa, settings.m_cwBandwidth);
|
||||
}
|
||||
|
||||
if ((m_settings.m_cwGain != settings.m_cwGain) || force) {
|
||||
WDSP::SPEAK::SetSPCWGain(*m_rxa, settings.m_cwGain);
|
||||
}
|
||||
|
||||
// Noise Blanker
|
||||
|
||||
if ((m_settings.m_dnb != settings.m_dnb)
|
||||
|| (m_settings.m_nbScheme != settings.m_nbScheme) || force)
|
||||
{
|
||||
WDSP::ANB::SetANBRun(*m_rxa, 0);
|
||||
WDSP::NOB::SetNOBRun(*m_rxa, 0);
|
||||
|
||||
if (settings.m_dnb)
|
||||
{
|
||||
switch(settings.m_nbScheme)
|
||||
{
|
||||
case WDSPRxProfile::NBSchemeNB:
|
||||
WDSP::ANB::SetANBRun(*m_rxa, 1);
|
||||
break;
|
||||
case WDSPRxProfile::NBSchemeNB2:
|
||||
WDSP::NOB::SetNOBRun(*m_rxa, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_nbSlewTime != settings.m_nbSlewTime) || force)
|
||||
{
|
||||
WDSP::ANB::SetANBTau(*m_rxa, settings.m_nbSlewTime * 0.001);
|
||||
WDSP::NOB::SetNOBTau(*m_rxa, settings.m_nbSlewTime * 0.001);
|
||||
}
|
||||
|
||||
if ((m_settings.m_nbLeadTime != settings.m_nbLeadTime) || force)
|
||||
{
|
||||
WDSP::ANB::SetANBAdvtime(*m_rxa, settings.m_nbLeadTime * 0.001);
|
||||
WDSP::NOB::SetNOBAdvtime(*m_rxa, settings.m_nbLeadTime * 0.001);
|
||||
}
|
||||
|
||||
if ((m_settings.m_nbLagTime != settings.m_nbLagTime) || force)
|
||||
{
|
||||
WDSP::ANB::SetANBHangtime(*m_rxa, settings.m_nbLagTime * 0.001);
|
||||
WDSP::NOB::SetNOBHangtime(*m_rxa, settings.m_nbLagTime * 0.001);
|
||||
}
|
||||
|
||||
if ((m_settings.m_nbThreshold != settings.m_nbThreshold) || force)
|
||||
{
|
||||
WDSP::ANB::SetANBThreshold(*m_rxa, settings.m_nbThreshold);
|
||||
WDSP::NOB::SetNOBThreshold(*m_rxa, settings.m_nbThreshold);
|
||||
}
|
||||
|
||||
if ((m_settings.m_nbAvgTime != settings.m_nbAvgTime) || force)
|
||||
{
|
||||
WDSP::ANB::SetANBBacktau(*m_rxa, settings.m_nbAvgTime * 0.001);
|
||||
WDSP::NOB::SetNOBBacktau(*m_rxa, settings.m_nbAvgTime * 0.001);
|
||||
}
|
||||
|
||||
// AM option
|
||||
|
||||
if ((m_settings.m_amFadeLevel != settings.m_amFadeLevel) || force) {
|
||||
WDSP::AMD::SetAMDFadeLevel(*m_rxa, settings.m_amFadeLevel);
|
||||
}
|
||||
|
||||
// FM options
|
||||
|
||||
if ((m_settings.m_fmDeviation != settings.m_fmDeviation) || force) {
|
||||
WDSP::FMD::SetFMDeviation(*m_rxa, settings.m_fmDeviation);
|
||||
}
|
||||
|
||||
if ((m_settings.m_fmAFLow != settings.m_fmAFLow)
|
||||
|| (m_settings.m_fmAFHigh != settings.m_fmAFHigh) || force)
|
||||
{
|
||||
WDSP::FMD::SetFMAFFilter(*m_rxa, settings.m_fmAFLow, settings.m_fmAFHigh);
|
||||
}
|
||||
|
||||
if ((m_settings.m_fmAFLimiter != settings.m_fmAFLimiter) || force) {
|
||||
WDSP::FMD::SetFMLimRun(*m_rxa, settings.m_fmAFLimiter ? 1 : 0);
|
||||
}
|
||||
|
||||
if ((m_settings.m_fmAFLimiterGain != settings.m_fmAFLimiterGain) || force) {
|
||||
WDSP::FMD::SetFMLimGain(*m_rxa, settings.m_fmAFLimiterGain);
|
||||
}
|
||||
|
||||
if ((m_settings.m_fmCTCSSNotch != settings.m_fmCTCSSNotch) || force) {
|
||||
WDSP::FMD::SetCTCSSRun(*m_rxa, settings.m_fmCTCSSNotch ? 1 : 0);
|
||||
}
|
||||
|
||||
if ((m_settings.m_fmCTCSSNotchFrequency != settings.m_fmCTCSSNotchFrequency) || force) {
|
||||
WDSP::FMD::SetCTCSSFreq(*m_rxa, settings.m_fmCTCSSNotchFrequency);
|
||||
}
|
||||
|
||||
// Squelch
|
||||
|
||||
if ((m_settings.m_squelch != settings.m_squelch)
|
||||
|| (m_settings.m_squelchThreshold != settings.m_squelchThreshold)
|
||||
|| (m_settings.m_squelchMode != settings.m_squelchMode) || force)
|
||||
{
|
||||
WDSP::SSQL::SetSSQLRun(*m_rxa, 0);
|
||||
WDSP::AMSQ::SetAMSQRun(*m_rxa, 0);
|
||||
WDSP::FMSQ::SetFMSQRun(*m_rxa, 0);
|
||||
|
||||
if (settings.m_squelch)
|
||||
{
|
||||
switch(settings.m_squelchMode)
|
||||
{
|
||||
case WDSPRxProfile::SquelchModeVoice:
|
||||
{
|
||||
WDSP::SSQL::SetSSQLRun(*m_rxa, 1);
|
||||
double threshold = 0.0075 * settings.m_squelchThreshold;
|
||||
WDSP::SSQL::SetSSQLThreshold(*m_rxa, threshold);
|
||||
}
|
||||
break;
|
||||
case WDSPRxProfile::SquelchModeAM:
|
||||
{
|
||||
WDSP::AMSQ::SetAMSQRun(*m_rxa, 1);
|
||||
double threshold = ((settings.m_squelchThreshold / 100.0) * 160.0) - 160.0;
|
||||
WDSP::AMSQ::SetAMSQThreshold(*m_rxa, threshold);
|
||||
}
|
||||
break;
|
||||
case WDSPRxProfile::SquelchModeFM:
|
||||
{
|
||||
WDSP::FMSQ::SetFMSQRun(*m_rxa, 1);
|
||||
double threshold = pow(10.0, -2.0 * ((double) settings.m_squelchThreshold) / 100.0);
|
||||
qDebug("WDSPRxSink::applySettings: FM squelch %lf", threshold);
|
||||
WDSP::FMSQ::SetFMSQThreshold(*m_rxa, threshold);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_ssqlTauMute != settings.m_ssqlTauMute) || force) {
|
||||
WDSP::SSQL::SetSSQLTauMute(*m_rxa, settings.m_ssqlTauMute);
|
||||
}
|
||||
|
||||
if ((m_settings.m_ssqlTauUnmute != settings.m_ssqlTauUnmute) || force) {
|
||||
WDSP::SSQL::SetSSQLTauUnMute(*m_rxa, settings.m_ssqlTauUnmute);
|
||||
}
|
||||
|
||||
if ((m_settings.m_amsqMaxTail != settings.m_amsqMaxTail) || force) {
|
||||
WDSP::AMSQ::SetAMSQMaxTail(*m_rxa, settings.m_amsqMaxTail);
|
||||
}
|
||||
|
||||
// Audio panel
|
||||
|
||||
if ((m_settings.m_volume != settings.m_volume) || force) {
|
||||
WDSP::PANEL::SetPanelGain1(*m_rxa, settings.m_volume);
|
||||
}
|
||||
|
||||
if ((m_settings.m_audioBinaural != settings.m_audioBinaural) || force) {
|
||||
WDSP::PANEL::SetPanelBinaural(*m_rxa, settings.m_audioBinaural ? 1 : 0);
|
||||
}
|
||||
|
||||
if ((m_settings.m_audioFlipChannels != settings.m_audioFlipChannels) || force) {
|
||||
WDSP::PANEL::SetPanelCopy(*m_rxa, settings.m_audioFlipChannels ? 3 : 0);
|
||||
}
|
||||
|
||||
// AGC
|
||||
|
||||
if ((m_settings.m_agc != settings.m_agc)
|
||||
|| (m_settings.m_agcMode != settings.m_agcMode)
|
||||
|| (m_settings.m_agcSlope != settings.m_agcSlope)
|
||||
|| (m_settings.m_agcHangThreshold != settings.m_agcHangThreshold)
|
||||
|| (m_settings.m_agcGain != settings.m_agcGain) || force)
|
||||
{
|
||||
WDSP::WCPAGC::SetAGCSlope(*m_rxa, settings.m_agcSlope); // SetRXAAGCSlope(id, rx->agc_slope);
|
||||
WDSP::WCPAGC::SetAGCTop(*m_rxa, (float) settings.m_agcGain); // SetRXAAGCTop(id, rx->agc_gain);
|
||||
|
||||
if (settings.m_agc)
|
||||
{
|
||||
switch (settings.m_agcMode)
|
||||
{
|
||||
case WDSPRxProfile::WDSPRxAGCMode::AGCLong:
|
||||
WDSP::WCPAGC::SetAGCMode(*m_rxa, 1);
|
||||
WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2);
|
||||
WDSP::WCPAGC::SetAGCHang(*m_rxa, 2000); // SetRXAAGCHang(id, 2000);
|
||||
WDSP::WCPAGC::SetAGCDecay(*m_rxa, 2000); // SetRXAAGCDecay(id, 2000);
|
||||
WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, (int)rx->agc_hang_threshold);
|
||||
break;
|
||||
case WDSPRxProfile::WDSPRxAGCMode::AGCSlow:
|
||||
WDSP::WCPAGC::SetAGCMode(*m_rxa, 2);
|
||||
WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2);
|
||||
WDSP::WCPAGC::SetAGCHang(*m_rxa, 1000); // SetRXAAGCHang(id, 1000);
|
||||
WDSP::WCPAGC::SetAGCDecay(*m_rxa, 500); // SetRXAAGCDecay(id, 500);
|
||||
WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, (int)rx->agc_hang_threshold);
|
||||
break;
|
||||
case WDSPRxProfile::WDSPRxAGCMode::AGCMedium:
|
||||
WDSP::WCPAGC::SetAGCMode(*m_rxa, 3);
|
||||
WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2);
|
||||
WDSP::WCPAGC::SetAGCHang(*m_rxa, 0); // SetRXAAGCHang(id, 0);
|
||||
WDSP::WCPAGC::SetAGCDecay(*m_rxa, 250); // SetRXAAGCDecay(id, 250);
|
||||
WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, 100);
|
||||
break;
|
||||
case WDSPRxProfile::WDSPRxAGCMode::AGCFast:
|
||||
WDSP::WCPAGC::SetAGCMode(*m_rxa, 4);
|
||||
WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2);
|
||||
WDSP::WCPAGC::SetAGCHang(*m_rxa, 0); // SetRXAAGCHang(id, 0);
|
||||
WDSP::WCPAGC::SetAGCDecay(*m_rxa, 50); // SetRXAAGCDecay(id, 50);
|
||||
WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WDSP::WCPAGC::SetAGCMode(*m_rxa, 0);
|
||||
}
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
}
|
@ -36,7 +36,7 @@ public:
|
||||
};
|
||||
|
||||
explicit WDSPRxSquelchDialog(QWidget* parent = nullptr);
|
||||
~WDSPRxSquelchDialog();
|
||||
~WDSPRxSquelchDialog() override;
|
||||
|
||||
void setMode(WDSPRxProfile::WDSPRxSquelchMode mode);
|
||||
void setSSQLTauMute(double value);
|
||||
|
@ -17330,7 +17330,7 @@ margin-bottom: 20px;
|
||||
},
|
||||
"eqF" : {
|
||||
"type" : "array",
|
||||
"description" : "Frequency points (Hz). Positon 0 is preamp then 10 frequency points",
|
||||
"description" : "Frequency points (Hz). Position 0 is preamp then 10 frequency points",
|
||||
"items" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
@ -17338,7 +17338,7 @@ margin-bottom: 20px;
|
||||
},
|
||||
"eqG" : {
|
||||
"type" : "array",
|
||||
"description" : "Frequency points gains (dB). Positon 0 is for preamp gain then for the 10 frequency points",
|
||||
"description" : "Frequency points gains (dB). Position 0 is for preamp gain then for the 10 frequency points",
|
||||
"items" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
@ -59441,7 +59441,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2024-07-13T13:44:10.416+02:00
|
||||
Generated 2024-07-16T23:20:27.082+02:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -228,13 +228,13 @@ WDSPRxSettings:
|
||||
* 0 - Off
|
||||
* 1 - On
|
||||
eqF:
|
||||
description: Frequency points (Hz). Positon 0 is preamp then 10 frequency points
|
||||
description: Frequency points (Hz). Position 0 is preamp then 10 frequency points
|
||||
type: array
|
||||
items:
|
||||
type: number
|
||||
format: float
|
||||
eqG:
|
||||
description: Frequency points gains (dB). Positon 0 is for preamp gain then for the 10 frequency points
|
||||
description: Frequency points gains (dB). Position 0 is for preamp gain then for the 10 frequency points
|
||||
type: array
|
||||
items:
|
||||
type: number
|
||||
|
@ -228,13 +228,13 @@ WDSPRxSettings:
|
||||
* 0 - Off
|
||||
* 1 - On
|
||||
eqF:
|
||||
description: Frequency points (Hz). Positon 0 is preamp then 10 frequency points
|
||||
description: Frequency points (Hz). Position 0 is preamp then 10 frequency points
|
||||
type: array
|
||||
items:
|
||||
type: number
|
||||
format: float
|
||||
eqG:
|
||||
description: Frequency points gains (dB). Positon 0 is for preamp gain then for the 10 frequency points
|
||||
description: Frequency points gains (dB). Position 0 is for preamp gain then for the 10 frequency points
|
||||
type: array
|
||||
items:
|
||||
type: number
|
||||
|
@ -17330,7 +17330,7 @@ margin-bottom: 20px;
|
||||
},
|
||||
"eqF" : {
|
||||
"type" : "array",
|
||||
"description" : "Frequency points (Hz). Positon 0 is preamp then 10 frequency points",
|
||||
"description" : "Frequency points (Hz). Position 0 is preamp then 10 frequency points",
|
||||
"items" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
@ -17338,7 +17338,7 @@ margin-bottom: 20px;
|
||||
},
|
||||
"eqG" : {
|
||||
"type" : "array",
|
||||
"description" : "Frequency points gains (dB). Positon 0 is for preamp gain then for the 10 frequency points",
|
||||
"description" : "Frequency points gains (dB). Position 0 is for preamp gain then for the 10 frequency points",
|
||||
"items" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
@ -59441,7 +59441,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2024-07-13T13:44:10.416+02:00
|
||||
Generated 2024-07-16T23:20:27.082+02:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -42,6 +42,7 @@ set(wdsp_SOURCES
|
||||
osctrl.cpp
|
||||
patchpanel.cpp
|
||||
resample.cpp
|
||||
resamplef.cpp
|
||||
rmatch.cpp
|
||||
RXA.cpp
|
||||
sender.cpp
|
||||
@ -98,6 +99,7 @@ set(wdsp_HEADERS
|
||||
osctrl.hpp
|
||||
patchpanel.hpp
|
||||
resample.hpp
|
||||
resamplef.hpp
|
||||
rmatch.hpp
|
||||
RXA.hpp
|
||||
sender.hpp
|
||||
@ -132,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()
|
||||
|
12
wdsp/RXA.cpp
12
wdsp/RXA.cpp
@ -506,9 +506,9 @@ RXA* RXA::create_rxa (
|
||||
// Dolly filter (multiple peak filter) - default is 2 for RTTY
|
||||
{
|
||||
int def_enable[2] = {1, 1};
|
||||
float def_freq[2] = {2125.0, 2295.0};
|
||||
float def_bw[2] = {75.0, 75.0};
|
||||
float def_gain[2] = {1.0, 1.0};
|
||||
double def_freq[2] = {2125.0, 2295.0};
|
||||
double def_bw[2] = {75.0, 75.0};
|
||||
double def_gain[2] = {1.0, 1.0};
|
||||
rxa->mpeak.p = MPEAK::create_mpeak (
|
||||
0, // run
|
||||
rxa->dsp_size, // size
|
||||
@ -611,9 +611,9 @@ void RXA::destroy_rxa (RXA *rxa)
|
||||
|
||||
void RXA::flush_rxa (RXA *rxa)
|
||||
{
|
||||
memset (rxa->inbuff, 0, 1 * rxa->dsp_insize * sizeof (wcomplex));
|
||||
memset (rxa->outbuff, 0, 1 * rxa->dsp_outsize * sizeof (wcomplex));
|
||||
memset (rxa->midbuff, 0, 2 * rxa->dsp_size * sizeof (wcomplex));
|
||||
std::fill(rxa->inbuff, rxa->inbuff + 1 * rxa->dsp_insize * 2, 0);
|
||||
std::fill(rxa->outbuff, rxa->outbuff + 1 * rxa->dsp_outsize * 2, 0);
|
||||
std::fill(rxa->midbuff, rxa->midbuff + 2 * rxa->dsp_size * 2, 0);
|
||||
SHIFT::flush_shift (rxa->shift.p);
|
||||
RESAMPLE::flush_resample (rxa->rsmpin.p);
|
||||
GEN::flush_gen (rxa->gen0.p);
|
||||
|
@ -558,9 +558,9 @@ void TXA::destroy_txa (TXA *txa)
|
||||
|
||||
void TXA::flush_txa (TXA* txa)
|
||||
{
|
||||
memset (txa->inbuff, 0, 1 * txa->dsp_insize * sizeof (wcomplex));
|
||||
memset (txa->outbuff, 0, 1 * txa->dsp_outsize * sizeof (wcomplex));
|
||||
memset (txa->midbuff, 0, 2 * txa->dsp_size * sizeof (wcomplex));
|
||||
std::fill(txa->inbuff, txa->inbuff + 1 * txa->dsp_insize * 2, 0);
|
||||
std::fill(txa->outbuff, txa->outbuff + 1 * txa->dsp_outsize * 2, 0);
|
||||
std::fill(txa->midbuff, txa->midbuff + 2 * txa->dsp_size * 2, 0);
|
||||
RESAMPLE::flush_resample (txa->rsmpin.p);
|
||||
GEN::flush_gen (txa->gen0.p);
|
||||
PANEL::flush_panel (txa->panel.p);
|
||||
|
36
wdsp/amd.cpp
36
wdsp/amd.cpp
@ -134,6 +134,7 @@ void AMD::xamd (AMD *a)
|
||||
double ai, bi, aq, bq;
|
||||
double ai_ps, bi_ps, aq_ps, bq_ps;
|
||||
int j, k;
|
||||
|
||||
if (a->run)
|
||||
{
|
||||
switch (a->mode)
|
||||
@ -143,16 +144,21 @@ void AMD::xamd (AMD *a)
|
||||
{
|
||||
for (i = 0; i < a->buff_size; i++)
|
||||
{
|
||||
audio = sqrt(a->in_buff[2 * i + 0] * a->in_buff[2 * i + 0] + a->in_buff[2 * i + 1] * a->in_buff[2 * i + 1]);
|
||||
double xr = a->in_buff[2 * i + 0];
|
||||
double xi = a->in_buff[2 * i + 1];
|
||||
audio = sqrt(xr*xr + xi*xi);
|
||||
|
||||
if (a->levelfade)
|
||||
{
|
||||
a->dc = a->mtauR * a->dc + a->onem_mtauR * audio;
|
||||
a->dc_insert = a->mtauI * a->dc_insert + a->onem_mtauI * audio;
|
||||
audio += a->dc_insert - a->dc;
|
||||
}
|
||||
|
||||
a->out_buff[2 * i + 0] = audio;
|
||||
a->out_buff[2 * i + 1] = audio;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -185,6 +191,7 @@ void AMD::xamd (AMD *a)
|
||||
a->c[k + 3] = a->c0[j] * (a->c[k] - a->c[k + 5]) + a->c[k + 2];
|
||||
a->d[k + 3] = a->c1[j] * (a->d[k] - a->d[k + 5]) + a->d[k + 2];
|
||||
}
|
||||
|
||||
ai_ps = a->a[OUT_IDX];
|
||||
bi_ps = a->b[OUT_IDX];
|
||||
bq_ps = a->c[OUT_IDX];
|
||||
@ -227,27 +234,40 @@ void AMD::xamd (AMD *a)
|
||||
a->dc_insert = a->mtauI * a->dc_insert + a->onem_mtauI * corr[0];
|
||||
audio += a->dc_insert - a->dc;
|
||||
}
|
||||
|
||||
a->out_buff[2 * i + 0] = audio;
|
||||
a->out_buff[2 * i + 1] = audio;
|
||||
|
||||
if ((corr[0] == 0.0) && (corr[1] == 0.0)) corr[0] = 1.0;
|
||||
if ((corr[0] == 0.0) && (corr[1] == 0.0))
|
||||
corr[0] = 1.0;
|
||||
|
||||
det = atan2(corr[1], corr[0]);
|
||||
del_out = a->fil_out;
|
||||
a->omega += a->g2 * det;
|
||||
if (a->omega < a->omega_min) a->omega = a->omega_min;
|
||||
if (a->omega > a->omega_max) a->omega = a->omega_max;
|
||||
|
||||
if (a->omega < a->omega_min)
|
||||
a->omega = a->omega_min;
|
||||
|
||||
if (a->omega > a->omega_max)
|
||||
a->omega = a->omega_max;
|
||||
|
||||
a->fil_out = a->g1 * det + a->omega;
|
||||
a->phs += del_out;
|
||||
while (a->phs >= 2 * M_PI) a->phs -= 2 * M_PI;
|
||||
while (a->phs < 0.0) a->phs += 2 * M_PI;
|
||||
|
||||
while (a->phs >= 2 * M_PI)
|
||||
a->phs -= 2 * M_PI;
|
||||
|
||||
while (a->phs < 0.0)
|
||||
a->phs += 2 * M_PI;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (a->in_buff != a->out_buff)
|
||||
{
|
||||
memcpy (a->out_buff, a->in_buff, a->buff_size * sizeof(wcomplex));
|
||||
std::copy (a->in_buff, a->in_buff + a->buff_size * 2, a->out_buff);
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,6 +297,7 @@ void AMD::setSize_amd (AMD *a, int size)
|
||||
void AMD::SetAMDRun(RXA& rxa, int run)
|
||||
{
|
||||
AMD *a = rxa.amd.p;
|
||||
|
||||
if (a->run != run)
|
||||
{
|
||||
RXA::bp1Check (
|
||||
@ -287,6 +308,7 @@ void AMD::SetAMDRun(RXA& rxa, int run)
|
||||
rxa.anf.p->run,
|
||||
rxa.anr.p->run
|
||||
);
|
||||
|
||||
a->run = run;
|
||||
RXA::bp1Set (rxa);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ void AMMOD::xammod(AMMOD *a)
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void AMMOD::setBuffers_ammod(AMMOD *a, float* in, float* out)
|
||||
|
@ -38,13 +38,16 @@ void AMSQ::compute_slews(AMSQ *a)
|
||||
double delta, theta;
|
||||
delta = PI / (double)a->ntup;
|
||||
theta = 0.0;
|
||||
|
||||
for (i = 0; i <= a->ntup; i++)
|
||||
{
|
||||
a->cup[i] = a->muted_gain + (1.0 - a->muted_gain) * 0.5 * (1.0 - cos (theta));
|
||||
theta += delta;
|
||||
}
|
||||
|
||||
delta = PI / (double)a->ntdown;
|
||||
theta = 0.0;
|
||||
|
||||
for (i = 0; i <= a->ntdown; i++)
|
||||
{
|
||||
a->cdown[i] = a->muted_gain + (1.0 - a->muted_gain) * 0.5 * (1.0 + cos (theta));
|
||||
@ -55,15 +58,15 @@ void AMSQ::compute_slews(AMSQ *a)
|
||||
void AMSQ::calc_amsq(AMSQ *a)
|
||||
{
|
||||
// signal averaging
|
||||
a->trigsig = new float[a->size * 2]; // (float *)malloc0(a->size * sizeof(wcomplex));
|
||||
a->trigsig = new float[a->size * 2];
|
||||
a->avm = exp(-1.0 / (a->rate * a->avtau));
|
||||
a->onem_avm = 1.0 - a->avm;
|
||||
a->avsig = 0.0;
|
||||
// level change
|
||||
a->ntup = (int)(a->tup * a->rate);
|
||||
a->ntdown = (int)(a->tdown * a->rate);
|
||||
a->cup = new float[(a->ntup + 1) * 2]; // (float *)malloc0((a->ntup + 1) * sizeof(float));
|
||||
a->cdown = new float[(a->ntdown + 1) * 2]; // (float *)malloc0((a->ntdown + 1) * sizeof(float));
|
||||
a->cup = new double[(a->ntup + 1) * 2]; // (float *)malloc0((a->ntup + 1) * sizeof(float));
|
||||
a->cdown = new double[(a->ntdown + 1) * 2]; // (float *)malloc0((a->ntdown + 1) * sizeof(float));
|
||||
compute_slews(a);
|
||||
// control
|
||||
a->state = 0;
|
||||
@ -120,7 +123,7 @@ void AMSQ::destroy_amsq (AMSQ *a)
|
||||
|
||||
void AMSQ::flush_amsq (AMSQ*a)
|
||||
{
|
||||
memset (a->trigsig, 0, a->size * sizeof (wcomplex));
|
||||
std::fill(a->trigsig, a->trigsig + a->size * 2, 0);
|
||||
a->avsig = 0.0;
|
||||
a->state = 0;
|
||||
}
|
||||
@ -140,10 +143,12 @@ void AMSQ::xamsq (AMSQ *a)
|
||||
{
|
||||
int i;
|
||||
double sig, siglimit;
|
||||
|
||||
for (i = 0; i < a->size; i++)
|
||||
{
|
||||
sig = sqrt (a->trigsig[2 * i + 0] * a->trigsig[2 * i + 0] + a->trigsig[2 * i + 1] * a->trigsig[2 * i + 1]);
|
||||
a->avsig = a->avm * a->avsig + a->onem_avm * sig;
|
||||
|
||||
switch (a->state)
|
||||
{
|
||||
case MUTED:
|
||||
@ -152,52 +157,73 @@ void AMSQ::xamsq (AMSQ *a)
|
||||
a->state = INCREASE;
|
||||
a->count = a->ntup;
|
||||
}
|
||||
|
||||
a->out[2 * i + 0] = a->muted_gain * a->in[2 * i + 0];
|
||||
a->out[2 * i + 1] = a->muted_gain * a->in[2 * i + 1];
|
||||
|
||||
break;
|
||||
|
||||
case INCREASE:
|
||||
a->out[2 * i + 0] = a->in[2 * i + 0] * a->cup[a->ntup - a->count];
|
||||
a->out[2 * i + 1] = a->in[2 * i + 1] * a->cup[a->ntup - a->count];
|
||||
|
||||
if (a->count-- == 0)
|
||||
a->state = UNMUTED;
|
||||
|
||||
break;
|
||||
|
||||
case UNMUTED:
|
||||
if (a->avsig < a->tail_thresh)
|
||||
{
|
||||
a->state = TAIL;
|
||||
if ((siglimit = a->avsig) > 1.0) siglimit = 1.0;
|
||||
|
||||
if ((siglimit = a->avsig) > 1.0)
|
||||
siglimit = 1.0;
|
||||
|
||||
a->count = (int)((a->min_tail + (a->max_tail - a->min_tail) * (1.0 - siglimit)) * a->rate);
|
||||
}
|
||||
|
||||
a->out[2 * i + 0] = a->in[2 * i + 0];
|
||||
a->out[2 * i + 1] = a->in[2 * i + 1];
|
||||
|
||||
break;
|
||||
|
||||
case TAIL:
|
||||
a->out[2 * i + 0] = a->in[2 * i + 0];
|
||||
a->out[2 * i + 1] = a->in[2 * i + 1];
|
||||
|
||||
if (a->avsig > a->unmute_thresh)
|
||||
{
|
||||
a->state = UNMUTED;
|
||||
}
|
||||
else if (a->count-- == 0)
|
||||
{
|
||||
a->state = DECREASE;
|
||||
a->count = a->ntdown;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DECREASE:
|
||||
a->out[2 * i + 0] = a->in[2 * i + 0] * a->cdown[a->ntdown - a->count];
|
||||
a->out[2 * i + 1] = a->in[2 * i + 1] * a->cdown[a->ntdown - a->count];
|
||||
|
||||
if (a->count-- == 0)
|
||||
a->state = MUTED;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void AMSQ::xamsqcap (AMSQ *a)
|
||||
{
|
||||
memcpy (a->trigsig, a->trigger, a->size * sizeof (wcomplex));
|
||||
std::copy(a->trigger, a->trigger + a->size * 2, a->trigsig);
|
||||
}
|
||||
|
||||
void AMSQ::setBuffers_amsq (AMSQ *a, float* in, float* out, float* trigger)
|
||||
@ -243,7 +269,10 @@ void AMSQ::SetAMSQMaxTail (RXA& rxa, double tail)
|
||||
{
|
||||
AMSQ *a;
|
||||
a = rxa.amsq.p;
|
||||
if (tail < a->min_tail) tail = a->min_tail;
|
||||
|
||||
if (tail < a->min_tail)
|
||||
tail = a->min_tail;
|
||||
|
||||
a->max_tail = tail;
|
||||
}
|
||||
|
||||
|
@ -54,8 +54,8 @@ public:
|
||||
double tdown;
|
||||
int ntup;
|
||||
int ntdown;
|
||||
float* cup;
|
||||
float* cdown;
|
||||
double* cup;
|
||||
double* cdown;
|
||||
double tail_thresh;
|
||||
double unmute_thresh;
|
||||
double min_tail;
|
||||
|
50
wdsp/anb.cpp
50
wdsp/anb.cpp
@ -39,7 +39,10 @@ void ANB::initBlanker(ANB *a)
|
||||
{
|
||||
int i;
|
||||
a->trans_count = (int)(a->tau * a->samplerate);
|
||||
if (a->trans_count < 2) a->trans_count = 2;
|
||||
|
||||
if (a->trans_count < 2)
|
||||
a->trans_count = 2;
|
||||
|
||||
a->hang_count = (int)(a->hangtime * a->samplerate);
|
||||
a->adv_count = (int)(a->advtime * a->samplerate);
|
||||
a->count = 0;
|
||||
@ -51,9 +54,11 @@ void ANB::initBlanker(ANB *a)
|
||||
a->power = 1.0;
|
||||
a->backmult = exp(-1.0 / (a->samplerate * a->backtau));
|
||||
a->ombackmult = 1.0 - a->backmult;
|
||||
|
||||
for (i = 0; i <= a->trans_count; i++)
|
||||
a->wave[i] = 0.5 * cos(i * a->coef);
|
||||
memset(a->dline, 0, a->dline_size * sizeof(wcomplex));
|
||||
|
||||
std::fill(a->dline, a->dline + a->dline_size * 2, 0);
|
||||
}
|
||||
|
||||
ANB* ANB::create_anb (
|
||||
@ -81,7 +86,7 @@ ANB* ANB::create_anb (
|
||||
a->advtime = advtime;
|
||||
a->backtau = backtau;
|
||||
a->threshold = threshold;
|
||||
a->wave = new float[((int)(MAX_SAMPLERATE * MAX_TAU) + 1)];
|
||||
a->wave = new double[((int)(MAX_SAMPLERATE * MAX_TAU) + 1)];
|
||||
a->dline_size = (int)((MAX_TAU + MAX_ADVTIME) * MAX_SAMPLERATE) + 1;
|
||||
a->dline = new float[a->dline_size * 2];
|
||||
initBlanker(a);
|
||||
@ -107,14 +112,18 @@ void ANB::xanb (ANB *a)
|
||||
double scale;
|
||||
double mag;
|
||||
int i;
|
||||
|
||||
if (a->run)
|
||||
{
|
||||
for (i = 0; i < a->buffsize; i++)
|
||||
{
|
||||
mag = sqrt(a->in[2 * i + 0] * a->in[2 * i + 0] + a->in[2 * i + 1] * a->in[2 * i + 1]);
|
||||
double xr = a->in[2 * i + 0];
|
||||
double xi = a->in[2 * i + 1];
|
||||
mag = sqrt(xr*xr + xi*xi);
|
||||
a->avg = a->backmult * a->avg + a->ombackmult * mag;
|
||||
a->dline[2 * a->in_idx + 0] = a->in[2 * i + 0];
|
||||
a->dline[2 * a->in_idx + 1] = a->in[2 * i + 1];
|
||||
|
||||
if (mag > (a->avg * a->threshold))
|
||||
a->count = a->trans_count + a->adv_count;
|
||||
|
||||
@ -123,45 +132,59 @@ void ANB::xanb (ANB *a)
|
||||
case 0:
|
||||
a->out[2 * i + 0] = a->dline[2 * a->out_idx + 0];
|
||||
a->out[2 * i + 1] = a->dline[2 * a->out_idx + 1];
|
||||
|
||||
if (a->count > 0)
|
||||
{
|
||||
a->state = 1;
|
||||
a->dtime = 0;
|
||||
a->power = 1.0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
scale = a->power * (0.5 + a->wave[a->dtime]);
|
||||
a->out[2 * i + 0] = a->dline[2 * a->out_idx + 0] * scale;
|
||||
a->out[2 * i + 1] = a->dline[2 * a->out_idx + 1] * scale;
|
||||
|
||||
if (++a->dtime > a->trans_count)
|
||||
{
|
||||
a->state = 2;
|
||||
a->atime = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
a->out[2 * i + 0] = 0.0;
|
||||
a->out[2 * i + 1] = 0.0;
|
||||
|
||||
if (++a->atime > a->adv_count)
|
||||
a->state = 3;
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (a->count > 0)
|
||||
a->htime = -a->count;
|
||||
|
||||
a->out[2 * i + 0] = 0.0;
|
||||
a->out[2 * i + 1] = 0.0;
|
||||
|
||||
if (++a->htime > a->hang_count)
|
||||
{
|
||||
a->state = 4;
|
||||
a->itime = 0;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
scale = 0.5 - a->wave[a->itime];
|
||||
a->out[2 * i + 0] = a->dline[2 * a->out_idx + 0] * scale;
|
||||
a->out[2 * i + 1] = a->dline[2 * a->out_idx + 1] * scale;
|
||||
|
||||
if (a->count > 0)
|
||||
{
|
||||
a->state = 1;
|
||||
@ -169,16 +192,27 @@ void ANB::xanb (ANB *a)
|
||||
a->power = scale;
|
||||
}
|
||||
else if (++a->itime > a->trans_count)
|
||||
{
|
||||
a->state = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (a->count > 0) a->count--;
|
||||
if (++a->in_idx == a->dline_size) a->in_idx = 0;
|
||||
if (++a->out_idx == a->dline_size) a->out_idx = 0;
|
||||
|
||||
if (a->count > 0)
|
||||
a->count--;
|
||||
|
||||
if (++a->in_idx == a->dline_size)
|
||||
a->in_idx = 0;
|
||||
|
||||
if (++a->out_idx == a->dline_size)
|
||||
a->out_idx = 0;
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->buffsize * sizeof (wcomplex));
|
||||
{
|
||||
std::copy(a->in, a->in + a->buffsize * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void ANB::setBuffers_anb (ANB *a, float* in, float* out)
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
double advtime; // deadtime (zero output) in advance of detected noise
|
||||
double backtau; // time constant used in averaging the magnitude of the input signal
|
||||
double threshold; // triggers if (noise > threshold * average_signal_magnitude)
|
||||
float *wave; // pointer to array holding transition waveform
|
||||
double *wave; // pointer to array holding transition waveform
|
||||
int state; // state of the state machine
|
||||
double avg; // average value of the signal magnitude
|
||||
int dtime; // count when decreasing the signal magnitude
|
||||
|
54
wdsp/anf.cpp
54
wdsp/anf.cpp
@ -45,15 +45,15 @@ ANF* ANF::create_anf(
|
||||
int dline_size,
|
||||
int n_taps,
|
||||
int delay,
|
||||
float two_mu,
|
||||
float gamma,
|
||||
float lidx,
|
||||
float lidx_min,
|
||||
float lidx_max,
|
||||
float ngamma,
|
||||
float den_mult,
|
||||
float lincr,
|
||||
float ldecr
|
||||
double two_mu,
|
||||
double gamma,
|
||||
double lidx,
|
||||
double lidx_min,
|
||||
double lidx_max,
|
||||
double ngamma,
|
||||
double den_mult,
|
||||
double lincr,
|
||||
double ldecr
|
||||
)
|
||||
{
|
||||
ANF *a = new ANF;
|
||||
@ -77,8 +77,8 @@ ANF* ANF::create_anf(
|
||||
a->lincr = lincr;
|
||||
a->ldecr = ldecr;
|
||||
|
||||
memset (a->d, 0, sizeof(float) * ANF_DLINE_SIZE);
|
||||
memset (a->w, 0, sizeof(float) * ANF_DLINE_SIZE);
|
||||
memset (a->d, 0, sizeof(double) * ANF_DLINE_SIZE);
|
||||
memset (a->w, 0, sizeof(double) * ANF_DLINE_SIZE);
|
||||
|
||||
return a;
|
||||
}
|
||||
@ -91,9 +91,10 @@ void ANF::destroy_anf (ANF *a)
|
||||
void ANF::xanf(ANF *a, int position)
|
||||
{
|
||||
int i, j, idx;
|
||||
float c0, c1;
|
||||
float y, error, sigma, inv_sigp;
|
||||
float nel, nev;
|
||||
double c0, c1;
|
||||
double y, error, sigma, inv_sigp;
|
||||
double nel, nev;
|
||||
|
||||
if (a->run && (a->position == position))
|
||||
{
|
||||
for (i = 0; i < a->buff_size; i++)
|
||||
@ -109,14 +110,19 @@ void ANF::xanf(ANF *a, int position)
|
||||
y += a->w[j] * a->d[idx];
|
||||
sigma += a->d[idx] * a->d[idx];
|
||||
}
|
||||
|
||||
inv_sigp = 1.0 / (sigma + 1e-10);
|
||||
error = a->d[a->in_idx] - y;
|
||||
|
||||
a->out_buff[2 * i + 0] = error;
|
||||
a->out_buff[2 * i + 1] = 0.0;
|
||||
|
||||
if((nel = error * (1.0 - a->two_mu * sigma * inv_sigp)) < 0.0) nel = -nel;
|
||||
if((nev = a->d[a->in_idx] - (1.0 - a->two_mu * a->ngamma) * y - a->two_mu * error * sigma * inv_sigp) < 0.0) nev = -nev;
|
||||
if ((nel = error * (1.0 - a->two_mu * sigma * inv_sigp)) < 0.0)
|
||||
nel = -nel;
|
||||
|
||||
if ((nev = a->d[a->in_idx] - (1.0 - a->two_mu * a->ngamma) * y - a->two_mu * error * sigma * inv_sigp) < 0.0)
|
||||
nev = -nev;
|
||||
|
||||
if (nev < nel)
|
||||
{
|
||||
if ((a->lidx += a->lincr) > a->lidx_max) a->lidx = a->lidx_max;
|
||||
@ -125,6 +131,7 @@ void ANF::xanf(ANF *a, int position)
|
||||
{
|
||||
if ((a->lidx -= a->ldecr) < a->lidx_min) a->lidx = a->lidx_min;
|
||||
}
|
||||
|
||||
a->ngamma = a->gamma * (a->lidx * a->lidx) * (a->lidx * a->lidx) * a->den_mult;
|
||||
|
||||
c0 = 1.0 - a->two_mu * a->ngamma;
|
||||
@ -135,17 +142,20 @@ void ANF::xanf(ANF *a, int position)
|
||||
idx = (a->in_idx + j + a->delay) & a->mask;
|
||||
a->w[j] = c0 * a->w[j] + c1 * a->d[idx];
|
||||
}
|
||||
|
||||
a->in_idx = (a->in_idx + a->mask) & a->mask;
|
||||
}
|
||||
}
|
||||
else if (a->in_buff != a->out_buff)
|
||||
memcpy (a->out_buff, a->in_buff, a->buff_size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy(a->in_buff, a->in_buff + a->buff_size * 2, a->out_buff);
|
||||
}
|
||||
}
|
||||
|
||||
void ANF::flush_anf (ANF *a)
|
||||
{
|
||||
memset (a->d, 0, sizeof(float) * ANF_DLINE_SIZE);
|
||||
memset (a->w, 0, sizeof(float) * ANF_DLINE_SIZE);
|
||||
memset (a->d, 0, sizeof(double) * ANF_DLINE_SIZE);
|
||||
memset (a->w, 0, sizeof(double) * ANF_DLINE_SIZE);
|
||||
a->in_idx = 0;
|
||||
}
|
||||
|
||||
@ -193,7 +203,7 @@ void ANF::SetANFRun (RXA& rxa, int run)
|
||||
}
|
||||
|
||||
|
||||
void ANF::SetANFVals (RXA& rxa, int taps, int delay, float gain, float leakage)
|
||||
void ANF::SetANFVals (RXA& rxa, int taps, int delay, double gain, double leakage)
|
||||
{
|
||||
rxa.anf.p->n_taps = taps;
|
||||
rxa.anf.p->delay = delay;
|
||||
@ -214,13 +224,13 @@ void ANF::SetANFDelay (RXA& rxa, int delay)
|
||||
flush_anf (rxa.anf.p);
|
||||
}
|
||||
|
||||
void ANF::SetANFGain (RXA& rxa, float gain)
|
||||
void ANF::SetANFGain (RXA& rxa, double gain)
|
||||
{
|
||||
rxa.anf.p->two_mu = gain;
|
||||
flush_anf (rxa.anf.p);
|
||||
}
|
||||
|
||||
void ANF::SetANFLeakage (RXA& rxa, float leakage)
|
||||
void ANF::SetANFLeakage (RXA& rxa, double leakage)
|
||||
{
|
||||
rxa.anf.p->gamma = leakage;
|
||||
flush_anf (rxa.anf.p);
|
||||
|
46
wdsp/anf.hpp
46
wdsp/anf.hpp
@ -48,18 +48,18 @@ public:
|
||||
int mask;
|
||||
int n_taps;
|
||||
int delay;
|
||||
float two_mu;
|
||||
float gamma;
|
||||
float d [ANF_DLINE_SIZE];
|
||||
float w [ANF_DLINE_SIZE];
|
||||
double two_mu;
|
||||
double gamma;
|
||||
double d [ANF_DLINE_SIZE];
|
||||
double w [ANF_DLINE_SIZE];
|
||||
int in_idx;
|
||||
float lidx;
|
||||
float lidx_min;
|
||||
float lidx_max;
|
||||
float ngamma;
|
||||
float den_mult;
|
||||
float lincr;
|
||||
float ldecr;
|
||||
double lidx;
|
||||
double lidx_min;
|
||||
double lidx_max;
|
||||
double ngamma;
|
||||
double den_mult;
|
||||
double lincr;
|
||||
double ldecr;
|
||||
|
||||
static ANF* create_anf(
|
||||
int run,
|
||||
@ -70,15 +70,15 @@ public:
|
||||
int dline_size,
|
||||
int n_taps,
|
||||
int delay,
|
||||
float two_mu,
|
||||
float gamma,
|
||||
float lidx,
|
||||
float lidx_min,
|
||||
float lidx_max,
|
||||
float ngamma,
|
||||
float den_mult,
|
||||
float lincr,
|
||||
float ldecr
|
||||
double two_mu,
|
||||
double gamma,
|
||||
double lidx,
|
||||
double lidx_min,
|
||||
double lidx_max,
|
||||
double ngamma,
|
||||
double den_mult,
|
||||
double lincr,
|
||||
double ldecr
|
||||
);
|
||||
static void destroy_anf (ANF *a);
|
||||
static void flush_anf (ANF *a);
|
||||
@ -88,11 +88,11 @@ public:
|
||||
static void setSize_anf (ANF *a, int size);
|
||||
// RXA Properties
|
||||
static void SetANFRun (RXA& rxa, int setit);
|
||||
static void SetANFVals (RXA& rxa, int taps, int delay, float gain, float leakage);
|
||||
static void SetANFVals (RXA& rxa, int taps, int delay, double gain, double leakage);
|
||||
static void SetANFTaps (RXA& rxa, int taps);
|
||||
static void SetANFDelay (RXA& rxa, int delay);
|
||||
static void SetANFGain (RXA& rxa, float gain);
|
||||
static void SetANFLeakage (RXA& rxa, float leakage);
|
||||
static void SetANFGain (RXA& rxa, double gain);
|
||||
static void SetANFLeakage (RXA& rxa, double leakage);
|
||||
static void SetANFPosition (RXA& rxa, int position);
|
||||
};
|
||||
|
||||
|
71
wdsp/anr.cpp
71
wdsp/anr.cpp
@ -45,16 +45,15 @@ ANR* ANR::create_anr (
|
||||
int dline_size,
|
||||
int n_taps,
|
||||
int delay,
|
||||
float two_mu,
|
||||
float gamma,
|
||||
|
||||
float lidx,
|
||||
float lidx_min,
|
||||
float lidx_max,
|
||||
float ngamma,
|
||||
float den_mult,
|
||||
float lincr,
|
||||
float ldecr
|
||||
double two_mu,
|
||||
double gamma,
|
||||
double lidx,
|
||||
double lidx_min,
|
||||
double lidx_max,
|
||||
double ngamma,
|
||||
double den_mult,
|
||||
double lincr,
|
||||
double ldecr
|
||||
)
|
||||
{
|
||||
ANR *a = new ANR;
|
||||
@ -78,8 +77,8 @@ ANR* ANR::create_anr (
|
||||
a->lincr = lincr;
|
||||
a->ldecr = ldecr;
|
||||
|
||||
memset (a->d, 0, sizeof(float) * ANR_DLINE_SIZE);
|
||||
memset (a->w, 0, sizeof(float) * ANR_DLINE_SIZE);
|
||||
memset (a->d, 0, sizeof(double) * ANR_DLINE_SIZE);
|
||||
memset (a->w, 0, sizeof(double) * ANR_DLINE_SIZE);
|
||||
|
||||
return a;
|
||||
}
|
||||
@ -92,9 +91,10 @@ void ANR::destroy_anr (ANR *a)
|
||||
void ANR::xanr (ANR *a, int position)
|
||||
{
|
||||
int i, j, idx;
|
||||
float c0, c1;
|
||||
float y, error, sigma, inv_sigp;
|
||||
float nel, nev;
|
||||
double c0, c1;
|
||||
double y, error, sigma, inv_sigp;
|
||||
double nel, nev;
|
||||
|
||||
if (a->run && (a->position == position))
|
||||
{
|
||||
for (i = 0; i < a->buff_size; i++)
|
||||
@ -110,24 +110,30 @@ void ANR::xanr (ANR *a, int position)
|
||||
y += a->w[j] * a->d[idx];
|
||||
sigma += a->d[idx] * a->d[idx];
|
||||
}
|
||||
|
||||
inv_sigp = 1.0 / (sigma + 1e-10);
|
||||
error = a->d[a->in_idx] - y;
|
||||
|
||||
a->out_buff[2 * i + 0] = y;
|
||||
a->out_buff[2 * i + 1] = 0.0;
|
||||
|
||||
if((nel = error * (1.0 - a->two_mu * sigma * inv_sigp)) < 0.0) nel = -nel;
|
||||
if((nev = a->d[a->in_idx] - (1.0 - a->two_mu * a->ngamma) * y - a->two_mu * error * sigma * inv_sigp) < 0.0) nev = -nev;
|
||||
if ((nel = error * (1.0 - a->two_mu * sigma * inv_sigp)) < 0.0)
|
||||
nel = -nel;
|
||||
if ((nev = a->d[a->in_idx] - (1.0 - a->two_mu * a->ngamma) * y - a->two_mu * error * sigma * inv_sigp) < 0.0)
|
||||
nev = -nev;
|
||||
|
||||
if (nev < nel)
|
||||
{
|
||||
if ((a->lidx += a->lincr) > a->lidx_max) a->lidx = a->lidx_max;
|
||||
if ((a->lidx += a->lincr) > a->lidx_max)
|
||||
a->lidx = a->lidx_max;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((a->lidx -= a->ldecr) < a->lidx_min) a->lidx = a->lidx_min;
|
||||
if ((a->lidx -= a->ldecr) < a->lidx_min)
|
||||
a->lidx = a->lidx_min;
|
||||
}
|
||||
a->ngamma = a->gamma * (a->lidx * a->lidx) * (a->lidx * a->lidx) * a->den_mult;
|
||||
|
||||
a->ngamma = a->gamma * (a->lidx * a->lidx) * (a->lidx * a->lidx) * a->den_mult;
|
||||
c0 = 1.0 - a->two_mu * a->ngamma;
|
||||
c1 = a->two_mu * error * inv_sigp;
|
||||
|
||||
@ -136,17 +142,20 @@ void ANR::xanr (ANR *a, int position)
|
||||
idx = (a->in_idx + j + a->delay) & a->mask;
|
||||
a->w[j] = c0 * a->w[j] + c1 * a->d[idx];
|
||||
}
|
||||
|
||||
a->in_idx = (a->in_idx + a->mask) & a->mask;
|
||||
}
|
||||
}
|
||||
else if (a->in_buff != a->out_buff)
|
||||
memcpy (a->out_buff, a->in_buff, a->buff_size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy(a->in_buff, a->in_buff + a->buff_size * 2, a->out_buff);
|
||||
}
|
||||
}
|
||||
|
||||
void ANR::flush_anr (ANR *a)
|
||||
{
|
||||
memset (a->d, 0, sizeof(float) * ANR_DLINE_SIZE);
|
||||
memset (a->w, 0, sizeof(float) * ANR_DLINE_SIZE);
|
||||
memset (a->d, 0, sizeof(double) * ANR_DLINE_SIZE);
|
||||
memset (a->w, 0, sizeof(double) * ANR_DLINE_SIZE);
|
||||
a->in_idx = 0;
|
||||
}
|
||||
|
||||
@ -179,15 +188,21 @@ void ANR::SetANRRun (RXA& rxa, int run)
|
||||
|
||||
if (a->run != run)
|
||||
{
|
||||
RXA::bp1Check (rxa, rxa.amd.p->run, rxa.snba.p->run,
|
||||
rxa.emnr.p->run, rxa.anf.p->run, run);
|
||||
RXA::bp1Check (
|
||||
rxa,
|
||||
rxa.amd.p->run,
|
||||
rxa.snba.p->run,
|
||||
rxa.emnr.p->run,
|
||||
rxa.anf.p->run,
|
||||
run
|
||||
);
|
||||
a->run = run;
|
||||
RXA::bp1Set (rxa);
|
||||
flush_anr (a);
|
||||
}
|
||||
}
|
||||
|
||||
void ANR::SetANRVals (RXA& rxa, int taps, int delay, float gain, float leakage)
|
||||
void ANR::SetANRVals (RXA& rxa, int taps, int delay, double gain, double leakage)
|
||||
{
|
||||
rxa.anr.p->n_taps = taps;
|
||||
rxa.anr.p->delay = delay;
|
||||
@ -208,13 +223,13 @@ void ANR::SetANRDelay (RXA& rxa, int delay)
|
||||
flush_anr (rxa.anr.p);
|
||||
}
|
||||
|
||||
void ANR::SetANRGain (RXA& rxa, float gain)
|
||||
void ANR::SetANRGain (RXA& rxa, double gain)
|
||||
{
|
||||
rxa.anr.p->two_mu = gain;
|
||||
flush_anr (rxa.anr.p);
|
||||
}
|
||||
|
||||
void ANR::SetANRLeakage (RXA& rxa, float leakage)
|
||||
void ANR::SetANRLeakage (RXA& rxa, double leakage)
|
||||
{
|
||||
rxa.anr.p->gamma = leakage;
|
||||
flush_anr (rxa.anr.p);
|
||||
|
47
wdsp/anr.hpp
47
wdsp/anr.hpp
@ -48,19 +48,19 @@ public:
|
||||
int mask;
|
||||
int n_taps;
|
||||
int delay;
|
||||
float two_mu;
|
||||
float gamma;
|
||||
float d [ANR_DLINE_SIZE];
|
||||
float w [ANR_DLINE_SIZE];
|
||||
double two_mu;
|
||||
double gamma;
|
||||
double d [ANR_DLINE_SIZE];
|
||||
double w [ANR_DLINE_SIZE];
|
||||
int in_idx;
|
||||
|
||||
float lidx;
|
||||
float lidx_min;
|
||||
float lidx_max;
|
||||
float ngamma;
|
||||
float den_mult;
|
||||
float lincr;
|
||||
float ldecr;
|
||||
double lidx;
|
||||
double lidx_min;
|
||||
double lidx_max;
|
||||
double ngamma;
|
||||
double den_mult;
|
||||
double lincr;
|
||||
double ldecr;
|
||||
|
||||
static ANR* create_anr (
|
||||
int run,
|
||||
@ -71,16 +71,15 @@ public:
|
||||
int dline_size,
|
||||
int n_taps,
|
||||
int delay,
|
||||
float two_mu,
|
||||
float gamma,
|
||||
|
||||
float lidx,
|
||||
float lidx_min,
|
||||
float lidx_max,
|
||||
float ngamma,
|
||||
float den_mult,
|
||||
float lincr,
|
||||
float ldecr
|
||||
double two_mu,
|
||||
double gamma,
|
||||
double lidx,
|
||||
double lidx_min,
|
||||
double lidx_max,
|
||||
double ngamma,
|
||||
double den_mult,
|
||||
double lincr,
|
||||
double ldecr
|
||||
);
|
||||
|
||||
static void destroy_anr (ANR *a);
|
||||
@ -91,11 +90,11 @@ public:
|
||||
static void setSize_anr (ANR *a, int size);
|
||||
// RXA Properties
|
||||
static void SetANRRun (RXA& rxa, int setit);
|
||||
static void SetANRVals (RXA& rxa, int taps, int delay, float gain, float leakage);
|
||||
static void SetANRVals (RXA& rxa, int taps, int delay, double gain, double leakage);
|
||||
static void SetANRTaps (RXA& rxa, int taps);
|
||||
static void SetANRDelay (RXA& rxa, int delay);
|
||||
static void SetANRGain (RXA& rxa, float gain);
|
||||
static void SetANRLeakage (RXA& rxa, float leakage);
|
||||
static void SetANRGain (RXA& rxa, double gain);
|
||||
static void SetANRLeakage (RXA& rxa, double leakage);
|
||||
static void SetANRPosition (RXA& rxa, int position);
|
||||
};
|
||||
|
||||
|
@ -48,11 +48,11 @@ BANDPASS* BANDPASS::create_bandpass (
|
||||
int mp,
|
||||
float* in,
|
||||
float* out,
|
||||
float f_low,
|
||||
float f_high,
|
||||
double f_low,
|
||||
double f_high,
|
||||
int samplerate,
|
||||
int wintype,
|
||||
float gain
|
||||
double gain
|
||||
)
|
||||
{
|
||||
// NOTE: 'nc' must be >= 'size'
|
||||
@ -76,7 +76,7 @@ BANDPASS* BANDPASS::create_bandpass (
|
||||
a->samplerate,
|
||||
a->wintype,
|
||||
1,
|
||||
a->gain / (float)(2 * a->size)
|
||||
a->gain / (double)(2 * a->size)
|
||||
);
|
||||
a->p = FIRCORE::create_fircore (a->size, a->in, a->out, a->nc, a->mp, impulse);
|
||||
delete[] impulse;
|
||||
@ -99,7 +99,7 @@ void BANDPASS::xbandpass (BANDPASS *a, int pos)
|
||||
if (a->run && a->position == pos)
|
||||
FIRCORE::xfircore (a->p);
|
||||
else if (a->out != a->in)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void BANDPASS::setBuffers_bandpass (BANDPASS *a, float* in, float* out)
|
||||
@ -144,7 +144,7 @@ void BANDPASS::setSize_bandpass (BANDPASS *a, int size)
|
||||
delete[] (impulse);
|
||||
}
|
||||
|
||||
void BANDPASS::setGain_bandpass (BANDPASS *a, float gain, int update)
|
||||
void BANDPASS::setGain_bandpass (BANDPASS *a, double gain, int update)
|
||||
{
|
||||
a->gain = gain;
|
||||
float* impulse = FIR::fir_bandpass (
|
||||
@ -154,13 +154,13 @@ void BANDPASS::setGain_bandpass (BANDPASS *a, float gain, int update)
|
||||
a->samplerate,
|
||||
a->wintype,
|
||||
1,
|
||||
a->gain / (float)(2 * a->size)
|
||||
a->gain / (double)(2 * a->size)
|
||||
);
|
||||
FIRCORE::setImpulse_fircore (a->p, impulse, update);
|
||||
delete[] (impulse);
|
||||
}
|
||||
|
||||
void BANDPASS::CalcBandpassFilter (BANDPASS *a, float f_low, float f_high, float gain)
|
||||
void BANDPASS::CalcBandpassFilter (BANDPASS *a, double f_low, double f_high, double gain)
|
||||
{
|
||||
if ((a->f_low != f_low) || (a->f_high != f_high) || (a->gain != gain))
|
||||
{
|
||||
@ -174,7 +174,7 @@ void BANDPASS::CalcBandpassFilter (BANDPASS *a, float f_low, float f_high, float
|
||||
a->samplerate,
|
||||
a->wintype,
|
||||
1,
|
||||
a->gain / (float)(2 * a->size)
|
||||
a->gain / (double)(2 * a->size)
|
||||
);
|
||||
FIRCORE::setImpulse_fircore (a->p, impulse, 1);
|
||||
delete[] (impulse);
|
||||
@ -187,7 +187,7 @@ void BANDPASS::CalcBandpassFilter (BANDPASS *a, float f_low, float f_high, float
|
||||
* *
|
||||
********************************************************************************************************/
|
||||
|
||||
void BANDPASS::SetBandpassFreqs (RXA& rxa, float f_low, float f_high)
|
||||
void BANDPASS::SetBandpassFreqs (RXA& rxa, double f_low, double f_high)
|
||||
{
|
||||
BANDPASS *a = rxa.bp1.p;
|
||||
|
||||
@ -200,7 +200,7 @@ void BANDPASS::SetBandpassFreqs (RXA& rxa, float f_low, float f_high)
|
||||
a->samplerate,
|
||||
a->wintype,
|
||||
1,
|
||||
a->gain / (float)(2 * a->size)
|
||||
a->gain / (double)(2 * a->size)
|
||||
);
|
||||
|
||||
FIRCORE::setImpulse_fircore (a->p, impulse, 0);
|
||||
@ -227,7 +227,7 @@ void BANDPASS::SetBandpassNC (RXA& rxa, int nc)
|
||||
a->samplerate,
|
||||
a->wintype,
|
||||
1,
|
||||
a->gain / (float)(2 * a->size)
|
||||
a->gain / (double)(2 * a->size)
|
||||
);
|
||||
FIRCORE::setNc_fircore (a->p, a->nc, impulse);
|
||||
delete[] (impulse);
|
||||
@ -302,7 +302,7 @@ void BANDPASS::SetBandpassNC (TXA& txa, int nc)
|
||||
a->samplerate,
|
||||
a->wintype,
|
||||
1,
|
||||
a->gain / (float)(2 * a->size)
|
||||
a->gain / (double)(2 * a->size)
|
||||
);
|
||||
FIRCORE::setNc_fircore (a->p, a->nc, impulse);
|
||||
delete[] (impulse);
|
||||
@ -320,7 +320,7 @@ void BANDPASS::SetBandpassNC (TXA& txa, int nc)
|
||||
a->samplerate,
|
||||
a->wintype,
|
||||
1,
|
||||
a->gain / (float)(2 * a->size)
|
||||
a->gain / (double)(2 * a->size)
|
||||
);
|
||||
FIRCORE::setNc_fircore (a->p, a->nc, impulse);
|
||||
delete[] (impulse);
|
||||
@ -338,7 +338,7 @@ void BANDPASS::SetBandpassNC (TXA& txa, int nc)
|
||||
a->samplerate,
|
||||
a->wintype,
|
||||
1,
|
||||
a->gain / (float)(2 * a->size)
|
||||
a->gain / (double)(2 * a->size)
|
||||
);
|
||||
FIRCORE::setNc_fircore (a->p, a->nc, impulse);
|
||||
delete[] (impulse);
|
||||
|
@ -59,25 +59,37 @@ public:
|
||||
int mp;
|
||||
float* in;
|
||||
float* out;
|
||||
float f_low;
|
||||
float f_high;
|
||||
float samplerate;
|
||||
double f_low;
|
||||
double f_high;
|
||||
double samplerate;
|
||||
int wintype;
|
||||
float gain;
|
||||
double gain;
|
||||
FIRCORE *p;
|
||||
|
||||
static BANDPASS *create_bandpass (int run, int position, int size, int nc, int mp, float* in, float* out,
|
||||
float f_low, float f_high, int samplerate, int wintype, float gain);
|
||||
static BANDPASS *create_bandpass (
|
||||
int run,
|
||||
int position,
|
||||
int size,
|
||||
int nc,
|
||||
int mp,
|
||||
float* in,
|
||||
float* out,
|
||||
double f_low,
|
||||
double f_high,
|
||||
int samplerate,
|
||||
int wintype,
|
||||
double gain
|
||||
);
|
||||
static void destroy_bandpass (BANDPASS *a);
|
||||
static void flush_bandpass (BANDPASS *a);
|
||||
static void xbandpass (BANDPASS *a, int pos);
|
||||
static void setBuffers_bandpass (BANDPASS *a, float* in, float* out);
|
||||
static void setSamplerate_bandpass (BANDPASS *a, int rate);
|
||||
static void setSize_bandpass (BANDPASS *a, int size);
|
||||
static void setGain_bandpass (BANDPASS *a, float gain, int update);
|
||||
static void CalcBandpassFilter (BANDPASS *a, float f_low, float f_high, float gain);
|
||||
static void setGain_bandpass (BANDPASS *a, double gain, int update);
|
||||
static void CalcBandpassFilter (BANDPASS *a, double f_low, double f_high, double gain);
|
||||
// RXA Prototypes
|
||||
static void SetBandpassFreqs (RXA& rxa, float f_low, float f_high);
|
||||
static void SetBandpassFreqs (RXA& rxa, double f_low, double f_high);
|
||||
static void SetBandpassNC (RXA& rxa, int nc);
|
||||
static void SetBandpassMP (RXA& rxa, int mp);
|
||||
// TXA Prototypes
|
||||
|
12
wdsp/bps.cpp
12
wdsp/bps.cpp
@ -43,8 +43,8 @@ namespace WDSP {
|
||||
void BPS::calc_bps (BPS *a)
|
||||
{
|
||||
float* impulse;
|
||||
a->infilt = new float[2 * a->size * 2]; // (float *)malloc0(2 * a->size * sizeof(wcomplex));
|
||||
a->product = new float[2 * a->size * 2]; // (float *)malloc0(2 * a->size * sizeof(wcomplex));
|
||||
a->infilt = new float[2 * a->size * 2];
|
||||
a->product = new float[2 * a->size * 2];
|
||||
impulse = FIR::fir_bandpass(a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size));
|
||||
a->mults = FIR::fftcv_mults(2 * a->size, impulse);
|
||||
a->CFor = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->infilt, (fftwf_complex *)a->product, FFTW_FORWARD, FFTW_PATIENT);
|
||||
@ -87,7 +87,7 @@ void BPS::destroy_bps (BPS *a)
|
||||
|
||||
void BPS::flush_bps (BPS *a)
|
||||
{
|
||||
memset (a->infilt, 0, 2 * a->size * sizeof (wcomplex));
|
||||
std::fill(a->infilt, a->infilt + 2 * a->size * 2, 0);
|
||||
}
|
||||
|
||||
void BPS::xbps (BPS *a, int pos)
|
||||
@ -96,7 +96,7 @@ void BPS::xbps (BPS *a, int pos)
|
||||
float I, Q;
|
||||
if (a->run && pos == a->position)
|
||||
{
|
||||
memcpy (&(a->infilt[2 * a->size]), a->in, a->size * sizeof (wcomplex));
|
||||
std::copy(a->in, a->in + a->size * 2, &(a->infilt[2 * a->size]));
|
||||
fftwf_execute (a->CFor);
|
||||
for (i = 0; i < 2 * a->size; i++)
|
||||
{
|
||||
@ -106,10 +106,10 @@ void BPS::xbps (BPS *a, int pos)
|
||||
a->product[2 * i + 1] = I * a->mults[2 * i + 1] + Q * a->mults[2 * i + 0];
|
||||
}
|
||||
fftwf_execute (a->CRev);
|
||||
memcpy (a->infilt, &(a->infilt[2 * a->size]), a->size * sizeof(wcomplex));
|
||||
std::copy(&(a->infilt[2 * a->size]), &(a->infilt[2 * a->size]) + a->size * 2, a->infilt);
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void BPS::setBuffers_bps (BPS *a, float* in, float* out)
|
||||
|
@ -131,7 +131,7 @@ void BPSNBA::destroy_bpsnba (BPSNBA *a)
|
||||
|
||||
void BPSNBA::flush_bpsnba (BPSNBA *a)
|
||||
{
|
||||
memset (a->buff, 0, a->size * sizeof (wcomplex));
|
||||
std::fill(a->buff, a->buff + a->size * 2, 0);
|
||||
NBP::flush_nbp (a->bpsnba);
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ void BPSNBA::setSize_bpsnba (BPSNBA *a, int size)
|
||||
void BPSNBA::xbpsnbain (BPSNBA *a, int position)
|
||||
{
|
||||
if (a->run && a->position == position)
|
||||
memcpy (a->buff, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy(a->in, a->in + a->size * 2, a->buff);
|
||||
}
|
||||
|
||||
void BPSNBA::xbpsnbaout (BPSNBA *a, int position)
|
||||
|
@ -40,16 +40,15 @@ void CBL::calc_cbl (CBL *a)
|
||||
a->mtau = exp(-1.0 / (a->sample_rate * a->tau));
|
||||
}
|
||||
|
||||
CBL* CBL::create_cbl
|
||||
(
|
||||
CBL* CBL::create_cbl(
|
||||
int run,
|
||||
int buff_size,
|
||||
float *in_buff,
|
||||
float *out_buff,
|
||||
int mode,
|
||||
int sample_rate,
|
||||
float tau
|
||||
)
|
||||
double tau
|
||||
)
|
||||
{
|
||||
CBL *a = new CBL;
|
||||
a->run = run;
|
||||
@ -57,7 +56,7 @@ CBL* CBL::create_cbl
|
||||
a->in_buff = in_buff;
|
||||
a->out_buff = out_buff;
|
||||
a->mode = mode;
|
||||
a->sample_rate = (float)sample_rate;
|
||||
a->sample_rate = (double) sample_rate;
|
||||
a->tau = tau;
|
||||
calc_cbl (a);
|
||||
return a;
|
||||
@ -81,7 +80,8 @@ void CBL::xcbl (CBL *a)
|
||||
if (a->run)
|
||||
{
|
||||
int i;
|
||||
float tempI, tempQ;
|
||||
double tempI, tempQ;
|
||||
|
||||
for (i = 0; i < a->buff_size; i++)
|
||||
{
|
||||
tempI = a->in_buff[2 * i + 0];
|
||||
@ -90,12 +90,18 @@ void CBL::xcbl (CBL *a)
|
||||
a->out_buff[2 * i + 1] = a->in_buff[2 * i + 1] - a->prevQin + a->mtau * a->prevQout;
|
||||
a->prevIin = tempI;
|
||||
a->prevQin = tempQ;
|
||||
if (fabs(a->prevIout = a->out_buff[2 * i + 0]) < 1.0e-100) a->prevIout = 0.0;
|
||||
if (fabs(a->prevQout = a->out_buff[2 * i + 1]) < 1.0e-100) a->prevQout = 0.0;
|
||||
|
||||
if (fabs(a->prevIout = a->out_buff[2 * i + 0]) < 1.0e-20)
|
||||
a->prevIout = 0.0;
|
||||
|
||||
if (fabs(a->prevQout = a->out_buff[2 * i + 1]) < 1.0e-20)
|
||||
a->prevQout = 0.0;
|
||||
}
|
||||
}
|
||||
else if (a->in_buff != a->out_buff)
|
||||
memcpy (a->out_buff, a->in_buff, a->buff_size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy(a->in_buff, a->in_buff + a->buff_size * 2, a->out_buff);
|
||||
}
|
||||
}
|
||||
|
||||
void CBL::setBuffers_cbl (CBL *a, float* in, float* out)
|
||||
|
@ -42,24 +42,23 @@ public:
|
||||
float *in_buff; //pointer to input buffer
|
||||
float *out_buff; //pointer to output buffer
|
||||
int mode;
|
||||
float sample_rate; //sample rate
|
||||
float prevIin;
|
||||
float prevQin;
|
||||
float prevIout;
|
||||
float prevQout;
|
||||
float tau; //carrier removal time constant
|
||||
float mtau; //carrier removal multiplier
|
||||
double sample_rate; //sample rate
|
||||
double prevIin;
|
||||
double prevQin;
|
||||
double prevIout;
|
||||
double prevQout;
|
||||
double tau; //carrier removal time constant
|
||||
double mtau; //carrier removal multiplier
|
||||
|
||||
static CBL* create_cbl
|
||||
(
|
||||
static CBL* create_cbl(
|
||||
int run,
|
||||
int buff_size,
|
||||
float *in_buff,
|
||||
float *out_buff,
|
||||
int mode,
|
||||
int sample_rate,
|
||||
float tau
|
||||
);
|
||||
double tau
|
||||
);
|
||||
static void destroy_cbl (CBL *a);
|
||||
static void flush_cbl (CBL *a);
|
||||
static void xcbl (CBL *a);
|
||||
|
@ -387,7 +387,7 @@ void CFCOMP::xcfcomp (CFCOMP *a, int pos)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy (a->out, a->in, a->bsize * sizeof (wcomplex));
|
||||
std::copy(a->in, a->in + a->bsize * 2, a->out);
|
||||
}
|
||||
|
||||
void CFCOMP::setBuffers_cfcomp (CFCOMP *a, float* in, float* out)
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -98,7 +113,7 @@ void CFIR::xcfir (CFIR *a)
|
||||
if (a->run)
|
||||
FIRCORE::xfircore (a->p);
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void CFIR::setBuffers_cfir (CFIR *a, float* in, float* out)
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 <QThread>
|
||||
|
||||
#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
|
@ -74,12 +74,6 @@ warren@wpratt.com
|
||||
#define PI 3.1415926535897932
|
||||
#define TWOPI 6.2831853071795864
|
||||
|
||||
namespace WDSP {
|
||||
// miscellaneous
|
||||
typedef float wcomplex[2];
|
||||
typedef double dcomplex[2];
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <cstdint>
|
||||
|
@ -74,7 +74,7 @@ void COMPRESSOR::xcompressor (COMPRESSOR *a)
|
||||
a->outbuff[2 * i + 1] = 0.0;
|
||||
}
|
||||
else if (a->inbuff != a->outbuff)
|
||||
memcpy(a->outbuff, a->inbuff, a->buffsize * sizeof (wcomplex));
|
||||
std::copy(a->inbuff, a->inbuff + a->buffsize * 2, a->outbuff);
|
||||
}
|
||||
|
||||
void COMPRESSOR::setBuffers_compressor (COMPRESSOR *a, float* in, float* out)
|
||||
|
@ -67,7 +67,7 @@ void DELAY::destroy_delay (DELAY *a)
|
||||
|
||||
void DELAY::flush_delay (DELAY *a)
|
||||
{
|
||||
memset (a->ring, 0, a->cpp * sizeof (wcomplex));
|
||||
std::fill(a->ring, a->ring + a->cpp * 2, 0);
|
||||
a->idx_in = 0;
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ void DELAY::xdelay (DELAY *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
/********************************************************************************************************
|
||||
|
250
wdsp/emnr.cpp
250
wdsp/emnr.cpp
@ -24,6 +24,8 @@ The author can be reached by email at
|
||||
warren@wpratt.com
|
||||
|
||||
*/
|
||||
#include <limits>
|
||||
|
||||
#include "comm.hpp"
|
||||
#include "calculus.hpp"
|
||||
#include "emnr.hpp"
|
||||
@ -51,11 +53,16 @@ namespace WDSP {
|
||||
double EMNR::bessI0 (double x)
|
||||
{
|
||||
double res, p;
|
||||
|
||||
if (x == 0.0)
|
||||
{
|
||||
res = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x < 0.0) x = -x;
|
||||
if (x < 0.0)
|
||||
x = -x;
|
||||
|
||||
if (x <= 3.75)
|
||||
{
|
||||
p = x / 3.75;
|
||||
@ -90,11 +97,16 @@ double EMNR::bessI1 (double x)
|
||||
{
|
||||
|
||||
double res, p;
|
||||
|
||||
if (x == 0.0)
|
||||
{
|
||||
res = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x < 0.0) x = -x;
|
||||
if (x < 0.0)
|
||||
x = -x;
|
||||
|
||||
if (x <= 3.75)
|
||||
{
|
||||
p = x / 3.75;
|
||||
@ -123,6 +135,7 @@ double EMNR::bessI1 (double x)
|
||||
+ 0.39894228);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -136,8 +149,11 @@ double EMNR::e1xb (double x)
|
||||
{
|
||||
double e1, ga, r, t, t0;
|
||||
int k, m;
|
||||
|
||||
if (x == 0.0)
|
||||
e1 = 1.0e300;
|
||||
{
|
||||
e1 = std::numeric_limits<double>::max();;
|
||||
}
|
||||
else if (x <= 1.0)
|
||||
{
|
||||
e1 = 1.0;
|
||||
@ -147,6 +163,7 @@ double EMNR::e1xb (double x)
|
||||
{
|
||||
r = -r * k * x / ((k + 1.0)*(k + 1.0));
|
||||
e1 = e1 + r;
|
||||
|
||||
if ( fabs (r) <= fabs (e1) * 1.0e-15 )
|
||||
break;
|
||||
}
|
||||
@ -158,11 +175,14 @@ double EMNR::e1xb (double x)
|
||||
{
|
||||
m = 20 + (int)(80.0 / x);
|
||||
t0 = 0.0;
|
||||
|
||||
for (k = m; k >= 1; k--)
|
||||
t0 = (float)k / (1.0 + k / (x + t0));
|
||||
|
||||
t = 1.0 / (x + t0);
|
||||
e1 = exp (- x) * t;
|
||||
}
|
||||
|
||||
return e1;
|
||||
}
|
||||
|
||||
@ -175,20 +195,25 @@ double EMNR::e1xb (double x)
|
||||
void EMNR::calc_window (EMNR *a)
|
||||
{
|
||||
int i;
|
||||
float arg, sum, inv_coherent_gain;
|
||||
double arg, sum, inv_coherent_gain;
|
||||
|
||||
switch (a->wintype)
|
||||
{
|
||||
case 0:
|
||||
arg = 2.0 * PI / (float)a->fsize;
|
||||
arg = 2.0 * PI / (double) a->fsize;
|
||||
sum = 0.0;
|
||||
|
||||
for (i = 0; i < a->fsize; i++)
|
||||
{
|
||||
a->window[i] = sqrt (0.54 - 0.46 * cos((float)i * arg));
|
||||
sum += a->window[i];
|
||||
}
|
||||
inv_coherent_gain = (float)a->fsize / sum;
|
||||
|
||||
inv_coherent_gain = (double) a->fsize / sum;
|
||||
|
||||
for (i = 0; i < a->fsize; i++)
|
||||
a->window[i] *= inv_coherent_gain;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -196,14 +221,21 @@ void EMNR::calc_window (EMNR *a)
|
||||
void EMNR::interpM (double* res, double x, int nvals, double* xvals, double* yvals)
|
||||
{
|
||||
if (x <= xvals[0])
|
||||
{
|
||||
*res = yvals[0];
|
||||
}
|
||||
else if (x >= xvals[nvals - 1])
|
||||
{
|
||||
*res = yvals[nvals - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
int idx = 0;
|
||||
double xllow, xlhigh, frac;
|
||||
while (x >= xvals[idx]) idx++;
|
||||
|
||||
while ((x >= xvals[idx]) && (idx < nvals - 1))
|
||||
idx++;
|
||||
|
||||
xllow = log10 (xvals[idx - 1]);
|
||||
xlhigh = log10(xvals[idx]);
|
||||
frac = (log10 (x) - xllow) / (xlhigh - xllow);
|
||||
@ -222,16 +254,22 @@ void EMNR::calc_emnr(EMNR *a)
|
||||
// 3.100, 3.380, 4.150, 4.350, 4.250, 3.900, 4.100, 4.700, 5.000 };
|
||||
a->incr = a->fsize / a->ovrlp;
|
||||
a->gain = a->ogain / a->fsize / (float)a->ovrlp;
|
||||
|
||||
if (a->fsize > a->bsize)
|
||||
a->iasize = a->fsize;
|
||||
else
|
||||
a->iasize = a->bsize + a->fsize - a->incr;
|
||||
|
||||
a->iainidx = 0;
|
||||
a->iaoutidx = 0;
|
||||
|
||||
if (a->fsize > a->bsize)
|
||||
{
|
||||
if (a->bsize > a->incr) a->oasize = a->bsize;
|
||||
else a->oasize = a->incr;
|
||||
if (a->bsize > a->incr)
|
||||
a->oasize = a->bsize;
|
||||
else
|
||||
a->oasize = a->incr;
|
||||
|
||||
a->oainidx = (a->fsize - a->bsize - a->incr) % a->oasize;
|
||||
}
|
||||
else
|
||||
@ -239,6 +277,7 @@ void EMNR::calc_emnr(EMNR *a)
|
||||
a->oasize = a->bsize;
|
||||
a->oainidx = a->fsize - a->incr;
|
||||
}
|
||||
|
||||
a->init_oainidx = a->oainidx;
|
||||
a->oaoutidx = 0;
|
||||
a->msize = a->fsize / 2 + 1;
|
||||
@ -251,13 +290,26 @@ void EMNR::calc_emnr(EMNR *a)
|
||||
a->revfftin = new float[a->msize * 2]; // (float *)malloc0(a->msize * sizeof(complex));
|
||||
a->revfftout = new float[a->fsize]; // (float *)malloc0(a->fsize * sizeof(float));
|
||||
a->save = new float*[a->ovrlp]; // (float **)malloc0(a->ovrlp * sizeof(float *));
|
||||
|
||||
for (i = 0; i < a->ovrlp; i++)
|
||||
a->save[i] = new float[a->fsize]; // (float *)malloc0(a->fsize * sizeof(float));
|
||||
|
||||
a->outaccum = new float[a->oasize]; // (float *)malloc0(a->oasize * sizeof(float));
|
||||
a->nsamps = 0;
|
||||
a->saveidx = 0;
|
||||
a->Rfor = fftwf_plan_dft_r2c_1d(a->fsize, a->forfftin, (fftwf_complex *)a->forfftout, FFTW_ESTIMATE);
|
||||
a->Rrev = fftwf_plan_dft_c2r_1d(a->fsize, (fftwf_complex *)a->revfftin, a->revfftout, FFTW_ESTIMATE);
|
||||
a->Rfor = fftwf_plan_dft_r2c_1d(
|
||||
a->fsize,
|
||||
a->forfftin,
|
||||
(fftwf_complex *)a->forfftout,
|
||||
FFTW_ESTIMATE
|
||||
);
|
||||
a->Rrev = fftwf_plan_dft_c2r_1d(
|
||||
a->fsize,
|
||||
(fftwf_complex *)a->revfftin,
|
||||
a->revfftout,
|
||||
FFTW_ESTIMATE
|
||||
);
|
||||
|
||||
calc_window(a);
|
||||
|
||||
a->g.msize = a->msize;
|
||||
@ -270,21 +322,24 @@ void EMNR::calc_emnr(EMNR *a)
|
||||
|
||||
a->g.gf1p5 = sqrt(PI) / 2.0;
|
||||
{
|
||||
float tau = -128.0 / 8000.0 / log(0.98);
|
||||
double tau = -128.0 / 8000.0 / log(0.98);
|
||||
a->g.alpha = exp(-a->incr / a->rate / tau);
|
||||
}
|
||||
a->g.eps_floor = 1.0e-300;
|
||||
a->g.eps_floor = std::numeric_limits<double>::min();
|
||||
a->g.gamma_max = 1000.0;
|
||||
a->g.q = 0.2;
|
||||
|
||||
for (i = 0; i < a->g.msize; i++)
|
||||
{
|
||||
a->g.prev_mask[i] = 1.0;
|
||||
a->g.prev_gamma[i] = 1.0;
|
||||
}
|
||||
|
||||
a->g.gmax = 10000.0;
|
||||
//
|
||||
a->g.GG = new double[241 * 241]; // (float *)malloc0(241 * 241 * sizeof(float));
|
||||
a->g.GGS = new double[241 * 241]; // (float *)malloc0(241 * 241 * sizeof(float));
|
||||
|
||||
if ((a->g.fileb = fopen("calculus", "rb")))
|
||||
{
|
||||
std::size_t lgg = fread(a->g.GG, sizeof(float), 241 * 241, a->g.fileb);
|
||||
@ -311,24 +366,24 @@ void EMNR::calc_emnr(EMNR *a)
|
||||
a->np.lambda_d = a->g.lambda_d;
|
||||
|
||||
{
|
||||
float tau = -128.0 / 8000.0 / log(0.7);
|
||||
double tau = -128.0 / 8000.0 / log(0.7);
|
||||
a->np.alphaCsmooth = exp(-a->np.incr / a->np.rate / tau);
|
||||
}
|
||||
{
|
||||
float tau = -128.0 / 8000.0 / log(0.96);
|
||||
double tau = -128.0 / 8000.0 / log(0.96);
|
||||
a->np.alphaMax = exp(-a->np.incr / a->np.rate / tau);
|
||||
}
|
||||
{
|
||||
float tau = -128.0 / 8000.0 / log(0.7);
|
||||
double tau = -128.0 / 8000.0 / log(0.7);
|
||||
a->np.alphaCmin = exp(-a->np.incr / a->np.rate / tau);
|
||||
}
|
||||
{
|
||||
float tau = -128.0 / 8000.0 / log(0.3);
|
||||
double tau = -128.0 / 8000.0 / log(0.3);
|
||||
a->np.alphaMin_max_value = exp(-a->np.incr / a->np.rate / tau);
|
||||
}
|
||||
a->np.snrq = -a->np.incr / (0.064 * a->np.rate);
|
||||
{
|
||||
float tau = -128.0 / 8000.0 / log(0.8);
|
||||
double tau = -128.0 / 8000.0 / log(0.8);
|
||||
a->np.betamax = exp(-a->np.incr / a->np.rate / tau);
|
||||
}
|
||||
a->np.invQeqMax = 0.5;
|
||||
@ -336,17 +391,22 @@ void EMNR::calc_emnr(EMNR *a)
|
||||
a->np.Dtime = 8.0 * 12.0 * 128.0 / 8000.0;
|
||||
a->np.U = 8;
|
||||
a->np.V = (int)(0.5 + (a->np.Dtime * a->np.rate / (a->np.U * a->np.incr)));
|
||||
if (a->np.V < 4) a->np.V = 4;
|
||||
if ((a->np.U = (int)(0.5 + (a->np.Dtime * a->np.rate / (a->np.V * a->np.incr)))) < 1) a->np.U = 1;
|
||||
|
||||
if (a->np.V < 4)
|
||||
a->np.V = 4;
|
||||
|
||||
if ((a->np.U = (int)(0.5 + (a->np.Dtime * a->np.rate / (a->np.V * a->np.incr)))) < 1)
|
||||
a->np.U = 1;
|
||||
|
||||
a->np.D = a->np.U * a->np.V;
|
||||
interpM(&a->np.MofD, a->np.D, 18, Dvals, Mvals);
|
||||
interpM(&a->np.MofV, a->np.V, 18, Dvals, Mvals);
|
||||
a->np.invQbar_points[0] = 0.03;
|
||||
a->np.invQbar_points[1] = 0.05;
|
||||
a->np.invQbar_points[2] = 0.06;
|
||||
a->np.invQbar_points[3] = 1.0e300;
|
||||
a->np.invQbar_points[3] = std::numeric_limits<double>::max();;
|
||||
{
|
||||
float db;
|
||||
double db;
|
||||
db = 10.0 * log10(8.0) / (12.0 * 128 / 8000);
|
||||
a->np.nsmax[0] = pow(10.0, db / 10.0 * a->np.V * a->np.incr / a->np.rate);
|
||||
db = 10.0 * log10(4.0) / (12.0 * 128 / 8000);
|
||||
@ -372,6 +432,7 @@ void EMNR::calc_emnr(EMNR *a)
|
||||
a->np.lmin_flag = new int[a->np.msize]; // (int *)malloc0(a->np.msize * sizeof(int));
|
||||
a->np.pmin_u = new double[a->np.msize]; // (float *)malloc0(a->np.msize * sizeof(float));
|
||||
a->np.actminbuff = new double*[a->np.U]; // (float**)malloc0(a->np.U * sizeof(float*));
|
||||
|
||||
for (i = 0; i < a->np.U; i++)
|
||||
a->np.actminbuff[i] = new double[a->np.msize]; // (float *)malloc0(a->np.msize * sizeof(float));
|
||||
|
||||
@ -380,19 +441,25 @@ void EMNR::calc_emnr(EMNR *a)
|
||||
a->np.alphaC = 1.0;
|
||||
a->np.subwc = a->np.V;
|
||||
a->np.amb_idx = 0;
|
||||
for (k = 0; k < a->np.msize; k++) a->np.lambda_y[k] = 0.5;
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
a->np.lambda_y[k] = 0.5;
|
||||
|
||||
std::copy(a->np.lambda_y, a->np.lambda_y + a->np.msize, a->np.p);
|
||||
std::copy(a->np.lambda_y, a->np.lambda_y + a->np.msize, a->np.sigma2N);
|
||||
std::copy(a->np.lambda_y, a->np.lambda_y + a->np.msize, a->np.pbar);
|
||||
std::copy(a->np.lambda_y, a->np.lambda_y + a->np.msize, a->np.pmin_u);
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
{
|
||||
a->np.p2bar[k] = a->np.lambda_y[k] * a->np.lambda_y[k];
|
||||
a->np.actmin[k] = 1.0e300;
|
||||
a->np.actmin_sub[k] = 1.0e300;
|
||||
a->np.actmin[k] = std::numeric_limits<double>::max();
|
||||
a->np.actmin_sub[k] = std::numeric_limits<double>::max();;
|
||||
|
||||
for (ku = 0; ku < a->np.U; ku++)
|
||||
a->np.actminbuff[ku][k] = 1.0e300;
|
||||
a->np.actminbuff[ku][k] = std::numeric_limits<double>::max();;
|
||||
}
|
||||
|
||||
std::fill(a->np.lmin_flag, a->np.lmin_flag + a->np.msize, 0);
|
||||
}
|
||||
|
||||
@ -403,13 +470,14 @@ void EMNR::calc_emnr(EMNR *a)
|
||||
a->nps.lambda_d = a->g.lambda_d;
|
||||
|
||||
{
|
||||
float tau = -128.0 / 8000.0 / log(0.8);
|
||||
double tau = -128.0 / 8000.0 / log(0.8);
|
||||
a->nps.alpha_pow = exp(-a->nps.incr / a->nps.rate / tau);
|
||||
}
|
||||
{
|
||||
float tau = -128.0 / 8000.0 / log(0.9);
|
||||
double tau = -128.0 / 8000.0 / log(0.9);
|
||||
a->nps.alpha_Pbar = exp(-a->nps.incr / a->nps.rate / tau);
|
||||
}
|
||||
|
||||
a->nps.epsH1 = pow(10.0, 15.0 / 10.0);
|
||||
a->nps.epsH1r = a->nps.epsH1 / (1.0 + a->nps.epsH1);
|
||||
|
||||
@ -445,6 +513,7 @@ void EMNR::decalc_emnr(EMNR *a)
|
||||
|
||||
for (i = 0; i < a->np.U; i++)
|
||||
delete[] (a->np.actminbuff[i]);
|
||||
|
||||
delete[] (a->np.actminbuff);
|
||||
delete[] (a->np.pmin_u);
|
||||
delete[] (a->np.lmin_flag);
|
||||
@ -470,9 +539,12 @@ void EMNR::decalc_emnr(EMNR *a)
|
||||
|
||||
fftwf_destroy_plan(a->Rrev);
|
||||
fftwf_destroy_plan(a->Rfor);
|
||||
|
||||
delete[] (a->outaccum);
|
||||
|
||||
for (i = 0; i < a->ovrlp; i++)
|
||||
delete[] (a->save[i]);
|
||||
|
||||
delete[] (a->save);
|
||||
delete[] (a->revfftout);
|
||||
delete[] (a->revfftin);
|
||||
@ -493,7 +565,7 @@ EMNR* EMNR::create_emnr (
|
||||
int ovrlp,
|
||||
int rate,
|
||||
int wintype,
|
||||
float gain,
|
||||
double gain,
|
||||
int gain_method,
|
||||
int npe_method,
|
||||
int ae_run
|
||||
@ -522,8 +594,10 @@ void EMNR::flush_emnr (EMNR *a)
|
||||
{
|
||||
int i;
|
||||
std::fill(a->inaccum, a->inaccum + a->iasize, 0);
|
||||
|
||||
for (i = 0; i < a->ovrlp; i++)
|
||||
std::fill(a->save[i], a->save[i] + a->fsize, 0);
|
||||
|
||||
std::fill(a->outaccum, a->outaccum + a->oasize, 0);
|
||||
a->nsamps = 0;
|
||||
a->iainidx = 0;
|
||||
@ -557,30 +631,39 @@ void EMNR::LambdaD(EMNR *a)
|
||||
sum_prev_p = 0.0;
|
||||
sum_lambda_y = 0.0;
|
||||
sum_prev_sigma2N = 0.0;
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
{
|
||||
sum_prev_p += a->np.p[k];
|
||||
sum_lambda_y += a->np.lambda_y[k];
|
||||
sum_prev_sigma2N += a->np.sigma2N[k];
|
||||
}
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
{
|
||||
f0 = a->np.p[k] / a->np.sigma2N[k] - 1.0;
|
||||
a->np.alphaOptHat[k] = 1.0 / (1.0 + f0 * f0);
|
||||
}
|
||||
|
||||
SNR = sum_prev_p / sum_prev_sigma2N;
|
||||
alphaMin = std::min (a->np.alphaMin_max_value, pow (SNR, a->np.snrq));
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
if (a->np.alphaOptHat[k] < alphaMin) a->np.alphaOptHat[k] = alphaMin;
|
||||
|
||||
f1 = sum_prev_p / sum_lambda_y - 1.0;
|
||||
alphaCtilda = 1.0 / (1.0 + f1 * f1);
|
||||
a->np.alphaC = a->np.alphaCsmooth * a->np.alphaC + (1.0 - a->np.alphaCsmooth) * std::max (alphaCtilda, a->np.alphaCmin);
|
||||
f2 = a->np.alphaMax * a->np.alphaC;
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
a->np.alphaHat[k] = f2 * a->np.alphaOptHat[k];
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
a->np.p[k] = a->np.alphaHat[k] * a->np.p[k] + (1.0 - a->np.alphaHat[k]) * a->np.lambda_y[k];
|
||||
|
||||
invQbar = 0.0;
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
{
|
||||
beta = std::min (a->np.betamax, a->np.alphaHat[k] * a->np.alphaHat[k]);
|
||||
@ -592,8 +675,9 @@ void EMNR::LambdaD(EMNR *a)
|
||||
a->np.Qeq[k] = 1.0 / invQeq;
|
||||
invQbar += invQeq;
|
||||
}
|
||||
invQbar /= (float)a->np.msize;
|
||||
invQbar /= (double) a->np.msize;
|
||||
bc = 1.0 + a->np.av * sqrt (invQbar);
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
{
|
||||
QeqTilda = (a->np.Qeq[k] - 2.0 * a->np.MofD) / (1.0 - a->np.MofD);
|
||||
@ -601,10 +685,13 @@ void EMNR::LambdaD(EMNR *a)
|
||||
a->np.bmin[k] = 1.0 + 2.0 * (a->np.D - 1.0) / QeqTilda;
|
||||
a->np.bmin_sub[k] = 1.0 + 2.0 * (a->np.V - 1.0) / QeqTildaSub;
|
||||
}
|
||||
|
||||
std::fill(a->np.k_mod, a->np.k_mod + a->np.msize, 0);
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
{
|
||||
f3 = a->np.p[k] * a->np.bmin[k] * bc;
|
||||
|
||||
if (f3 < a->np.actmin[k])
|
||||
{
|
||||
a->np.actmin[k] = f3;
|
||||
@ -612,24 +699,37 @@ void EMNR::LambdaD(EMNR *a)
|
||||
a->np.k_mod[k] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (a->np.subwc == a->np.V)
|
||||
{
|
||||
if (invQbar < a->np.invQbar_points[0]) noise_slope_max = a->np.nsmax[0];
|
||||
else if (invQbar < a->np.invQbar_points[1]) noise_slope_max = a->np.nsmax[1];
|
||||
else if (invQbar < a->np.invQbar_points[2]) noise_slope_max = a->np.nsmax[2];
|
||||
else noise_slope_max = a->np.nsmax[3];
|
||||
if (invQbar < a->np.invQbar_points[0])
|
||||
noise_slope_max = a->np.nsmax[0];
|
||||
else if (invQbar < a->np.invQbar_points[1])
|
||||
noise_slope_max = a->np.nsmax[1];
|
||||
else if (invQbar < a->np.invQbar_points[2])
|
||||
noise_slope_max = a->np.nsmax[2];
|
||||
else
|
||||
noise_slope_max = a->np.nsmax[3];
|
||||
|
||||
for (k = 0; k < a->np.msize; k++)
|
||||
{
|
||||
int ku;
|
||||
float min;
|
||||
double min;
|
||||
|
||||
if (a->np.k_mod[k])
|
||||
a->np.lmin_flag[k] = 0;
|
||||
|
||||
a->np.actminbuff[a->np.amb_idx][k] = a->np.actmin[k];
|
||||
min = 1.0e300;
|
||||
min = std::numeric_limits<double>::max();;
|
||||
|
||||
for (ku = 0; ku < a->np.U; ku++)
|
||||
if (a->np.actminbuff[ku][k] < min) min = a->np.actminbuff[ku][k];
|
||||
{
|
||||
if (a->np.actminbuff[ku][k] < min)
|
||||
min = a->np.actminbuff[ku][k];
|
||||
}
|
||||
|
||||
a->np.pmin_u[k] = min;
|
||||
|
||||
if ((a->np.lmin_flag[k] == 1)
|
||||
&& (a->np.actmin_sub[k] < noise_slope_max * a->np.pmin_u[k])
|
||||
&& (a->np.actmin_sub[k] > a->np.pmin_u[k]))
|
||||
@ -638,11 +738,15 @@ void EMNR::LambdaD(EMNR *a)
|
||||
for (ku = 0; ku < a->np.U; ku++)
|
||||
a->np.actminbuff[ku][k] = a->np.actmin_sub[k];
|
||||
}
|
||||
|
||||
a->np.lmin_flag[k] = 0;
|
||||
a->np.actmin[k] = 1.0e300;
|
||||
a->np.actmin_sub[k] = 1.0e300;
|
||||
a->np.actmin[k] = std::numeric_limits<double>::max();;
|
||||
a->np.actmin_sub[k] = std::numeric_limits<double>::max();;
|
||||
}
|
||||
if (++a->np.amb_idx == a->np.U) a->np.amb_idx = 0;
|
||||
|
||||
if (++a->np.amb_idx == a->np.U)
|
||||
a->np.amb_idx = 0;
|
||||
|
||||
a->np.subwc = 1;
|
||||
}
|
||||
else
|
||||
@ -659,23 +763,29 @@ void EMNR::LambdaD(EMNR *a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++a->np.subwc;
|
||||
}
|
||||
|
||||
std::copy(a->np.sigma2N, a->np.sigma2N + a->np.msize, a->np.lambda_d);
|
||||
}
|
||||
|
||||
void EMNR::LambdaDs (EMNR *a)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < a->nps.msize; k++)
|
||||
{
|
||||
a->nps.PH1y[k] = 1.0 / (1.0 + (1.0 + a->nps.epsH1) * exp (- a->nps.epsH1r * a->nps.lambda_y[k] / a->nps.sigma2N[k]));
|
||||
a->nps.Pbar[k] = a->nps.alpha_Pbar * a->nps.Pbar[k] + (1.0 - a->nps.alpha_Pbar) * a->nps.PH1y[k];
|
||||
|
||||
if (a->nps.Pbar[k] > 0.99)
|
||||
a->nps.PH1y[k] = std::min (a->nps.PH1y[k], 0.99);
|
||||
|
||||
a->nps.EN2y[k] = (1.0 - a->nps.PH1y[k]) * a->nps.lambda_y[k] + a->nps.PH1y[k] * a->nps.sigma2N[k];
|
||||
a->nps.sigma2N[k] = a->nps.alpha_pow * a->nps.sigma2N[k] + (1.0 - a->nps.alpha_pow) * a->nps.EN2y[k];
|
||||
}
|
||||
|
||||
std::copy(a->nps.sigma2N, a->nps.sigma2N + a->nps.msize, a->nps.lambda_d);
|
||||
}
|
||||
|
||||
@ -683,24 +793,30 @@ void EMNR::aepf(EMNR *a)
|
||||
{
|
||||
int k, m;
|
||||
int N, n;
|
||||
float sumPre, sumPost, zeta, zetaT;
|
||||
double sumPre, sumPost, zeta, zetaT;
|
||||
sumPre = 0.0;
|
||||
sumPost = 0.0;
|
||||
|
||||
for (k = 0; k < a->ae.msize; k++)
|
||||
{
|
||||
sumPre += a->ae.lambda_y[k];
|
||||
sumPost += a->mask[k] * a->mask[k] * a->ae.lambda_y[k];
|
||||
}
|
||||
|
||||
zeta = sumPost / sumPre;
|
||||
|
||||
if (zeta >= a->ae.zetaThresh)
|
||||
zetaT = 1.0;
|
||||
else
|
||||
zetaT = zeta;
|
||||
|
||||
if (zetaT == 1.0)
|
||||
N = 1;
|
||||
else
|
||||
N = 1 + 2 * (int)(0.5 + a->ae.psi * (1.0 - zetaT / a->ae.zetaThresh));
|
||||
|
||||
n = N / 2;
|
||||
|
||||
for (k = n; k < (a->ae.msize - n); k++)
|
||||
{
|
||||
a->ae.nmask[k] = 0.0;
|
||||
@ -708,6 +824,7 @@ void EMNR::aepf(EMNR *a)
|
||||
a->ae.nmask[k] += a->mask[m];
|
||||
a->ae.nmask[k] /= (float)N;
|
||||
}
|
||||
|
||||
std::copy(a->ae.nmask, a->ae.nmask + (a->ae.msize - 2 * n), a->mask + n);
|
||||
}
|
||||
|
||||
@ -717,6 +834,7 @@ double EMNR::getKey(double* type, double gamma, double xi)
|
||||
double tg, tx, dg, dx;
|
||||
const double dmin = 0.001;
|
||||
const double dmax = 1000.0;
|
||||
|
||||
if (gamma <= dmin)
|
||||
{
|
||||
ngamma1 = ngamma2 = 0;
|
||||
@ -733,6 +851,7 @@ double EMNR::getKey(double* type, double gamma, double xi)
|
||||
ngamma1 = (int)(4.0 * tg);
|
||||
ngamma2 = ngamma1 + 1;
|
||||
}
|
||||
|
||||
if (xi <= dmin)
|
||||
{
|
||||
nxi1 = nxi2 = 0;
|
||||
@ -749,6 +868,7 @@ double EMNR::getKey(double* type, double gamma, double xi)
|
||||
nxi1 = (int)(4.0 * tx);
|
||||
nxi2 = nxi1 + 1;
|
||||
}
|
||||
|
||||
dg = (tg - 0.25 * ngamma1) / 0.25;
|
||||
dx = (tx - 0.25 * nxi1) / 0.25;
|
||||
return (1.0 - dg) * (1.0 - dx) * type[241 * nxi1 + ngamma1]
|
||||
@ -760,12 +880,14 @@ double EMNR::getKey(double* type, double gamma, double xi)
|
||||
void EMNR::calc_gain (EMNR *a)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < a->g.msize; k++)
|
||||
{
|
||||
double y0 = a->g.y[2 * k + 0];
|
||||
double y1 = a->g.y[2 * k + 1];
|
||||
a->g.lambda_y[k] = y0 * y0 + y1 * y1;
|
||||
}
|
||||
|
||||
switch (a->g.npe_method)
|
||||
{
|
||||
case 0:
|
||||
@ -775,11 +897,13 @@ void EMNR::calc_gain (EMNR *a)
|
||||
LambdaDs(a);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (a->g.gain_method)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
double gamma, eps_hat, v;
|
||||
|
||||
for (k = 0; k < a->msize; k++)
|
||||
{
|
||||
gamma = std::min (a->g.lambda_y[k] / a->g.lambda_d[k], a->g.gamma_max);
|
||||
@ -795,16 +919,24 @@ void EMNR::calc_gain (EMNR *a)
|
||||
double witchHat = (1.0 - a->g.q) / a->g.q * exp (v2) / (1.0 + eps);
|
||||
a->g.mask[k] *= witchHat / (1.0 + witchHat);
|
||||
}
|
||||
if (a->g.mask[k] > a->g.gmax) a->g.mask[k] = a->g.gmax;
|
||||
if (a->g.mask[k] != a->g.mask[k]) a->g.mask[k] = 0.01;
|
||||
|
||||
if (a->g.mask[k] > a->g.gmax)
|
||||
a->g.mask[k] = a->g.gmax;
|
||||
|
||||
if (a->g.mask[k] != a->g.mask[k])
|
||||
a->g.mask[k] = 0.01;
|
||||
|
||||
a->g.prev_gamma[k] = gamma;
|
||||
a->g.prev_mask[k] = a->g.mask[k];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
double gamma, eps_hat, v, ehr;
|
||||
|
||||
for (k = 0; k < a->g.msize; k++)
|
||||
{
|
||||
gamma = std::min (a->g.lambda_y[k] / a->g.lambda_d[k], a->g.gamma_max);
|
||||
@ -812,16 +944,24 @@ void EMNR::calc_gain (EMNR *a)
|
||||
+ (1.0 - a->g.alpha) * std::max (gamma - 1.0f, a->g.eps_floor);
|
||||
ehr = eps_hat / (1.0 + eps_hat);
|
||||
v = ehr * gamma;
|
||||
if((a->g.mask[k] = ehr * exp (std::min (700.0, 0.5 * e1xb(v)))) > a->g.gmax) a->g.mask[k] = a->g.gmax;
|
||||
if (a->g.mask[k] != a->g.mask[k])a->g.mask[k] = 0.01;
|
||||
|
||||
if ((a->g.mask[k] = ehr * exp (std::min (700.0, 0.5 * e1xb(v)))) > a->g.gmax)
|
||||
a->g.mask[k] = a->g.gmax;
|
||||
|
||||
if (a->g.mask[k] != a->g.mask[k])
|
||||
a->g.mask[k] = 0.01;
|
||||
|
||||
a->g.prev_gamma[k] = gamma;
|
||||
a->g.prev_mask[k] = a->g.mask[k];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
double gamma, eps_hat, eps_p;
|
||||
|
||||
for (k = 0; k < a->msize; k++)
|
||||
{
|
||||
gamma = std::min(a->g.lambda_y[k] / a->g.lambda_d[k], a->g.gamma_max);
|
||||
@ -832,10 +972,13 @@ void EMNR::calc_gain (EMNR *a)
|
||||
a->g.prev_gamma[k] = gamma;
|
||||
a->g.prev_mask[k] = a->g.mask[k];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (a->g.ae_run) aepf(a);
|
||||
|
||||
if (a->g.ae_run)
|
||||
aepf(a);
|
||||
}
|
||||
|
||||
void EMNR::xemnr (EMNR *a, int pos)
|
||||
@ -843,34 +986,43 @@ void EMNR::xemnr (EMNR *a, int pos)
|
||||
if (a->run && pos == a->position)
|
||||
{
|
||||
int i, j, k, sbuff, sbegin;
|
||||
float g1;
|
||||
double g1;
|
||||
|
||||
for (i = 0; i < 2 * a->bsize; i += 2)
|
||||
{
|
||||
a->inaccum[a->iainidx] = a->in[i];
|
||||
a->iainidx = (a->iainidx + 1) % a->iasize;
|
||||
}
|
||||
|
||||
a->nsamps += a->bsize;
|
||||
|
||||
while (a->nsamps >= a->fsize)
|
||||
{
|
||||
for (i = 0, j = a->iaoutidx; i < a->fsize; i++, j = (j + 1) % a->iasize)
|
||||
a->forfftin[i] = a->window[i] * a->inaccum[j];
|
||||
|
||||
a->iaoutidx = (a->iaoutidx + a->incr) % a->iasize;
|
||||
a->nsamps -= a->incr;
|
||||
fftwf_execute (a->Rfor);
|
||||
calc_gain(a);
|
||||
|
||||
for (i = 0; i < a->msize; i++)
|
||||
{
|
||||
g1 = a->gain * a->mask[i];
|
||||
a->revfftin[2 * i + 0] = g1 * a->forfftout[2 * i + 0];
|
||||
a->revfftin[2 * i + 1] = g1 * a->forfftout[2 * i + 1];
|
||||
}
|
||||
|
||||
fftwf_execute (a->Rrev);
|
||||
|
||||
for (i = 0; i < a->fsize; i++)
|
||||
a->save[a->saveidx][i] = a->window[i] * a->revfftout[i];
|
||||
|
||||
for (i = a->ovrlp; i > 0; i--)
|
||||
{
|
||||
sbuff = (a->saveidx + i) % a->ovrlp;
|
||||
sbegin = a->incr * (a->ovrlp - i);
|
||||
|
||||
for (j = sbegin, k = a->oainidx; j < a->incr + sbegin; j++, k = (k + 1) % a->oasize)
|
||||
{
|
||||
if ( i == a->ovrlp)
|
||||
@ -879,9 +1031,11 @@ void EMNR::xemnr (EMNR *a, int pos)
|
||||
a->outaccum[k] += a->save[sbuff][j];
|
||||
}
|
||||
}
|
||||
|
||||
a->saveidx = (a->saveidx + 1) % a->ovrlp;
|
||||
a->oainidx = (a->oainidx + a->incr) % a->oasize;
|
||||
}
|
||||
|
||||
for (i = 0; i < a->bsize; i++)
|
||||
{
|
||||
a->out[2 * i + 0] = a->outaccum[a->oaoutidx];
|
||||
@ -890,7 +1044,9 @@ void EMNR::xemnr (EMNR *a, int pos)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
{
|
||||
std::copy(a->in, a->in + a->bsize * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void EMNR::setBuffers_emnr (EMNR *a, float* in, float* out)
|
||||
|
@ -58,10 +58,10 @@ public:
|
||||
float** save;
|
||||
int oasize;
|
||||
float* outaccum;
|
||||
float rate;
|
||||
double rate;
|
||||
int wintype;
|
||||
float ogain;
|
||||
float gain;
|
||||
double ogain;
|
||||
double gain;
|
||||
int nsamps;
|
||||
int iainidx;
|
||||
int iaoutidx;
|
||||
@ -173,7 +173,7 @@ public:
|
||||
int ovrlp,
|
||||
int rate,
|
||||
int wintype,
|
||||
float gain,
|
||||
double gain,
|
||||
int gain_method,
|
||||
int npe_method,
|
||||
int ae_run
|
||||
|
@ -76,7 +76,7 @@ void EMPHP::xemphp (EMPHP *a, int position)
|
||||
if (a->run && a->position == position)
|
||||
FIRCORE::xfircore (a->p);
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void EMPHP::setBuffers_emphp (EMPHP *a, float* in, float* out)
|
||||
@ -206,7 +206,7 @@ void EMPH::destroy_emph (EMPH *a)
|
||||
|
||||
void EMPH::flush_emph (EMPH *a)
|
||||
{
|
||||
memset (a->infilt, 0, 2 * a->size * sizeof (wcomplex));
|
||||
std::fill(a->infilt, a->infilt + 2 * a->size * 2, 0);
|
||||
}
|
||||
|
||||
void EMPH::xemph (EMPH *a, int position)
|
||||
@ -215,7 +215,7 @@ void EMPH::xemph (EMPH *a, int position)
|
||||
float I, Q;
|
||||
if (a->run && a->position == position)
|
||||
{
|
||||
memcpy (&(a->infilt[2 * a->size]), a->in, a->size * sizeof (wcomplex));
|
||||
std::copy(a->in, a->in + a->size * 2, &(a->infilt[2 * a->size]));
|
||||
fftwf_execute (a->CFor);
|
||||
for (i = 0; i < 2 * a->size; i++)
|
||||
{
|
||||
@ -225,10 +225,10 @@ void EMPH::xemph (EMPH *a, int position)
|
||||
a->product[2 * i + 1] = I * a->mults[2 * i + 1] + Q * a->mults[2 * i + 0];
|
||||
}
|
||||
fftwf_execute (a->CRev);
|
||||
memcpy (a->infilt, &(a->infilt[2 * a->size]), a->size * sizeof(wcomplex));
|
||||
std::copy(&(a->infilt[2 * a->size]), &(a->infilt[2 * a->size]) + a->size * 2, a->infilt);
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void EMPH::setBuffers_emph (EMPH *a, float* in, float* out)
|
||||
|
79
wdsp/eq.cpp
79
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,38 +106,46 @@ 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-100) lowmag = 1.0e-100;
|
||||
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-100) highmag = 1.0e-100;
|
||||
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-100) lowmag = 1.0e-100;
|
||||
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-100) highmag = 1.0e-100;
|
||||
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);
|
||||
@ -225,7 +252,7 @@ void EQP::xeqp (EQP *a)
|
||||
if (a->run)
|
||||
FIRCORE::xfircore (a->p);
|
||||
else
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void EQP::setBuffers_eqp (EQP *a, float* in, float* out)
|
||||
@ -579,7 +606,7 @@ void EQ::destroy_eq (EQ *a)
|
||||
|
||||
void EQ::flush_eq (EQ *a)
|
||||
{
|
||||
memset (a->infilt, 0, 2 * a->size * sizeof (wcomplex));
|
||||
std::fill(a->infilt, a->infilt + 2 * a->size * 2, 0);
|
||||
}
|
||||
|
||||
void EQ::xeq (EQ *a)
|
||||
@ -588,7 +615,7 @@ void EQ::xeq (EQ *a)
|
||||
float I, Q;
|
||||
if (a->run)
|
||||
{
|
||||
memcpy (&(a->infilt[2 * a->size]), a->in, a->size * sizeof (wcomplex));
|
||||
std::copy(a->in, a->in + a->size * 2, &(a->infilt[2 * a->size]));
|
||||
fftwf_execute (a->CFor);
|
||||
for (i = 0; i < 2 * a->size; i++)
|
||||
{
|
||||
@ -598,10 +625,10 @@ void EQ::xeq (EQ *a)
|
||||
a->product[2 * i + 1] = I * a->mults[2 * i + 1] + Q * a->mults[2 * i + 0];
|
||||
}
|
||||
fftwf_execute (a->CRev);
|
||||
memcpy (a->infilt, &(a->infilt[2 * a->size]), a->size * sizeof(wcomplex));
|
||||
std::copy(&(a->infilt[2 * a->size]), &(a->infilt[2 * a->size]) + a->size * 2, a->infilt);
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void EQ::setBuffers_eq (EQ *a, float* in, float* out)
|
||||
|
@ -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);
|
||||
|
@ -102,7 +102,7 @@ float* FCurve::fc_impulse (int nc, float f0, float f1, float g0, float, int curv
|
||||
{
|
||||
f = (float)k / (float)mid;
|
||||
lowmag *= (f * f * f * f) / flow4;
|
||||
if (lowmag < 1.0e-100) lowmag = 1.0e-100;
|
||||
if (lowmag < 1.0e-20) lowmag = 1.0e-20;
|
||||
A[k] = lowmag;
|
||||
}
|
||||
k = high;
|
||||
@ -110,7 +110,7 @@ float* FCurve::fc_impulse (int nc, float f0, float f1, float g0, float, int curv
|
||||
{
|
||||
f = (float)k / (float)mid;
|
||||
highmag *= fhigh4 / (f * f * f * f);
|
||||
if (highmag < 1.0e-100) highmag = 1.0e-100;
|
||||
if (highmag < 1.0e-20) highmag = 1.0e-20;
|
||||
A[k] = highmag;
|
||||
}
|
||||
}
|
||||
@ -127,7 +127,7 @@ float* FCurve::fc_impulse (int nc, float f0, float f1, float g0, float, int curv
|
||||
{
|
||||
f = (float)k / (float)mid;
|
||||
lowmag *= (f * f * f * f) / flow4;
|
||||
if (lowmag < 1.0e-100) lowmag = 1.0e-100;
|
||||
if (lowmag < 1.0e-20) lowmag = 1.0e-20;
|
||||
A[k] = lowmag;
|
||||
}
|
||||
k = high;
|
||||
@ -135,7 +135,7 @@ float* FCurve::fc_impulse (int nc, float f0, float f1, float g0, float, int curv
|
||||
{
|
||||
f = (float)k / (float)mid;
|
||||
highmag *= fhigh4 / (f * f * f * f);
|
||||
if (highmag < 1.0e-100) highmag = 1.0e-100;
|
||||
if (highmag < 1.0e-20) highmag = 1.0e-20;
|
||||
A[k] = highmag;
|
||||
}
|
||||
}
|
||||
|
143
wdsp/fir.cpp
143
wdsp/fir.cpp
@ -25,6 +25,9 @@ warren@pratt.one
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "fftw3.h"
|
||||
#include "comm.hpp"
|
||||
#include "fir.hpp"
|
||||
@ -33,13 +36,18 @@ namespace WDSP {
|
||||
|
||||
float* FIR::fftcv_mults (int NM, float* c_impulse)
|
||||
{
|
||||
float* mults = new float[NM * 2]; // (float *) malloc0 (NM * sizeof (wcomplex));
|
||||
float* cfft_impulse = new float[NM * 2]; // (float *) malloc0 (NM * sizeof (wcomplex));
|
||||
fftwf_plan ptmp = fftwf_plan_dft_1d(NM, (fftwf_complex *) cfft_impulse,
|
||||
(fftwf_complex *) mults, FFTW_FORWARD, FFTW_PATIENT);
|
||||
memset (cfft_impulse, 0, NM * sizeof (wcomplex));
|
||||
float* mults = new float[NM * 2];
|
||||
float* cfft_impulse = new float[NM * 2];
|
||||
fftwf_plan ptmp = fftwf_plan_dft_1d(
|
||||
NM,
|
||||
(fftwf_complex *) cfft_impulse,
|
||||
(fftwf_complex *) mults,
|
||||
FFTW_FORWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
std::fill(cfft_impulse, cfft_impulse + NM * 2, 0);
|
||||
// store complex coefs right-justified in the buffer
|
||||
memcpy (&(cfft_impulse[NM - 2]), c_impulse, (NM / 2 + 1) * sizeof(wcomplex));
|
||||
std::copy(c_impulse, c_impulse + (NM / 2 + 1) * 2, &(cfft_impulse[NM - 2]));
|
||||
fftwf_execute (ptmp);
|
||||
fftwf_destroy_plan (ptmp);
|
||||
delete[] cfft_impulse;
|
||||
@ -49,15 +57,15 @@ float* FIR::fftcv_mults (int NM, float* c_impulse)
|
||||
float* FIR::get_fsamp_window(int N, int wintype)
|
||||
{
|
||||
int i;
|
||||
float arg0, arg1;
|
||||
double arg0, arg1;
|
||||
float* window = new float[N]; // (float *) malloc0 (N * sizeof(float));
|
||||
switch (wintype)
|
||||
{
|
||||
case 0:
|
||||
arg0 = 2.0 * PI / ((float)N - 1.0);
|
||||
arg0 = 2.0 * PI / ((double)N - 1.0);
|
||||
for (i = 0; i < N; i++)
|
||||
{
|
||||
arg1 = cos(arg0 * (float)i);
|
||||
arg1 = cos(arg0 * (double)i);
|
||||
window[i] = +0.21747
|
||||
+ arg1 * (-0.45325
|
||||
+ arg1 * (+0.28256
|
||||
@ -65,10 +73,10 @@ float* FIR::get_fsamp_window(int N, int wintype)
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
arg0 = 2.0 * PI / ((float)N - 1.0);
|
||||
arg0 = 2.0 * PI / ((double)N - 1.0);
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
arg1 = cos(arg0 * (float)i);
|
||||
arg1 = cos(arg0 * (double)i);
|
||||
window[i] = +6.3964424114390378e-02
|
||||
+ arg1 * (-2.3993864599352804e-01
|
||||
+ arg1 * (+3.5015956323820469e-01
|
||||
@ -85,20 +93,26 @@ float* FIR::get_fsamp_window(int N, int wintype)
|
||||
return window;
|
||||
}
|
||||
|
||||
float* FIR::fir_fsamp_odd (int N, float* A, int rtype, float scale, int wintype)
|
||||
float* FIR::fir_fsamp_odd (int N, float* A, int rtype, double scale, int wintype)
|
||||
{
|
||||
int i, j;
|
||||
int mid = (N - 1) / 2;
|
||||
float mag, phs;
|
||||
double mag, phs;
|
||||
float* window;
|
||||
float *fcoef = new float[N * 2]; // (float *) malloc0 (N * sizeof (wcomplex));
|
||||
float *c_impulse = new float[N * 2]; // (float *) malloc0 (N * sizeof (wcomplex));
|
||||
fftwf_plan ptmp = fftwf_plan_dft_1d(N, (fftwf_complex *)fcoef, (fftwf_complex *)c_impulse, FFTW_BACKWARD, FFTW_PATIENT);
|
||||
float local_scale = 1.0 / (float)N;
|
||||
float *fcoef = new float[N * 2];
|
||||
float *c_impulse = new float[N * 2];
|
||||
fftwf_plan ptmp = fftwf_plan_dft_1d(
|
||||
N,
|
||||
(fftwf_complex *)fcoef,
|
||||
(fftwf_complex *)c_impulse,
|
||||
FFTW_BACKWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
double local_scale = 1.0 / (double) N;
|
||||
for (i = 0; i <= mid; i++)
|
||||
{
|
||||
mag = A[i] * local_scale;
|
||||
phs = - (float)mid * TWOPI * (float)i / (float)N;
|
||||
phs = - (double)mid * TWOPI * (double)i / (double)N;
|
||||
fcoef[2 * i + 0] = mag * cos (phs);
|
||||
fcoef[2 * i + 1] = mag * sin (phs);
|
||||
}
|
||||
@ -129,10 +143,10 @@ float* FIR::fir_fsamp_odd (int N, float* A, int rtype, float scale, int wintype)
|
||||
return c_impulse;
|
||||
}
|
||||
|
||||
float* FIR::fir_fsamp (int N, float* A, int rtype, float scale, int wintype)
|
||||
float* FIR::fir_fsamp (int N, float* A, int rtype, double scale, int wintype)
|
||||
{
|
||||
int n, i, j, k;
|
||||
float sum;
|
||||
double sum;
|
||||
float* window;
|
||||
float *c_impulse = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
|
||||
|
||||
@ -155,7 +169,7 @@ float* FIR::fir_fsamp (int N, float* A, int rtype, float scale, int wintype)
|
||||
}
|
||||
else
|
||||
{
|
||||
float M = (float)(N - 1) / 2.0;
|
||||
double M = (double)(N - 1) / 2.0;
|
||||
for (n = 0; n < N / 2; n++)
|
||||
{
|
||||
sum = 0.0;
|
||||
@ -189,18 +203,18 @@ float* FIR::fir_fsamp (int N, float* A, int rtype, float scale, int wintype)
|
||||
return c_impulse;
|
||||
}
|
||||
|
||||
float* FIR::fir_bandpass (int N, float f_low, float f_high, float samplerate, int wintype, int rtype, float scale)
|
||||
float* FIR::fir_bandpass (int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale)
|
||||
{
|
||||
float *c_impulse = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
|
||||
float ft = (f_high - f_low) / (2.0 * samplerate);
|
||||
float ft_rad = TWOPI * ft;
|
||||
float w_osc = PI * (f_high + f_low) / samplerate;
|
||||
double ft = (f_high - f_low) / (2.0 * samplerate);
|
||||
double ft_rad = TWOPI * ft;
|
||||
double w_osc = PI * (f_high + f_low) / samplerate;
|
||||
int i, j;
|
||||
float m = 0.5 * (float)(N - 1);
|
||||
float delta = PI / m;
|
||||
float cosphi;
|
||||
float posi, posj;
|
||||
float sinc, window, coef;
|
||||
double m = 0.5 * (double)(N - 1);
|
||||
double delta = PI / m;
|
||||
double cosphi;
|
||||
double posi, posj;
|
||||
double sinc, window, coef;
|
||||
|
||||
if (N & 1)
|
||||
{
|
||||
@ -217,8 +231,8 @@ float* FIR::fir_bandpass (int N, float f_low, float f_high, float samplerate, in
|
||||
}
|
||||
for (i = (N + 1) / 2, j = N / 2 - 1; i < N; i++, j--)
|
||||
{
|
||||
posi = (float)i - m;
|
||||
posj = (float)j - m;
|
||||
posi = (double)i - m;
|
||||
posj = (double)j - m;
|
||||
sinc = sin (ft_rad * posi) / (PI * posi);
|
||||
switch (wintype)
|
||||
{
|
||||
@ -304,13 +318,23 @@ 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, (fftwf_complex *) in,
|
||||
(fftwf_complex *) x, FFTW_FORWARD, FFTW_PATIENT);
|
||||
fftwf_plan prev = fftwf_plan_dft_1d (N, (fftwf_complex *) x,
|
||||
(fftwf_complex *) out, FFTW_BACKWARD, FFTW_PATIENT);
|
||||
fftwf_plan pfor = fftwf_plan_dft_1d (
|
||||
N,
|
||||
(fftwf_complex *) in,
|
||||
(fftwf_complex *) x,
|
||||
FFTW_FORWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
fftwf_plan prev = fftwf_plan_dft_1d (
|
||||
N,
|
||||
(fftwf_complex *) x,
|
||||
(fftwf_complex *) out,
|
||||
FFTW_BACKWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
fftwf_execute (pfor);
|
||||
x[0] *= inv_N;
|
||||
x[1] *= inv_N;
|
||||
@ -332,27 +356,38 @@ void FIR::mp_imp (int N, float* fir, float* mpfir, int pfactor, int polarity)
|
||||
{
|
||||
int i;
|
||||
int size = N * pfactor;
|
||||
float inv_PN = 1.0 / (float)size;
|
||||
float* firpad = new float[size * 2]; // (float *) malloc0 (size * sizeof (complex));
|
||||
float* firfreq = new float[size * 2]; // (float *) malloc0 (size * sizeof (complex));
|
||||
float* mag = new float[size]; // (float *) malloc0 (size * sizeof (float));
|
||||
float* ana = new float[size * 2]; // (float *) malloc0 (size * sizeof (complex));
|
||||
float* impulse = new float[size * 2]; // (float *) malloc0 (size * sizeof (complex));
|
||||
float* newfreq = new float[size * 2]; // (float *) malloc0 (size * sizeof (complex));
|
||||
memcpy (firpad, fir, N * sizeof (wcomplex));
|
||||
fftwf_plan pfor = fftwf_plan_dft_1d (size, (fftwf_complex *) firpad,
|
||||
(fftwf_complex *) firfreq, FFTW_FORWARD, FFTW_PATIENT);
|
||||
fftwf_plan prev = fftwf_plan_dft_1d (size, (fftwf_complex *) newfreq,
|
||||
(fftwf_complex *) impulse, FFTW_BACKWARD, FFTW_PATIENT);
|
||||
double inv_PN = 1.0 / (float)size;
|
||||
float* firpad = new float[size * 2]; // (float *) malloc0 (size * sizeof (complex));
|
||||
float* firfreq = new float[size * 2]; // (float *) malloc0 (size * sizeof (complex));
|
||||
double* mag = new double[size]; // (float *) malloc0 (size * sizeof (float));
|
||||
float* ana = new float[size * 2]; // (float *) malloc0 (size * sizeof (complex));
|
||||
float* impulse = new float[size * 2]; // (float *) malloc0 (size * sizeof (complex));
|
||||
float* newfreq = new float[size * 2]; // (float *) malloc0 (size * sizeof (complex));
|
||||
std::copy(fir, fir + N * 2, firpad);
|
||||
fftwf_plan pfor = fftwf_plan_dft_1d (
|
||||
size,
|
||||
(fftwf_complex *) firpad,
|
||||
(fftwf_complex *) firfreq,
|
||||
FFTW_FORWARD,
|
||||
FFTW_PATIENT);
|
||||
fftwf_plan prev = fftwf_plan_dft_1d (
|
||||
size,
|
||||
(fftwf_complex *) newfreq,
|
||||
(fftwf_complex *) impulse,
|
||||
FFTW_BACKWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
// print_impulse("orig_imp.txt", N, fir, 1, 0);
|
||||
fftwf_execute (pfor);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
mag[i] = sqrt (firfreq[2 * i + 0] * firfreq[2 * i + 0] + firfreq[2 * i + 1] * firfreq[2 * i + 1]) * inv_PN;
|
||||
double xr = firfreq[2 * i + 0];
|
||||
double xi = firfreq[2 * i + 1];
|
||||
mag[i] = sqrt (xr*xr + xi*xi) * inv_PN;
|
||||
if (mag[i] > 0.0)
|
||||
ana[2 * i + 0] = log (mag[i]);
|
||||
else
|
||||
ana[2 * i + 0] = log (1.0e-300);
|
||||
ana[2 * i + 0] = log (std::numeric_limits<float>::min());
|
||||
}
|
||||
analytic (size, ana, ana);
|
||||
for (i = 0; i < size; i++)
|
||||
@ -365,9 +400,9 @@ void FIR::mp_imp (int N, float* fir, float* mpfir, int pfactor, int polarity)
|
||||
}
|
||||
fftwf_execute (prev);
|
||||
if (polarity)
|
||||
memcpy (mpfir, &impulse[2 * (pfactor - 1) * N], N * sizeof (wcomplex));
|
||||
std::copy(&impulse[2 * (pfactor - 1) * N], &impulse[2 * (pfactor - 1) * N] + N * 2, mpfir);
|
||||
else
|
||||
memcpy (mpfir, impulse, N * sizeof (wcomplex));
|
||||
std::copy(impulse, impulse + N * 2, mpfir);
|
||||
// print_impulse("min_imp.txt", N, mpfir, 1, 0);
|
||||
fftwf_destroy_plan (prev);
|
||||
fftwf_destroy_plan (pfor);
|
||||
|
12
wdsp/fir.hpp
12
wdsp/fir.hpp
@ -35,16 +35,16 @@ class WDSP_API FIR
|
||||
{
|
||||
public:
|
||||
static float* fftcv_mults (int NM, float* c_impulse);
|
||||
static float* fir_fsamp_odd (int N, float* A, int rtype, float scale, int wintype);
|
||||
static float* fir_fsamp (int N, float* A, int rtype, float scale, int wintype);
|
||||
static float* fir_bandpass (int N, float f_low, float f_high, float samplerate, int wintype, int rtype, float scale);
|
||||
static float* get_fsamp_window(int N, int wintype);
|
||||
static float *fir_read (int N, const char *filename, int rtype, float scale);
|
||||
static float* fir_fsamp_odd (int N, float* A, int rtype, double scale, int wintype);
|
||||
static float* fir_fsamp (int N, float* A, int rtype, double scale, int wintype);
|
||||
static float* fir_bandpass (int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale);
|
||||
static void mp_imp (int N, float* fir, float* mpfir, int pfactor, int polarity);
|
||||
static float* zff_impulse(int nc, float scale);
|
||||
|
||||
private:
|
||||
static void analytic (int N, float* in, float* out);
|
||||
static float* get_fsamp_window(int N, int wintype);
|
||||
static float *fir_read (int N, const char *filename, int rtype, float scale);
|
||||
static float* zff_impulse(int nc, float scale);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -61,12 +61,36 @@ void FIRCORE::plan_fircore (FIRCORE *a)
|
||||
a->fftout[i] = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
|
||||
a->fmask[0][i] = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
|
||||
a->fmask[1][i] = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
|
||||
a->pcfor[i] = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->fftin, (fftwf_complex *)a->fftout[i], FFTW_FORWARD, FFTW_PATIENT);
|
||||
a->maskplan[0][i] = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->maskgen, (fftwf_complex *)a->fmask[0][i], FFTW_FORWARD, FFTW_PATIENT);
|
||||
a->maskplan[1][i] = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->maskgen, (fftwf_complex *)a->fmask[1][i], FFTW_FORWARD, FFTW_PATIENT);
|
||||
a->pcfor[i] = fftwf_plan_dft_1d(
|
||||
2 * a->size,
|
||||
(fftwf_complex *)a->fftin,
|
||||
(fftwf_complex *)a->fftout[i],
|
||||
FFTW_FORWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
a->maskplan[0][i] = fftwf_plan_dft_1d(
|
||||
2 * a->size,
|
||||
(fftwf_complex *)a->maskgen,
|
||||
(fftwf_complex *)a->fmask[0][i],
|
||||
FFTW_FORWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
a->maskplan[1][i] = fftwf_plan_dft_1d(
|
||||
2 * a->size,
|
||||
(fftwf_complex *)a->maskgen,
|
||||
(fftwf_complex *)a->fmask[1][i],
|
||||
FFTW_FORWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
}
|
||||
a->accum = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
|
||||
a->crev = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->accum, (fftwf_complex *)a->out, FFTW_BACKWARD, FFTW_PATIENT);
|
||||
a->crev = fftwf_plan_dft_1d(
|
||||
2 * a->size,
|
||||
(fftwf_complex *)a->accum,
|
||||
(fftwf_complex *)a->out,
|
||||
FFTW_BACKWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
a->masks_ready = 0;
|
||||
}
|
||||
|
||||
@ -79,13 +103,13 @@ void FIRCORE::calc_fircore (FIRCORE *a, int flip)
|
||||
if (a->mp)
|
||||
FIR::mp_imp (a->nc, a->impulse, a->imp, 16, 0);
|
||||
else
|
||||
memcpy (a->imp, a->impulse, a->nc * sizeof (wcomplex));
|
||||
std::copy(a->impulse, a->impulse + a->nc * 2, a->imp);
|
||||
|
||||
for (i = 0; i < a->nfor; i++)
|
||||
{
|
||||
// I right-justified the impulse response => take output from left side of output buff, discard right side
|
||||
// Be careful about flipping an asymmetrical impulse response.
|
||||
memcpy (&(a->maskgen[2 * a->size]), &(a->imp[2 * a->size * i]), a->size * sizeof(wcomplex));
|
||||
std::copy(&(a->imp[2 * a->size * i]), &(a->imp[2 * a->size * i]) + a->size * 2, &(a->maskgen[2 * a->size]));
|
||||
fftwf_execute (a->maskplan[1 - a->cset][i]);
|
||||
}
|
||||
|
||||
@ -110,7 +134,7 @@ FIRCORE* FIRCORE::create_fircore (int size, float* in, float* out, int nc, int m
|
||||
plan_fircore (a);
|
||||
a->impulse = new float[a->nc * 2]; // (float *) malloc0 (a->nc * sizeof (complex));
|
||||
a->imp = new float[a->nc * 2]; // (float *) malloc0 (a->nc * sizeof (complex));
|
||||
memcpy (a->impulse, impulse, a->nc * sizeof (wcomplex));
|
||||
std::copy(impulse, impulse + a->nc * 2, a->impulse);
|
||||
calc_fircore (a, 1);
|
||||
return a;
|
||||
}
|
||||
@ -152,19 +176,19 @@ void FIRCORE::destroy_fircore (FIRCORE *a)
|
||||
void FIRCORE::flush_fircore (FIRCORE *a)
|
||||
{
|
||||
int i;
|
||||
memset (a->fftin, 0, 2 * a->size * sizeof (wcomplex));
|
||||
std::fill(a->fftin, a->fftin + 2 * a->size * 2, 0);
|
||||
for (i = 0; i < a->nfor; i++)
|
||||
memset (a->fftout[i], 0, 2 * a->size * sizeof (wcomplex));
|
||||
std::fill(a->fftout[i], a->fftout[i] + 2 * a->size * 2, 0);
|
||||
a->buffidx = 0;
|
||||
}
|
||||
|
||||
void FIRCORE::xfircore (FIRCORE *a)
|
||||
{
|
||||
int i, j, k;
|
||||
memcpy (&(a->fftin[2 * a->size]), a->in, a->size * sizeof (wcomplex));
|
||||
std::copy(a->in, a->in + a->size * 2, &(a->fftin[2 * a->size]));
|
||||
fftwf_execute (a->pcfor[a->buffidx]);
|
||||
k = a->buffidx;
|
||||
memset (a->accum, 0, 2 * a->size * sizeof (wcomplex));
|
||||
std::fill(a->accum, a->accum + 2 * a->size * 2, 0);
|
||||
|
||||
for (j = 0; j < a->nfor; j++)
|
||||
{
|
||||
@ -179,7 +203,7 @@ void FIRCORE::xfircore (FIRCORE *a)
|
||||
|
||||
a->buffidx = (a->buffidx + 1) & a->idxmask;
|
||||
fftwf_execute (a->crev);
|
||||
memcpy (a->fftin, &(a->fftin[2 * a->size]), a->size * sizeof(wcomplex));
|
||||
std::copy(&(a->fftin[2 * a->size]), &(a->fftin[2 * a->size]) + a->size * 2, a->fftin);
|
||||
}
|
||||
|
||||
void FIRCORE::setBuffers_fircore (FIRCORE *a, float* in, float* out)
|
||||
@ -201,7 +225,7 @@ void FIRCORE::setSize_fircore (FIRCORE *a, int size)
|
||||
|
||||
void FIRCORE::setImpulse_fircore (FIRCORE *a, float* impulse, int update)
|
||||
{
|
||||
memcpy (a->impulse, impulse, a->nc * sizeof (wcomplex));
|
||||
std::copy(impulse, impulse + a->nc * 2, a->impulse);
|
||||
calc_fircore (a, update);
|
||||
}
|
||||
|
||||
@ -215,7 +239,7 @@ void FIRCORE::setNc_fircore (FIRCORE *a, int nc, float* impulse)
|
||||
plan_fircore (a);
|
||||
a->imp = new float[a->nc * 2]; // (float *) malloc0 (a->nc * sizeof (complex));
|
||||
a->impulse = new float[a->nc * 2]; // (float *) malloc0 (a->nc * sizeof (complex));
|
||||
memcpy (a->impulse, impulse, a->nc * sizeof (wcomplex));
|
||||
std::copy(impulse, impulse + a->nc * 2, a->impulse);
|
||||
calc_fircore (a, 1);
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ void FIRMIN::destroy_firmin (FIRMIN *a)
|
||||
|
||||
void FIRMIN::flush_firmin (FIRMIN *a)
|
||||
{
|
||||
memset (a->ring, 0, a->rsize * sizeof (wcomplex));
|
||||
std::fill(a->ring, a->ring + a->rsize * 2, 0);
|
||||
a->idx = 0;
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ void FIRMIN::xfirmin (FIRMIN *a, int pos)
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void FIRMIN::setBuffers_firmin (FIRMIN *a, float* in, float* out)
|
||||
|
@ -54,11 +54,29 @@ void FIROPT::plan_firopt (FIROPT *a)
|
||||
{
|
||||
a->fftout[i] = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
|
||||
a->fmask[i] = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
|
||||
a->pcfor[i] = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->fftin, (fftwf_complex *)a->fftout[i], FFTW_FORWARD, FFTW_PATIENT);
|
||||
a->maskplan[i] = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->maskgen, (fftwf_complex *)a->fmask[i], FFTW_FORWARD, FFTW_PATIENT);
|
||||
a->pcfor[i] = fftwf_plan_dft_1d(
|
||||
2 * a->size,
|
||||
(fftwf_complex *)a->fftin,
|
||||
(fftwf_complex *)a->fftout[i],
|
||||
FFTW_FORWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
a->maskplan[i] = fftwf_plan_dft_1d(
|
||||
2 * a->size,
|
||||
(fftwf_complex *)a->maskgen,
|
||||
(fftwf_complex *)a->fmask[i],
|
||||
FFTW_FORWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
}
|
||||
a->accum = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
|
||||
a->crev = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->accum, (fftwf_complex *)a->out, FFTW_BACKWARD, FFTW_PATIENT);
|
||||
a->crev = fftwf_plan_dft_1d(
|
||||
2 * a->size,
|
||||
(fftwf_complex *)a->accum,
|
||||
(fftwf_complex *)a->out,
|
||||
FFTW_BACKWARD,
|
||||
FFTW_PATIENT
|
||||
);
|
||||
}
|
||||
|
||||
void FIROPT::calc_firopt (FIROPT *a)
|
||||
@ -72,7 +90,7 @@ void FIROPT::calc_firopt (FIROPT *a)
|
||||
{
|
||||
// I right-justified the impulse response => take output from left side of output buff, discard right side
|
||||
// Be careful about flipping an asymmetrical impulse response.
|
||||
memcpy (&(a->maskgen[2 * a->size]), &(impulse[2 * a->size * i]), a->size * sizeof(wcomplex));
|
||||
std::copy(&(impulse[2 * a->size * i]), &(impulse[2 * a->size * i]) + a->size * 2, &(a->maskgen[2 * a->size]));
|
||||
fftwf_execute (a->maskplan[i]);
|
||||
}
|
||||
delete[] (impulse);
|
||||
@ -127,9 +145,9 @@ void FIROPT::destroy_firopt (FIROPT *a)
|
||||
void FIROPT::flush_firopt (FIROPT *a)
|
||||
{
|
||||
int i;
|
||||
memset (a->fftin, 0, 2 * a->size * sizeof (wcomplex));
|
||||
std::fill(a->fftin, a->fftin + 2 * a->size * 2, 0);
|
||||
for (i = 0; i < a->nfor; i++)
|
||||
memset (a->fftout[i], 0, 2 * a->size * sizeof (wcomplex));
|
||||
std::fill(a->fftout[i], a->fftout[i] + 2 * a->size * 2, 0);
|
||||
a->buffidx = 0;
|
||||
}
|
||||
|
||||
@ -138,10 +156,10 @@ void FIROPT::xfiropt (FIROPT *a, int pos)
|
||||
if (a->run && (a->position == pos))
|
||||
{
|
||||
int i, j, k;
|
||||
memcpy (&(a->fftin[2 * a->size]), a->in, a->size * sizeof (wcomplex));
|
||||
std::copy(a->in, a->in + a->size * 2, &(a->fftin[2 * a->size]));
|
||||
fftwf_execute (a->pcfor[a->buffidx]);
|
||||
k = a->buffidx;
|
||||
memset (a->accum, 0, 2 * a->size * sizeof (wcomplex));
|
||||
std::fill(a->accum, a->accum + 2 * a->size * 2, 0);
|
||||
for (j = 0; j < a->nfor; j++)
|
||||
{
|
||||
for (i = 0; i < 2 * a->size; i++)
|
||||
@ -153,10 +171,10 @@ void FIROPT::xfiropt (FIROPT *a, int pos)
|
||||
}
|
||||
a->buffidx = (a->buffidx + 1) & a->idxmask;
|
||||
fftwf_execute (a->crev);
|
||||
memcpy (a->fftin, &(a->fftin[2 * a->size]), a->size * sizeof(wcomplex));
|
||||
std::copy(&(a->fftin[2 * a->size]), &(a->fftin[2 * a->size]) + a->size * 2, a->fftin);
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void FIROPT::setBuffers_firopt (FIROPT *a, float* in, float* out)
|
||||
|
@ -160,7 +160,7 @@ void FMD::destroy_fmd (FMD *a)
|
||||
|
||||
void FMD::flush_fmd (FMD *a)
|
||||
{
|
||||
memset (a->audio, 0, a->size * sizeof (wcomplex));
|
||||
std::fill(a->audio, a->audio + a->size * 2, 0);
|
||||
FIRCORE::flush_fircore (a->pde);
|
||||
FIRCORE::flush_fircore (a->paud);
|
||||
a->phs = 0.0;
|
||||
@ -214,7 +214,7 @@ void FMD::xfmd (FMD *a)
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void FMD::setBuffers_fmd (FMD *a, float* in, float* out)
|
||||
|
@ -127,7 +127,7 @@ void FMMOD::xfmmod (FMMOD *a)
|
||||
FIRCORE::xfircore (a->p);
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void FMMOD::setBuffers_fmmod (FMMOD *a, float* in, float* out)
|
||||
|
@ -35,7 +35,7 @@ namespace WDSP {
|
||||
|
||||
void FMSQ::calc_fmsq (FMSQ *a)
|
||||
{
|
||||
float delta, theta;
|
||||
double delta, theta;
|
||||
float* impulse;
|
||||
int i;
|
||||
// noise filter
|
||||
@ -61,17 +61,20 @@ void FMSQ::calc_fmsq (FMSQ *a)
|
||||
// level change
|
||||
a->ntup = (int)(a->tup * a->rate);
|
||||
a->ntdown = (int)(a->tdown * a->rate);
|
||||
a->cup = new float[a->ntup + 1]; // (float *)malloc0 ((a->ntup + 1) * sizeof(float));
|
||||
a->cdown = new float[a->ntdown + 1]; //(float *)malloc0 ((a->ntdown + 1) * sizeof(float));
|
||||
delta = PI / (float)a->ntup;
|
||||
a->cup = new double[a->ntup + 1]; // (float *)malloc0 ((a->ntup + 1) * sizeof(float));
|
||||
a->cdown = new double[a->ntdown + 1]; //(float *)malloc0 ((a->ntdown + 1) * sizeof(float));
|
||||
delta = PI / (double) a->ntup;
|
||||
theta = 0.0;
|
||||
|
||||
for (i = 0; i <= a->ntup; i++)
|
||||
{
|
||||
a->cup[i] = 0.5 * (1.0 - cos(theta));
|
||||
theta += delta;
|
||||
}
|
||||
delta = PI / (float)a->ntdown;
|
||||
|
||||
delta = PI / (double) a->ntdown;
|
||||
theta = 0.0;
|
||||
|
||||
for (i = 0; i <= a->ntdown; i++)
|
||||
{
|
||||
a->cdown[i] = 0.5 * (1 + cos(theta));
|
||||
@ -170,6 +173,7 @@ void FMSQ::xfmsq (FMSQ *a)
|
||||
int i;
|
||||
double noise, lnlimit;
|
||||
FIRCORE::xfircore (a->p);
|
||||
|
||||
for (i = 0; i < a->size; i++)
|
||||
{
|
||||
double noise0 = a->noise[2 * i + 0];
|
||||
@ -177,8 +181,12 @@ void FMSQ::xfmsq (FMSQ *a)
|
||||
noise = sqrt(noise0 * noise0 + noise1 * noise1);
|
||||
a->avnoise = a->avm * a->avnoise + a->onem_avm * noise;
|
||||
a->longnoise = a->longavm * a->longnoise + a->onem_longavm * noise;
|
||||
if (!a->ready) a->ramp += a->rstep;
|
||||
if (a->ramp >= a->tdelay) a->ready = 1;
|
||||
|
||||
if (!a->ready)
|
||||
a->ramp += a->rstep;
|
||||
|
||||
if (a->ramp >= a->tdelay)
|
||||
a->ready = 1;
|
||||
|
||||
switch (a->state)
|
||||
{
|
||||
@ -188,47 +196,68 @@ void FMSQ::xfmsq (FMSQ *a)
|
||||
a->state = INCREASE;
|
||||
a->count = a->ntup;
|
||||
}
|
||||
|
||||
a->outsig[2 * i + 0] = 0.0;
|
||||
a->outsig[2 * i + 1] = 0.0;
|
||||
|
||||
break;
|
||||
|
||||
case INCREASE:
|
||||
a->outsig[2 * i + 0] = a->insig[2 * i + 0] * a->cup[a->ntup - a->count];
|
||||
a->outsig[2 * i + 1] = a->insig[2 * i + 1] * a->cup[a->ntup - a->count];
|
||||
|
||||
if (a->count-- == 0)
|
||||
a->state = UNMUTED;
|
||||
|
||||
break;
|
||||
|
||||
case UNMUTED:
|
||||
if (a->avnoise > a->tail_thresh)
|
||||
{
|
||||
a->state = TAIL;
|
||||
if ((lnlimit = a->longnoise) > 1.0) lnlimit = 1.0;
|
||||
|
||||
if ((lnlimit = a->longnoise) > 1.0)
|
||||
lnlimit = 1.0;
|
||||
|
||||
a->count = (int)((a->min_tail + (a->max_tail - a->min_tail) * lnlimit) * a->rate);
|
||||
}
|
||||
|
||||
a->outsig[2 * i + 0] = a->insig[2 * i + 0];
|
||||
a->outsig[2 * i + 1] = a->insig[2 * i + 1];
|
||||
|
||||
break;
|
||||
|
||||
case TAIL:
|
||||
a->outsig[2 * i + 0] = a->insig[2 * i + 0];
|
||||
a->outsig[2 * i + 1] = a->insig[2 * i + 1];
|
||||
|
||||
if (a->avnoise < a->unmute_thresh)
|
||||
{
|
||||
a->state = UNMUTED;
|
||||
}
|
||||
else if (a->count-- == 0)
|
||||
{
|
||||
a->state = DECREASE;
|
||||
a->count = a->ntdown;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DECREASE:
|
||||
a->outsig[2 * i + 0] = a->insig[2 * i + 0] * a->cdown[a->ntdown - a->count];
|
||||
a->outsig[2 * i + 1] = a->insig[2 * i + 1] * a->cdown[a->ntdown - a->count];
|
||||
|
||||
if (a->count-- == 0)
|
||||
a->state = MUTED;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (a->insig != a->outsig)
|
||||
memcpy (a->outsig, a->insig, a->size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy(a->insig, a->insig + a->size * 2, a->outsig);
|
||||
}
|
||||
}
|
||||
|
||||
void FMSQ::setBuffers_fmsq (FMSQ *a, float* in, float* out, float* trig)
|
||||
@ -289,6 +318,7 @@ void FMSQ::SetFMSQMP (RXA& rxa, int mp)
|
||||
{
|
||||
FMSQ *a;
|
||||
a = rxa.fmsq.p;
|
||||
|
||||
if (a->mp != mp)
|
||||
{
|
||||
a->mp = mp;
|
||||
|
@ -63,8 +63,8 @@ public:
|
||||
double tdown;
|
||||
int ntup;
|
||||
int ntdown;
|
||||
float* cup;
|
||||
float* cdown;
|
||||
double* cup;
|
||||
double* cdown;
|
||||
double tail_thresh;
|
||||
double unmute_thresh;
|
||||
double min_tail;
|
||||
|
@ -73,7 +73,7 @@ void GAIN::xgain (GAIN *a)
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void GAIN::setBuffers_gain (GAIN *a, float* in, float* out)
|
||||
|
@ -351,13 +351,13 @@ void GEN::xgen (GEN *a)
|
||||
break;
|
||||
default: // silence
|
||||
{
|
||||
memset (a->out, 0, a->size * sizeof (wcomplex));
|
||||
std::fill(a->out, a->out + a->size * 2, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void GEN::setBuffers_gen (GEN *a, float* in, float* out)
|
||||
|
@ -113,7 +113,7 @@ void ICFIR::xicfir (ICFIR *a)
|
||||
if (a->run)
|
||||
FIRCORE::xfircore (a->p);
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void ICFIR::setBuffers_icfir (ICFIR *a, float* in, float* out)
|
||||
|
265
wdsp/iir.cpp
265
wdsp/iir.cpp
@ -40,7 +40,7 @@ namespace WDSP {
|
||||
|
||||
void SNOTCH::calc_snotch (SNOTCH *a)
|
||||
{
|
||||
float fn, qk, qr, csn;
|
||||
double fn, qk, qr, csn;
|
||||
fn = a->f / (float)a->rate;
|
||||
csn = cos (TWOPI * fn);
|
||||
qr = 1.0 - 3.0 * a->bw;
|
||||
@ -53,7 +53,7 @@ void SNOTCH::calc_snotch (SNOTCH *a)
|
||||
flush_snotch (a);
|
||||
}
|
||||
|
||||
SNOTCH* SNOTCH::create_snotch (int run, int size, float* in, float* out, int rate, float f, float bw)
|
||||
SNOTCH* SNOTCH::create_snotch (int run, int size, float* in, float* out, int rate, double f, double bw)
|
||||
{
|
||||
SNOTCH *a = new SNOTCH;
|
||||
a->run = run;
|
||||
@ -93,7 +93,9 @@ void SNOTCH::xsnotch (SNOTCH *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void SNOTCH::setBuffers_snotch (SNOTCH *a, float* in, float* out)
|
||||
@ -120,7 +122,7 @@ void SNOTCH::setSize_snotch (SNOTCH *a, int size)
|
||||
* *
|
||||
********************************************************************************************************/
|
||||
|
||||
void SNOTCH::SetSNCTCSSFreq (SNOTCH *a, float freq)
|
||||
void SNOTCH::SetSNCTCSSFreq (SNOTCH *a, double freq)
|
||||
{
|
||||
a->f = freq;
|
||||
calc_snotch (a);
|
||||
@ -140,8 +142,8 @@ void SNOTCH::SetSNCTCSSRun (SNOTCH *a, int run)
|
||||
|
||||
void SPEAK::calc_speak (SPEAK *a)
|
||||
{
|
||||
float ratio;
|
||||
float f_corr, g_corr, bw_corr, bw_parm, A, f_min;
|
||||
double ratio;
|
||||
double f_corr, g_corr, bw_corr, bw_parm, A, f_min;
|
||||
|
||||
switch (a->design)
|
||||
{
|
||||
@ -161,11 +163,11 @@ void SPEAK::calc_speak (SPEAK *a)
|
||||
break;
|
||||
}
|
||||
{
|
||||
float fn, qk, qr, csn;
|
||||
double fn, qk, qr, csn;
|
||||
a->fgain = a->gain / g_corr;
|
||||
fn = a->f / (float)a->rate / f_corr;
|
||||
fn = a->f / (double)a->rate / f_corr;
|
||||
csn = cos (TWOPI * fn);
|
||||
qr = 1.0 - 3.0 * a->bw / (float)a->rate * bw_parm;
|
||||
qr = 1.0 - 3.0 * a->bw / (double)a->rate * bw_parm;
|
||||
qk = (1.0 - 2.0 * qr * csn + qr * qr) / (2.0 * (1.0 - csn));
|
||||
a->a0 = 1.0 - qk;
|
||||
a->a1 = 2.0 * (qk - qr) * csn;
|
||||
@ -195,9 +197,9 @@ void SPEAK::calc_speak (SPEAK *a)
|
||||
break;
|
||||
}
|
||||
{
|
||||
float w0, sn, c, den;
|
||||
double w0, sn, c, den;
|
||||
if (a->f < f_min) a->f = f_min;
|
||||
w0 = TWOPI * a->f / (float)a->rate;
|
||||
w0 = TWOPI * a->f / (double)a->rate;
|
||||
sn = sin (w0);
|
||||
a->cbw = bw_corr * a->f;
|
||||
c = sn * sinh(0.5 * log((a->f + 0.5 * a->cbw * bw_parm) / (a->f - 0.5 * a->cbw * bw_parm)) * w0 / sn);
|
||||
@ -207,14 +209,25 @@ void SPEAK::calc_speak (SPEAK *a)
|
||||
a->a2 = (1 - c * A) / den;
|
||||
a->b1 = - a->a1;
|
||||
a->b2 = - (1 - c / A ) / den;
|
||||
a->fgain = a->gain / pow (A * A, (float)a->nstages);
|
||||
a->fgain = a->gain / pow (A * A, (double)a->nstages);
|
||||
}
|
||||
break;
|
||||
}
|
||||
flush_speak (a);
|
||||
}
|
||||
|
||||
SPEAK* SPEAK::create_speak (int run, int size, float* in, float* out, int rate, float f, float bw, float gain, int nstages, int design)
|
||||
SPEAK* SPEAK::create_speak (
|
||||
int run,
|
||||
int size,
|
||||
float* in,
|
||||
float* out,
|
||||
int rate,
|
||||
double f,
|
||||
double bw,
|
||||
double gain,
|
||||
int nstages,
|
||||
int design
|
||||
)
|
||||
{
|
||||
SPEAK *a = new SPEAK;
|
||||
a->run = run;
|
||||
@ -227,12 +240,12 @@ SPEAK* SPEAK::create_speak (int run, int size, float* in, float* out, int rate,
|
||||
a->gain = gain;
|
||||
a->nstages = nstages;
|
||||
a->design = design;
|
||||
a->x0 = new float[a->nstages * 2]; // (float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->x1 = new float[a->nstages * 2]; // (float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->x2 = new float[a->nstages * 2]; //(float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->y0 = new float[a->nstages * 2]; // (float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->y1 = new float[a->nstages * 2]; // (float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->y2 = new float[a->nstages * 2]; // (float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->x0 = new double[a->nstages * 2]; // (float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->x1 = new double[a->nstages * 2]; // (float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->x2 = new double[a->nstages * 2]; //(float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->y0 = new double[a->nstages * 2]; // (float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->y1 = new double[a->nstages * 2]; // (float *) malloc0 (a->nstages * sizeof (complex));
|
||||
a->y2 = new double[a->nstages * 2]; // (float *) malloc0 (a->nstages * sizeof (complex));
|
||||
calc_speak (a);
|
||||
return a;
|
||||
}
|
||||
@ -272,12 +285,13 @@ void SPEAK::xspeak (SPEAK *a)
|
||||
|
||||
for (n = 0; n < a->nstages; n++)
|
||||
{
|
||||
if (n > 0) a->x0[2 * n + j] = a->y0[2 * (n - 1) + j];
|
||||
a->y0[2 * n + j] = a->a0 * a->x0[2 * n + j]
|
||||
+ a->a1 * a->x1[2 * n + j]
|
||||
+ a->a2 * a->x2[2 * n + j]
|
||||
+ a->b1 * a->y1[2 * n + j]
|
||||
+ a->b2 * a->y2[2 * n + j];
|
||||
if (n > 0)
|
||||
a->x0[2 * n + j] = a->y0[2 * (n - 1) + j];
|
||||
a->y0[2 * n + j] = a->a0 * a->x0[2 * n + j]
|
||||
+ a->a1 * a->x1[2 * n + j]
|
||||
+ a->a2 * a->x2[2 * n + j]
|
||||
+ a->b1 * a->y1[2 * n + j]
|
||||
+ a->b2 * a->y2[2 * n + j];
|
||||
a->y2[2 * n + j] = a->y1[2 * n + j];
|
||||
a->y1[2 * n + j] = a->y0[2 * n + j];
|
||||
a->x2[2 * n + j] = a->x1[2 * n + j];
|
||||
@ -289,7 +303,9 @@ void SPEAK::xspeak (SPEAK *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void SPEAK::setBuffers_speak (SPEAK *a, float* in, float* out)
|
||||
@ -322,21 +338,21 @@ void SPEAK::SetSPCWRun (RXA& rxa, int run)
|
||||
a->run = run;
|
||||
}
|
||||
|
||||
void SPEAK::SetSPCWFreq (RXA& rxa, float freq)
|
||||
void SPEAK::SetSPCWFreq (RXA& rxa, double freq)
|
||||
{
|
||||
SPEAK *a = rxa.speak.p;
|
||||
a->f = freq;
|
||||
calc_speak (a);
|
||||
}
|
||||
|
||||
void SPEAK::SetSPCWBandwidth (RXA& rxa, float bw)
|
||||
void SPEAK::SetSPCWBandwidth (RXA& rxa, double bw)
|
||||
{
|
||||
SPEAK *a = rxa.speak.p;
|
||||
a->bw = bw;
|
||||
calc_speak (a);
|
||||
}
|
||||
|
||||
void SPEAK::SetSPCWGain (RXA& rxa, float gain)
|
||||
void SPEAK::SetSPCWGain (RXA& rxa, double gain)
|
||||
{
|
||||
SPEAK *a = rxa.speak.p;
|
||||
a->gain = gain;
|
||||
@ -380,7 +396,19 @@ void MPEAK::decalc_mpeak (MPEAK *a)
|
||||
delete[] (a->tmp);
|
||||
}
|
||||
|
||||
MPEAK* MPEAK::create_mpeak (int run, int size, float* in, float* out, int rate, int npeaks, int* enable, float* f, float* bw, float* gain, int nstages)
|
||||
MPEAK* MPEAK::create_mpeak (
|
||||
int run,
|
||||
int size,
|
||||
float* in,
|
||||
float* out,
|
||||
int rate,
|
||||
int npeaks,
|
||||
int* enable,
|
||||
double* f,
|
||||
double* bw,
|
||||
double* gain,
|
||||
int nstages
|
||||
)
|
||||
{
|
||||
MPEAK *a = new MPEAK;
|
||||
a->run = run;
|
||||
@ -391,13 +419,13 @@ MPEAK* MPEAK::create_mpeak (int run, int size, float* in, float* out, int rate,
|
||||
a->npeaks = npeaks;
|
||||
a->nstages = nstages;
|
||||
a->enable = new int[a->npeaks]; // (int *) malloc0 (a->npeaks * sizeof (int));
|
||||
a->f = new float[a->npeaks]; // (float *) malloc0 (a->npeaks * sizeof (float));
|
||||
a->bw = new float[a->npeaks]; // (float *) malloc0 (a->npeaks * sizeof (float));
|
||||
a->gain = new float[a->npeaks]; // (float *) malloc0 (a->npeaks * sizeof (float));
|
||||
a->f = new double[a->npeaks]; // (float *) malloc0 (a->npeaks * sizeof (float));
|
||||
a->bw = new double[a->npeaks]; // (float *) malloc0 (a->npeaks * sizeof (float));
|
||||
a->gain = new double[a->npeaks]; // (float *) malloc0 (a->npeaks * sizeof (float));
|
||||
memcpy (a->enable, enable, a->npeaks * sizeof (int));
|
||||
memcpy (a->f, f, a->npeaks * sizeof (float));
|
||||
memcpy (a->bw, bw, a->npeaks * sizeof (float));
|
||||
memcpy (a->gain, gain, a->npeaks * sizeof (float));
|
||||
memcpy (a->f, f, a->npeaks * sizeof (double));
|
||||
memcpy (a->bw, bw, a->npeaks * sizeof (double));
|
||||
memcpy (a->gain, gain, a->npeaks * sizeof (double));
|
||||
a->pfil = new SPEAK*[a->npeaks]; // (SPEAK *) malloc0 (a->npeaks * sizeof (SPEAK));
|
||||
calc_mpeak (a);
|
||||
return a;
|
||||
@ -426,7 +454,7 @@ void MPEAK::xmpeak (MPEAK *a)
|
||||
if (a->run)
|
||||
{
|
||||
int i, j;
|
||||
memset (a->mix, 0, a->size * sizeof (wcomplex));
|
||||
std::fill(a->mix, a->mix + a->size * 2, 0);
|
||||
|
||||
for (i = 0; i < a->npeaks; i++)
|
||||
{
|
||||
@ -438,11 +466,12 @@ void MPEAK::xmpeak (MPEAK *a)
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (a->out, a->mix, a->size * sizeof (wcomplex));
|
||||
std::copy(a->mix, a->mix + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void MPEAK::setBuffers_mpeak (MPEAK *a, float* in, float* out)
|
||||
@ -491,7 +520,7 @@ void MPEAK::SetmpeakFilEnable (RXA& rxa, int fil, int enable)
|
||||
a->enable[fil] = enable;
|
||||
}
|
||||
|
||||
void MPEAK::SetmpeakFilFreq (RXA& rxa, int fil, float freq)
|
||||
void MPEAK::SetmpeakFilFreq (RXA& rxa, int fil, double freq)
|
||||
{
|
||||
MPEAK *a = rxa.mpeak.p;
|
||||
a->f[fil] = freq;
|
||||
@ -499,7 +528,7 @@ void MPEAK::SetmpeakFilFreq (RXA& rxa, int fil, float freq)
|
||||
SPEAK::calc_speak(a->pfil[fil]);
|
||||
}
|
||||
|
||||
void MPEAK::SetmpeakFilBw (RXA& rxa, int fil, float bw)
|
||||
void MPEAK::SetmpeakFilBw (RXA& rxa, int fil, double bw)
|
||||
{
|
||||
MPEAK *a = rxa.mpeak.p;
|
||||
a->bw[fil] = bw;
|
||||
@ -507,7 +536,7 @@ void MPEAK::SetmpeakFilBw (RXA& rxa, int fil, float bw)
|
||||
SPEAK::calc_speak(a->pfil[fil]);
|
||||
}
|
||||
|
||||
void MPEAK::SetmpeakFilGain (RXA& rxa, int fil, float gain)
|
||||
void MPEAK::SetmpeakFilGain (RXA& rxa, int fil, double gain)
|
||||
{
|
||||
MPEAK *a = rxa.mpeak.p;
|
||||
a->gain[fil] = gain;
|
||||
@ -524,11 +553,11 @@ void MPEAK::SetmpeakFilGain (RXA& rxa, int fil, float gain)
|
||||
|
||||
void PHROT::calc_phrot (PHROT *a)
|
||||
{
|
||||
float g;
|
||||
a->x0 = new float[a->nstages]; // (float *) malloc0 (a->nstages * sizeof (float));
|
||||
a->x1 = new float[a->nstages]; // (float *) malloc0 (a->nstages * sizeof (float));
|
||||
a->y0 = new float[a->nstages]; // (float *) malloc0 (a->nstages * sizeof (float));
|
||||
a->y1 = new float[a->nstages]; // (float *) malloc0 (a->nstages * sizeof (float));
|
||||
double g;
|
||||
a->x0 = new double[a->nstages]; // (float *) malloc0 (a->nstages * sizeof (float));
|
||||
a->x1 = new double[a->nstages]; // (float *) malloc0 (a->nstages * sizeof (float));
|
||||
a->y0 = new double[a->nstages]; // (float *) malloc0 (a->nstages * sizeof (float));
|
||||
a->y1 = new double[a->nstages]; // (float *) malloc0 (a->nstages * sizeof (float));
|
||||
g = tan (PI * a->fc / (float)a->rate);
|
||||
a->b0 = (g - 1.0) / (g + 1.0);
|
||||
a->b1 = 1.0;
|
||||
@ -543,7 +572,7 @@ void PHROT::decalc_phrot (PHROT *a)
|
||||
delete[] (a->x0);
|
||||
}
|
||||
|
||||
PHROT* PHROT::create_phrot (int run, int size, float* in, float* out, int rate, float fc, int nstages)
|
||||
PHROT* PHROT::create_phrot (int run, int size, float* in, float* out, int rate, double fc, int nstages)
|
||||
{
|
||||
PHROT *a = new PHROT;
|
||||
a->reverse = 0;
|
||||
@ -566,10 +595,10 @@ void PHROT::destroy_phrot (PHROT *a)
|
||||
|
||||
void PHROT::flush_phrot (PHROT *a)
|
||||
{
|
||||
memset (a->x0, 0, a->nstages * sizeof (float));
|
||||
memset (a->x1, 0, a->nstages * sizeof (float));
|
||||
memset (a->y0, 0, a->nstages * sizeof (float));
|
||||
memset (a->y1, 0, a->nstages * sizeof (float));
|
||||
memset (a->x0, 0, a->nstages * sizeof (double));
|
||||
memset (a->x1, 0, a->nstages * sizeof (double));
|
||||
memset (a->y0, 0, a->nstages * sizeof (double));
|
||||
memset (a->y1, 0, a->nstages * sizeof (double));
|
||||
}
|
||||
|
||||
void PHROT::xphrot (PHROT *a)
|
||||
@ -579,6 +608,7 @@ void PHROT::xphrot (PHROT *a)
|
||||
for (int i = 0; i < a->size; i++)
|
||||
a->in[2 * i + 0] = -a->in[2 * i + 0];
|
||||
}
|
||||
|
||||
if (a->run)
|
||||
{
|
||||
int i, n;
|
||||
@ -590,9 +620,9 @@ void PHROT::xphrot (PHROT *a)
|
||||
for (n = 0; n < a->nstages; n++)
|
||||
{
|
||||
if (n > 0) a->x0[n] = a->y0[n - 1];
|
||||
a->y0[n] = a->b0 * a->x0[n]
|
||||
+ a->b1 * a->x1[n]
|
||||
- a->a1 * a->y1[n];
|
||||
a->y0[n] = a->b0 * a->x0[n]
|
||||
+ a->b1 * a->x1[n]
|
||||
- a->a1 * a->y1[n];
|
||||
a->y1[n] = a->y0[n];
|
||||
a->x1[n] = a->x0[n];
|
||||
}
|
||||
@ -601,7 +631,9 @@ void PHROT::xphrot (PHROT *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void PHROT::setBuffers_phrot (PHROT *a, float* in, float* out)
|
||||
@ -638,7 +670,7 @@ void PHROT::SetPHROTRun (TXA& txa, int run)
|
||||
flush_phrot (a);
|
||||
}
|
||||
|
||||
void PHROT::SetPHROTCorner (TXA& txa, float corner)
|
||||
void PHROT::SetPHROTCorner (TXA& txa, double corner)
|
||||
{
|
||||
PHROT *a = txa.phrot.p;
|
||||
decalc_phrot (a);
|
||||
@ -668,8 +700,8 @@ void PHROT::SetPHROTReverse (TXA& txa, int reverse)
|
||||
|
||||
void BQLP::calc_bqlp(BQLP *a)
|
||||
{
|
||||
float w0, cs, c, den;
|
||||
w0 = TWOPI * a->fc / (float)a->rate;
|
||||
double w0, cs, c, den;
|
||||
w0 = TWOPI * a->fc / (double)a->rate;
|
||||
cs = cos(w0);
|
||||
c = sin(w0) / (2.0 * a->Q);
|
||||
den = 1.0 + c;
|
||||
@ -681,7 +713,7 @@ void BQLP::calc_bqlp(BQLP *a)
|
||||
flush_bqlp(a);
|
||||
}
|
||||
|
||||
BQLP* BQLP::create_bqlp(int run, int size, float* in, float* out, float rate, float fc, float Q, float gain, int nstages)
|
||||
BQLP* BQLP::create_bqlp(int run, int size, float* in, float* out, double rate, double fc, double Q, double gain, int nstages)
|
||||
{
|
||||
BQLP *a = new BQLP;
|
||||
a->run = run;
|
||||
@ -693,12 +725,12 @@ BQLP* BQLP::create_bqlp(int run, int size, float* in, float* out, float rate, fl
|
||||
a->Q = Q;
|
||||
a->gain = gain;
|
||||
a->nstages = nstages;
|
||||
a->x0 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x1 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x2 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y0 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y1 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y2 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x0 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x1 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x2 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y0 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y1 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y2 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
calc_bqlp(a);
|
||||
return a;
|
||||
}
|
||||
@ -738,7 +770,8 @@ void BQLP::xbqlp(BQLP *a)
|
||||
|
||||
for (n = 0; n < a->nstages; n++)
|
||||
{
|
||||
if (n > 0) a->x0[2 * n + j] = a->y0[2 * (n - 1) + j];
|
||||
if (n > 0)
|
||||
a->x0[2 * n + j] = a->y0[2 * (n - 1) + j];
|
||||
a->y0[2 * n + j] = a->a0 * a->x0[2 * n + j]
|
||||
+ a->a1 * a->x1[2 * n + j]
|
||||
+ a->a2 * a->x2[2 * n + j]
|
||||
@ -755,7 +788,9 @@ void BQLP::xbqlp(BQLP *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy(a->out, a->in, a->size * sizeof(wcomplex));
|
||||
{
|
||||
std::copy(a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void BQLP::setBuffers_bqlp(BQLP *a, float* in, float* out)
|
||||
@ -797,7 +832,7 @@ void DBQLP::calc_dbqlp(BQLP *a)
|
||||
flush_dbqlp(a);
|
||||
}
|
||||
|
||||
BQLP* DBQLP::create_dbqlp(int run, int size, float* in, float* out, float rate, float fc, float Q, float gain, int nstages)
|
||||
BQLP* DBQLP::create_dbqlp(int run, int size, float* in, float* out, double rate, double fc, double Q, double gain, int nstages)
|
||||
{
|
||||
BQLP *a = new BQLP;
|
||||
a->run = run;
|
||||
@ -809,12 +844,12 @@ BQLP* DBQLP::create_dbqlp(int run, int size, float* in, float* out, float rate,
|
||||
a->Q = Q;
|
||||
a->gain = gain;
|
||||
a->nstages = nstages;
|
||||
a->x0 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x1 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x2 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y0 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y1 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y2 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x0 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x1 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x2 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y0 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y1 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y2 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
calc_dbqlp(a);
|
||||
return a;
|
||||
}
|
||||
@ -869,7 +904,9 @@ void DBQLP::xdbqlp(BQLP *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
{
|
||||
memcpy(a->out, a->in, a->size * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
void DBQLP::setBuffers_dbqlp(BQLP *a, float* in, float* out)
|
||||
@ -899,7 +936,7 @@ void DBQLP::setSize_dbqlp(BQLP *a, int size)
|
||||
|
||||
void BQBP::calc_bqbp(BQBP *a)
|
||||
{
|
||||
float f0, w0, bw, q, sn, cs, c, den;
|
||||
double f0, w0, bw, q, sn, cs, c, den;
|
||||
bw = a->f_high - a->f_low;
|
||||
f0 = (a->f_high + a->f_low) / 2.0;
|
||||
q = f0 / bw;
|
||||
@ -916,7 +953,7 @@ void BQBP::calc_bqbp(BQBP *a)
|
||||
flush_bqbp(a);
|
||||
}
|
||||
|
||||
BQBP* BQBP::create_bqbp(int run, int size, float* in, float* out, float rate, float f_low, float f_high, float gain, int nstages)
|
||||
BQBP* BQBP::create_bqbp(int run, int size, float* in, float* out, double rate, double f_low, double f_high, double gain, int nstages)
|
||||
{
|
||||
BQBP *a = new BQBP;
|
||||
a->run = run;
|
||||
@ -928,12 +965,12 @@ BQBP* BQBP::create_bqbp(int run, int size, float* in, float* out, float rate, fl
|
||||
a->f_high = f_high;
|
||||
a->gain = gain;
|
||||
a->nstages = nstages;
|
||||
a->x0 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x1 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x2 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y0 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y1 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y2 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x0 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x1 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x2 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y0 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y1 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y2 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
calc_bqbp(a);
|
||||
return a;
|
||||
}
|
||||
@ -992,7 +1029,9 @@ void BQBP::xbqbp(BQBP *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy(a->out, a->in, a->size * sizeof(wcomplex));
|
||||
{
|
||||
std::copy(a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void BQBP::setBuffers_bqbp(BQBP *a, float* in, float* out)
|
||||
@ -1021,7 +1060,7 @@ void BQBP::setSize_bqbp(BQBP *a, int size)
|
||||
|
||||
void BQBP::calc_dbqbp(BQBP *a)
|
||||
{
|
||||
float f0, w0, bw, q, sn, cs, c, den;
|
||||
double f0, w0, bw, q, sn, cs, c, den;
|
||||
bw = a->f_high - a->f_low;
|
||||
f0 = (a->f_high + a->f_low) / 2.0;
|
||||
q = f0 / bw;
|
||||
@ -1038,7 +1077,7 @@ void BQBP::calc_dbqbp(BQBP *a)
|
||||
flush_dbqbp(a);
|
||||
}
|
||||
|
||||
BQBP* BQBP::create_dbqbp(int run, int size, float* in, float* out, float rate, float f_low, float f_high, float gain, int nstages)
|
||||
BQBP* BQBP::create_dbqbp(int run, int size, float* in, float* out, double rate, double f_low, double f_high, double gain, int nstages)
|
||||
{
|
||||
BQBP *a = new BQBP;
|
||||
a->run = run;
|
||||
@ -1050,12 +1089,12 @@ BQBP* BQBP::create_dbqbp(int run, int size, float* in, float* out, float rate, f
|
||||
a->f_high = f_high;
|
||||
a->gain = gain;
|
||||
a->nstages = nstages;
|
||||
a->x0 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x1 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x2 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y0 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y1 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y2 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x0 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x1 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x2 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y0 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y1 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y2 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
calc_dbqbp(a);
|
||||
return a;
|
||||
}
|
||||
@ -1110,7 +1149,9 @@ void BQBP::xdbqbp(BQBP *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
{
|
||||
memcpy(a->out, a->in, a->size * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
void BQBP::setBuffers_dbqbp(BQBP *a, float* in, float* out)
|
||||
@ -1139,18 +1180,18 @@ void BQBP::setSize_dbqbp(BQBP *a, int size)
|
||||
|
||||
void SPHP::calc_sphp(SPHP *a)
|
||||
{
|
||||
float g;
|
||||
a->x0 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x1 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y0 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y1 = new float[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
double g;
|
||||
a->x0 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->x1 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y0 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
a->y1 = new double[a->nstages * 2]; // (float*)malloc0(a->nstages * sizeof(complex));
|
||||
g = exp(-TWOPI * a->fc / a->rate);
|
||||
a->b0 = +0.5 * (1.0 + g);
|
||||
a->b1 = -0.5 * (1.0 + g);
|
||||
a->a1 = -g;
|
||||
}
|
||||
|
||||
SPHP* SPHP::create_sphp(int run, int size, float* in, float* out, float rate, float fc, int nstages)
|
||||
SPHP* SPHP::create_sphp(int run, int size, float* in, float* out, double rate, double fc, int nstages)
|
||||
{
|
||||
SPHP *a = new SPHP;
|
||||
a->run = run;
|
||||
@ -1180,10 +1221,10 @@ void SPHP::destroy_sphp(SPHP *a)
|
||||
|
||||
void SPHP::flush_sphp(SPHP *a)
|
||||
{
|
||||
memset(a->x0, 0, a->nstages * sizeof(wcomplex));
|
||||
memset(a->x1, 0, a->nstages * sizeof(wcomplex));
|
||||
memset(a->y0, 0, a->nstages * sizeof(wcomplex));
|
||||
memset(a->y1, 0, a->nstages * sizeof(wcomplex));
|
||||
std::fill(a->x0, a->x0 + a->nstages * 2, 0);
|
||||
std::fill(a->x1, a->x0 + a->nstages * 2, 0);
|
||||
std::fill(a->y0, a->x0 + a->nstages * 2, 0);
|
||||
std::fill(a->y1, a->x0 + a->nstages * 2, 0);
|
||||
}
|
||||
|
||||
void SPHP::xsphp(SPHP *a)
|
||||
@ -1214,7 +1255,9 @@ void SPHP::xsphp(SPHP *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy(a->out, a->in, a->size * sizeof(wcomplex));
|
||||
{
|
||||
std::copy(a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void SPHP::setBuffers_sphp(SPHP *a, float* in, float* out)
|
||||
@ -1244,18 +1287,18 @@ void SPHP::setSize_sphp(SPHP *a, int size)
|
||||
|
||||
void SPHP::calc_dsphp(SPHP *a)
|
||||
{
|
||||
float g;
|
||||
a->x0 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x1 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y0 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y1 = new float[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
double g;
|
||||
a->x0 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->x1 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y0 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
a->y1 = new double[a->nstages]; // (float*)malloc0(a->nstages * sizeof(float));
|
||||
g = exp(-TWOPI * a->fc / a->rate);
|
||||
a->b0 = +0.5 * (1.0 + g);
|
||||
a->b1 = -0.5 * (1.0 + g);
|
||||
a->a1 = -g;
|
||||
}
|
||||
|
||||
SPHP* SPHP::create_dsphp(int run, int size, float* in, float* out, float rate, float fc, int nstages)
|
||||
SPHP* SPHP::create_dsphp(int run, int size, float* in, float* out, double rate, double fc, int nstages)
|
||||
{
|
||||
SPHP *a = new SPHP;
|
||||
a->run = run;
|
||||
@ -1317,7 +1360,9 @@ void SPHP::xdsphp(SPHP *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
{
|
||||
memcpy(a->out, a->in, a->size * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
void SPHP::setBuffers_dsphp(SPHP *a, float* in, float* out)
|
||||
|
129
wdsp/iir.hpp
129
wdsp/iir.hpp
@ -45,20 +45,20 @@ public:
|
||||
int size;
|
||||
float* in;
|
||||
float* out;
|
||||
float rate;
|
||||
float f;
|
||||
float bw;
|
||||
float a0, a1, a2, b1, b2;
|
||||
float x0, x1, x2, y1, y2;
|
||||
double rate;
|
||||
double f;
|
||||
double bw;
|
||||
double a0, a1, a2, b1, b2;
|
||||
double x0, x1, x2, y1, y2;
|
||||
|
||||
static SNOTCH* create_snotch (int run, int size, float* in, float* out, int rate, float f, float bw);
|
||||
static SNOTCH* create_snotch (int run, int size, float* in, float* out, int rate, double f, double bw);
|
||||
static void destroy_snotch (SNOTCH *a);
|
||||
static void flush_snotch (SNOTCH *a);
|
||||
static void xsnotch (SNOTCH *a);
|
||||
static void setBuffers_snotch (SNOTCH *a, float* in, float* out);
|
||||
static void setSamplerate_snotch (SNOTCH *a, int rate);
|
||||
static void setSize_snotch (SNOTCH *a, int size);
|
||||
static void SetSNCTCSSFreq (SNOTCH *a, float freq);
|
||||
static void SetSNCTCSSFreq (SNOTCH *a, double freq);
|
||||
static void SetSNCTCSSRun (SNOTCH *a, int run);
|
||||
|
||||
private:
|
||||
@ -91,18 +91,29 @@ public:
|
||||
int size;
|
||||
float* in;
|
||||
float* out;
|
||||
float rate;
|
||||
float f;
|
||||
float bw;
|
||||
float cbw;
|
||||
float gain;
|
||||
float fgain;
|
||||
double rate;
|
||||
double f;
|
||||
double bw;
|
||||
double cbw;
|
||||
double gain;
|
||||
double fgain;
|
||||
int nstages;
|
||||
int design;
|
||||
float a0, a1, a2, b1, b2;
|
||||
float *x0, *x1, *x2, *y0, *y1, *y2;
|
||||
double a0, a1, a2, b1, b2;
|
||||
double *x0, *x1, *x2, *y0, *y1, *y2;
|
||||
|
||||
static SPEAK* create_speak (int run, int size, float* in, float* out, int rate, float f, float bw, float gain, int nstages, int design);
|
||||
static SPEAK* create_speak (
|
||||
int run,
|
||||
int size,
|
||||
float* in,
|
||||
float* out,
|
||||
int rate,
|
||||
double f,
|
||||
double bw,
|
||||
double gain,
|
||||
int nstages,
|
||||
int design
|
||||
);
|
||||
static void destroy_speak (SPEAK *a);
|
||||
static void flush_speak (SPEAK *a);
|
||||
static void xspeak (SPEAK *a);
|
||||
@ -111,9 +122,9 @@ public:
|
||||
static void setSize_speak (SPEAK *a, int size);
|
||||
// RXA
|
||||
static void SetSPCWRun (RXA& rxa, int run);
|
||||
static void SetSPCWFreq (RXA& rxa, float freq);
|
||||
static void SetSPCWBandwidth (RXA& rxa, float bw);
|
||||
static void SetSPCWGain (RXA& rxa, float gain);
|
||||
static void SetSPCWFreq (RXA& rxa, double freq);
|
||||
static void SetSPCWBandwidth (RXA& rxa, double bw);
|
||||
static void SetSPCWGain (RXA& rxa, double gain);
|
||||
static void calc_speak (SPEAK *a);
|
||||
};
|
||||
|
||||
@ -146,15 +157,27 @@ public:
|
||||
int rate;
|
||||
int npeaks;
|
||||
int* enable;
|
||||
float* f;
|
||||
float* bw;
|
||||
float* gain;
|
||||
double* f;
|
||||
double* bw;
|
||||
double* gain;
|
||||
int nstages;
|
||||
SPEAK** pfil;
|
||||
float* tmp;
|
||||
float* mix;
|
||||
|
||||
static MPEAK* create_mpeak (int run, int size, float* in, float* out, int rate, int npeaks, int* enable, float* f, float* bw, float* gain, int nstages);
|
||||
static MPEAK* create_mpeak (
|
||||
int run,
|
||||
int size,
|
||||
float* in,
|
||||
float* out,
|
||||
int rate,
|
||||
int npeaks,
|
||||
int* enable,
|
||||
double* f,
|
||||
double* bw,
|
||||
double* gain,
|
||||
int nstages
|
||||
);
|
||||
static void destroy_mpeak (MPEAK *a);
|
||||
static void flush_mpeak (MPEAK *a);
|
||||
static void xmpeak (MPEAK *a);
|
||||
@ -165,9 +188,9 @@ public:
|
||||
static void SetmpeakRun (RXA& rxa, int run);
|
||||
static void SetmpeakNpeaks (RXA& rxa, int npeaks);
|
||||
static void SetmpeakFilEnable (RXA& rxa, int fil, int enable);
|
||||
static void SetmpeakFilFreq (RXA& rxa, int fil, float freq);
|
||||
static void SetmpeakFilBw (RXA& rxa, int fil, float bw);
|
||||
static void SetmpeakFilGain (RXA& rxa, int fil, float gain);
|
||||
static void SetmpeakFilFreq (RXA& rxa, int fil, double freq);
|
||||
static void SetmpeakFilBw (RXA& rxa, int fil, double bw);
|
||||
static void SetmpeakFilGain (RXA& rxa, int fil, double gain);
|
||||
|
||||
private:
|
||||
static void calc_mpeak (MPEAK *a);
|
||||
@ -202,13 +225,13 @@ public:
|
||||
float* in;
|
||||
float* out;
|
||||
int rate;
|
||||
float fc;
|
||||
double fc;
|
||||
int nstages;
|
||||
// normalized such that a0 = 1
|
||||
float a1, b0, b1;
|
||||
float *x0, *x1, *y0, *y1;
|
||||
double a1, b0, b1;
|
||||
double *x0, *x1, *y0, *y1;
|
||||
|
||||
static PHROT* create_phrot (int run, int size, float* in, float* out, int rate, float fc, int nstages);
|
||||
static PHROT* create_phrot (int run, int size, float* in, float* out, int rate, double fc, int nstages);
|
||||
static void destroy_phrot (PHROT *a);
|
||||
static void flush_phrot (PHROT *a);
|
||||
static void xphrot (PHROT *a);
|
||||
@ -217,7 +240,7 @@ public:
|
||||
static void setSize_phrot (PHROT *a, int size);
|
||||
// TXA Properties
|
||||
static void SetPHROTRun (TXA& txa, int run);
|
||||
static void SetPHROTCorner (TXA& txa, float corner);
|
||||
static void SetPHROTCorner (TXA& txa, double corner);
|
||||
static void SetPHROTNstages (TXA& txa, int nstages);
|
||||
static void SetPHROTReverse (TXA& txa, int reverse);
|
||||
|
||||
@ -250,15 +273,15 @@ public:
|
||||
int size;
|
||||
float* in;
|
||||
float* out;
|
||||
float rate;
|
||||
float fc;
|
||||
float Q;
|
||||
float gain;
|
||||
double rate;
|
||||
double fc;
|
||||
double Q;
|
||||
double gain;
|
||||
int nstages;
|
||||
float a0, a1, a2, b1, b2;
|
||||
float* x0, * x1, * x2, * y0, * y1, * y2;
|
||||
double a0, a1, a2, b1, b2;
|
||||
double* x0, * x1, * x2, * y0, * y1, * y2;
|
||||
|
||||
static BQLP* create_bqlp(int run, int size, float* in, float* out, float rate, float fc, float Q, float gain, int nstages);
|
||||
static BQLP* create_bqlp(int run, int size, float* in, float* out, double rate, double fc, double Q, double gain, int nstages);
|
||||
static void destroy_bqlp(BQLP *a);
|
||||
static void flush_bqlp(BQLP *a);
|
||||
static void xbqlp(BQLP *a);
|
||||
@ -290,7 +313,7 @@ namespace WDSP {
|
||||
class WDSP_API DBQLP
|
||||
{
|
||||
public:
|
||||
static BQLP* create_dbqlp(int run, int size, float* in, float* out, float rate, float fc, float Q, float gain, int nstages);
|
||||
static BQLP* create_dbqlp(int run, int size, float* in, float* out, double rate, double fc, double Q, double gain, int nstages);
|
||||
static void destroy_dbqlp(BQLP *a);
|
||||
static void flush_dbqlp(BQLP *a);
|
||||
static void xdbqlp(BQLP *a);
|
||||
@ -326,15 +349,15 @@ public:
|
||||
int size;
|
||||
float* in;
|
||||
float* out;
|
||||
float rate;
|
||||
float f_low;
|
||||
float f_high;
|
||||
float gain;
|
||||
double rate;
|
||||
double f_low;
|
||||
double f_high;
|
||||
double gain;
|
||||
int nstages;
|
||||
float a0, a1, a2, b1, b2;
|
||||
float* x0, * x1, * x2, * y0, * y1, * y2;
|
||||
double a0, a1, a2, b1, b2;
|
||||
double* x0, * x1, * x2, * y0, * y1, * y2;
|
||||
|
||||
static BQBP* create_bqbp(int run, int size, float* in, float* out, float rate, float f_low, float f_high, float gain, int nstages);
|
||||
static BQBP* create_bqbp(int run, int size, float* in, float* out, double rate, double f_low, double f_high, double gain, int nstages);
|
||||
static void destroy_bqbp(BQBP *a);
|
||||
static void flush_bqbp(BQBP *a);
|
||||
static void xbqbp(BQBP *a);
|
||||
@ -343,7 +366,7 @@ public:
|
||||
static void setSize_bqbp(BQBP *a, int size);
|
||||
|
||||
// Double Bi-Quad Band-Pass
|
||||
static BQBP* create_dbqbp(int run, int size, float* in, float* out, float rate, float f_low, float f_high, float gain, int nstages);
|
||||
static BQBP* create_dbqbp(int run, int size, float* in, float* out, double rate, double f_low, double f_high, double gain, int nstages);
|
||||
static void destroy_dbqbp(BQBP *a);
|
||||
static void flush_dbqbp(BQBP *a);
|
||||
static void xdbqbp(BQBP *a);
|
||||
@ -380,13 +403,13 @@ public:
|
||||
int size;
|
||||
float* in;
|
||||
float* out;
|
||||
float rate;
|
||||
float fc;
|
||||
double rate;
|
||||
double fc;
|
||||
int nstages;
|
||||
float a1, b0, b1;
|
||||
float* x0, * x1, * y0, * y1;
|
||||
double a1, b0, b1;
|
||||
double* x0, * x1, * y0, * y1;
|
||||
|
||||
static SPHP* create_dsphp(int run, int size, float* in, float* out, float rate, float fc, int nstages);
|
||||
static SPHP* create_dsphp(int run, int size, float* in, float* out, double rate, double fc, int nstages);
|
||||
static void destroy_dsphp(SPHP *a);
|
||||
static void flush_dsphp(SPHP *a);
|
||||
static void xdsphp(SPHP *a);
|
||||
@ -395,7 +418,7 @@ public:
|
||||
static void setSize_dsphp(SPHP *a, int size);
|
||||
|
||||
// Complex Single-Pole High-Pass
|
||||
static SPHP* create_sphp(int run, int size, float* in, float* out, float rate, float fc, int nstages);
|
||||
static SPHP* create_sphp(int run, int size, float* in, float* out, double rate, double fc, int nstages);
|
||||
static void destroy_sphp(SPHP *a);
|
||||
static void flush_sphp(SPHP *a);
|
||||
static void xsphp(SPHP *a);
|
||||
|
@ -203,7 +203,7 @@ void IQC::xiqc (IQC *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void IQC::setBuffers_iqc (IQC *a, float* in, float* out)
|
||||
|
@ -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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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; i<argc; i++) {
|
||||
infile=fopen(argv[i],"r");
|
||||
if (infile == NULL) continue;
|
||||
first_in_file=1;
|
||||
for (;;) {
|
||||
if (getline(&buffer, &linesize, infile) < 0) break;
|
||||
trimm(line, linesize);
|
||||
if (strncmp(line,"PORT", 4) != 0) continue;
|
||||
// found an interface
|
||||
if (first_in_file) {
|
||||
printf("\n//\n// Interfaces from %s\n//\n\n", argv[i]);
|
||||
first_in_file=0;
|
||||
}
|
||||
if (strlen(line) >4) {
|
||||
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;
|
||||
}
|
@ -60,7 +60,7 @@ METER* METER::create_meter (
|
||||
a->prun = prun;
|
||||
a->size = size;
|
||||
a->buff = buff;
|
||||
a->rate = (float)rate;
|
||||
a->rate = (double) rate;
|
||||
a->tau_average = tau_av;
|
||||
a->tau_peak_decay = tau_decay;
|
||||
a->result = result;
|
||||
@ -105,7 +105,9 @@ void METER::xmeter (METER *a)
|
||||
|
||||
for (i = 0; i < a->size; i++)
|
||||
{
|
||||
smag = a->buff[2 * i + 0] * a->buff[2 * i + 0] + a->buff[2 * i + 1] * a->buff[2 * i + 1];
|
||||
double xr = a->buff[2 * i + 0];
|
||||
double xi = a->buff[2 * i + 1];
|
||||
smag = xr*xr + xi*xi;
|
||||
a->avg = a->avg * a->mult_average + (1.0 - a->mult_average) * smag;
|
||||
a->peak *= a->mult_peak;
|
||||
|
||||
@ -140,7 +142,7 @@ void METER::setBuffers_meter (METER *a, float* in)
|
||||
|
||||
void METER::setSamplerate_meter (METER *a, int rate)
|
||||
{
|
||||
a->rate = rate;
|
||||
a->rate = (double) rate;
|
||||
calc_meter(a);
|
||||
}
|
||||
|
||||
|
69
wdsp/nbp.cpp
69
wdsp/nbp.cpp
@ -46,10 +46,10 @@ namespace WDSP {
|
||||
a->master_run = master_run;
|
||||
a->maxnotches = maxnotches;
|
||||
a->nn = 0;
|
||||
a->fcenter = new float[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float));
|
||||
a->fwidth = new float[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float));
|
||||
a->nlow = new float[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float));
|
||||
a->nhigh = new float[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float));
|
||||
a->fcenter = new double[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float));
|
||||
a->fwidth = new double[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float));
|
||||
a->nlow = new double[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float));
|
||||
a->nhigh = new double[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float));
|
||||
a->active = new int[a->maxnotches]; // (int *) malloc0 (a->maxnotches * sizeof (int ));
|
||||
return a;
|
||||
}
|
||||
@ -69,7 +69,7 @@ void NOTCHDB::destroy_notchdb (NOTCHDB *b)
|
||||
* *
|
||||
********************************************************************************************************/
|
||||
|
||||
float* NBP::fir_mbandpass (int N, int nbp, float* flow, float* fhigh, float rate, float scale, int wintype)
|
||||
float* NBP::fir_mbandpass (int N, int nbp, double* flow, double* fhigh, double rate, double scale, int wintype)
|
||||
{
|
||||
int i, k;
|
||||
float* impulse = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
|
||||
@ -87,9 +87,9 @@ float* NBP::fir_mbandpass (int N, int nbp, float* flow, float* fhigh, float rate
|
||||
return impulse;
|
||||
}
|
||||
|
||||
float NBP::min_notch_width (NBP *a)
|
||||
double NBP::min_notch_width (NBP *a)
|
||||
{
|
||||
float min_width;
|
||||
double min_width;
|
||||
switch (a->wintype)
|
||||
{
|
||||
case 0:
|
||||
@ -105,23 +105,23 @@ float NBP::min_notch_width (NBP *a)
|
||||
int NBP::make_nbp (
|
||||
int nn,
|
||||
int* active,
|
||||
float* center,
|
||||
float* width,
|
||||
float* nlow,
|
||||
float* nhigh,
|
||||
float minwidth,
|
||||
double* center,
|
||||
double* width,
|
||||
double* nlow,
|
||||
double* nhigh,
|
||||
double minwidth,
|
||||
int autoincr,
|
||||
float flow,
|
||||
float fhigh,
|
||||
float* bplow,
|
||||
float* bphigh,
|
||||
double flow,
|
||||
double fhigh,
|
||||
double* bplow,
|
||||
double* bphigh,
|
||||
int* havnotch
|
||||
)
|
||||
{
|
||||
int nbp;
|
||||
int nnbp, adds;
|
||||
int i, j, k;
|
||||
float nl, nh;
|
||||
double nl, nh;
|
||||
int* del = new int[1024]; // (int *) malloc0 (1024 * sizeof (int));
|
||||
if (fhigh > flow)
|
||||
{
|
||||
@ -132,6 +132,7 @@ int NBP::make_nbp (
|
||||
else
|
||||
{
|
||||
nbp = 0;
|
||||
delete[] del;
|
||||
return nbp;
|
||||
}
|
||||
*havnotch = 0;
|
||||
@ -202,8 +203,8 @@ int NBP::make_nbp (
|
||||
void NBP::calc_nbp_lightweight (NBP *a)
|
||||
{ // calculate and set new impulse response; used when changing tune freq or shift freq
|
||||
int i;
|
||||
float fl, fh;
|
||||
float offset;
|
||||
double fl, fh;
|
||||
double offset;
|
||||
NOTCHDB *b = a->ptraddr;
|
||||
if (a->fnfrun)
|
||||
{
|
||||
@ -249,7 +250,7 @@ void NBP::calc_nbp_impulse (NBP *a)
|
||||
{ // calculates impulse response; for create_fircore() and parameter changes
|
||||
int i;
|
||||
float fl, fh;
|
||||
float offset;
|
||||
double offset;
|
||||
NOTCHDB *b = a->ptraddr;
|
||||
if (a->fnfrun)
|
||||
{
|
||||
@ -309,11 +310,11 @@ NBP* NBP::create_nbp(
|
||||
int mp,
|
||||
float* in,
|
||||
float* out,
|
||||
float flow,
|
||||
float fhigh,
|
||||
double flow,
|
||||
double fhigh,
|
||||
int rate,
|
||||
int wintype,
|
||||
float gain,
|
||||
double gain,
|
||||
int autoincr,
|
||||
int maxpb,
|
||||
NOTCHDB* ptraddr
|
||||
@ -326,7 +327,7 @@ NBP* NBP::create_nbp(
|
||||
a->size = size;
|
||||
a->nc = nc;
|
||||
a->mp = mp;
|
||||
a->rate = (float)rate;
|
||||
a->rate = (double) rate;
|
||||
a->wintype = wintype;
|
||||
a->gain = gain;
|
||||
a->in = in;
|
||||
@ -336,8 +337,8 @@ NBP* NBP::create_nbp(
|
||||
a->fhigh = fhigh;
|
||||
a->maxpb = maxpb;
|
||||
a->ptraddr = ptraddr;
|
||||
a->bplow = new float[a->maxpb]; // (float *) malloc0 (a->maxpb * sizeof (float));
|
||||
a->bphigh = new float[a->maxpb]; // (float *) malloc0 (a->maxpb * sizeof (float));
|
||||
a->bplow = new double[a->maxpb]; // (float *) malloc0 (a->maxpb * sizeof (float));
|
||||
a->bphigh = new double[a->maxpb]; // (float *) malloc0 (a->maxpb * sizeof (float));
|
||||
calc_nbp_impulse (a);
|
||||
a->p = FIRCORE::create_fircore (a->size, a->in, a->out, a->nc, a->mp, a->impulse);
|
||||
// print_impulse ("nbp.txt", a->size + 1, impulse, 1, 0);
|
||||
@ -363,7 +364,7 @@ void NBP::xnbp (NBP *a, int pos)
|
||||
if (a->run && pos == a->position)
|
||||
FIRCORE::xfircore (a->p);
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void NBP::setBuffers_nbp (NBP *a, float* in, float* out)
|
||||
@ -433,7 +434,7 @@ void NBP::UpdateNBPFilters(RXA& rxa)
|
||||
}
|
||||
}
|
||||
|
||||
int NBP::NBPAddNotch (RXA& rxa, int notch, float fcenter, float fwidth, int active)
|
||||
int NBP::NBPAddNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active)
|
||||
{
|
||||
NOTCHDB *b;
|
||||
int i, j;
|
||||
@ -463,7 +464,7 @@ int NBP::NBPAddNotch (RXA& rxa, int notch, float fcenter, float fwidth, int acti
|
||||
return rval;
|
||||
}
|
||||
|
||||
int NBP::NBPGetNotch (RXA& rxa, int notch, float* fcenter, float* fwidth, int* active)
|
||||
int NBP::NBPGetNotch (RXA& rxa, int notch, double* fcenter, double* fwidth, int* active)
|
||||
{
|
||||
NOTCHDB *a;
|
||||
int rval;
|
||||
@ -512,7 +513,7 @@ int NBP::NBPDeleteNotch (RXA& rxa, int notch)
|
||||
return rval;
|
||||
}
|
||||
|
||||
int NBP::NBPEditNotch (RXA& rxa, int notch, float fcenter, float fwidth, int active)
|
||||
int NBP::NBPEditNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active)
|
||||
{
|
||||
NOTCHDB *a;
|
||||
int rval;
|
||||
@ -539,7 +540,7 @@ void NBP::NBPGetNumNotches (RXA& rxa, int* nnotches)
|
||||
*nnotches = a->nn;
|
||||
}
|
||||
|
||||
void NBP::NBPSetTuneFrequency (RXA& rxa, float tunefreq)
|
||||
void NBP::NBPSetTuneFrequency (RXA& rxa, double tunefreq)
|
||||
{
|
||||
NOTCHDB *a;
|
||||
a = rxa.ndb.p;
|
||||
@ -551,7 +552,7 @@ void NBP::NBPSetTuneFrequency (RXA& rxa, float tunefreq)
|
||||
}
|
||||
}
|
||||
|
||||
void NBP::NBPSetShiftFrequency (RXA& rxa, float shift)
|
||||
void NBP::NBPSetShiftFrequency (RXA& rxa, double shift)
|
||||
{
|
||||
NOTCHDB *a;
|
||||
a = rxa.ndb.p;
|
||||
@ -589,7 +590,7 @@ void NBP::NBPSetRun (RXA& rxa, int run)
|
||||
a->run = run;
|
||||
}
|
||||
|
||||
void NBP::NBPSetFreqs (RXA& rxa, float flow, float fhigh)
|
||||
void NBP::NBPSetFreqs (RXA& rxa, double flow, double fhigh)
|
||||
{
|
||||
NBP *a;
|
||||
a = rxa.nbp0.p;
|
||||
@ -651,7 +652,7 @@ void NBP::NBPSetMP (RXA& rxa, int mp)
|
||||
}
|
||||
}
|
||||
|
||||
void NBP::NBPGetMinNotchWidth (RXA& rxa, float* minwidth)
|
||||
void NBP::NBPGetMinNotchWidth (RXA& rxa, double* minwidth)
|
||||
{
|
||||
NBP *a;
|
||||
a = rxa.nbp0.p;
|
||||
|
72
wdsp/nbp.hpp
72
wdsp/nbp.hpp
@ -39,14 +39,14 @@ class WDSP_API NOTCHDB
|
||||
{
|
||||
public:
|
||||
int master_run;
|
||||
float tunefreq;
|
||||
float shift;
|
||||
double tunefreq;
|
||||
double shift;
|
||||
int nn;
|
||||
int* active;
|
||||
float* fcenter;
|
||||
float* fwidth;
|
||||
float* nlow;
|
||||
float* nhigh;
|
||||
double* fcenter;
|
||||
double* fwidth;
|
||||
double* nlow;
|
||||
double* nhigh;
|
||||
int maxnotches;
|
||||
|
||||
static NOTCHDB* create_notchdb (int master_run, int maxnotches);
|
||||
@ -63,19 +63,19 @@ public:
|
||||
int size; // buffer size
|
||||
int nc; // number of filter coefficients
|
||||
int mp; // minimum phase flag
|
||||
float* in; // input buffer
|
||||
float* out; // output buffer
|
||||
float flow; // low bandpass cutoff freq
|
||||
float fhigh; // high bandpass cutoff freq
|
||||
float* impulse; // filter impulse response
|
||||
float rate; // sample rate
|
||||
float* in; // input buffer
|
||||
float* out; // output buffer
|
||||
double flow; // low bandpass cutoff freq
|
||||
double fhigh; // high bandpass cutoff freq
|
||||
float* impulse; // filter impulse response
|
||||
double rate; // sample rate
|
||||
int wintype; // filter window type
|
||||
float gain; // filter gain
|
||||
double gain; // filter gain
|
||||
int autoincr; // auto-increment notch width
|
||||
int maxpb; // maximum number of passbands
|
||||
NOTCHDB* ptraddr; // ptr to addr of notch-database data structure
|
||||
float* bplow; // array of passband lows
|
||||
float* bphigh; // array of passband highs
|
||||
double* bplow; // array of passband lows
|
||||
double* bphigh; // array of passband highs
|
||||
int numpb; // number of passbands
|
||||
FIRCORE *p;
|
||||
int havnotch;
|
||||
@ -90,11 +90,11 @@ public:
|
||||
int mp,
|
||||
float* in,
|
||||
float* out,
|
||||
float flow,
|
||||
float fhigh,
|
||||
double flow,
|
||||
double fhigh,
|
||||
int rate,
|
||||
int wintype,
|
||||
float gain,
|
||||
double gain,
|
||||
int autoincr,
|
||||
int maxpb,
|
||||
NOTCHDB* ptraddr
|
||||
@ -111,40 +111,40 @@ public:
|
||||
// RXA Properties
|
||||
static void UpdateNBPFiltersLightWeight (RXA& rxa);
|
||||
static void UpdateNBPFilters(RXA& rxa);
|
||||
static int NBPAddNotch (RXA& rxa, int notch, float fcenter, float fwidth, int active);
|
||||
static int NBPGetNotch (RXA& rxa, int notch, float* fcenter, float* fwidth, int* active);
|
||||
static int NBPAddNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active);
|
||||
static int NBPGetNotch (RXA& rxa, int notch, double* fcenter, double* fwidth, int* active);
|
||||
static int NBPDeleteNotch (RXA& rxa, int notch);
|
||||
static int NBPEditNotch (RXA& rxa, int notch, float fcenter, float fwidth, int active);
|
||||
static int NBPEditNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active);
|
||||
static void NBPGetNumNotches (RXA& rxa, int* nnotches);
|
||||
static void NBPSetTuneFrequency (RXA& rxa, float tunefreq);
|
||||
static void NBPSetShiftFrequency (RXA& rxa, float shift);
|
||||
static void NBPSetTuneFrequency (RXA& rxa, double tunefreq);
|
||||
static void NBPSetShiftFrequency (RXA& rxa, double shift);
|
||||
static void NBPSetNotchesRun (RXA& rxa, int run);
|
||||
static void NBPSetRun (RXA& rxa, int run);
|
||||
static void NBPSetFreqs (RXA& rxa, float flow, float fhigh);
|
||||
static void NBPSetFreqs (RXA& rxa, double flow, double fhigh);
|
||||
static void NBPSetWindow (RXA& rxa, int wintype);
|
||||
|
||||
static void NBPSetNC (RXA& rxa, int nc);
|
||||
static void NBPSetMP (RXA& rxa, int mp);
|
||||
|
||||
static void NBPGetMinNotchWidth (RXA& rxa, float* minwidth);
|
||||
static void NBPGetMinNotchWidth (RXA& rxa, double* minwidth);
|
||||
static void NBPSetAutoIncrease (RXA& rxa, int autoincr);
|
||||
|
||||
private:
|
||||
static float* fir_mbandpass (int N, int nbp, float* flow, float* fhigh, float rate, float scale, int wintype);
|
||||
static float min_notch_width (NBP *a);
|
||||
static float* fir_mbandpass (int N, int nbp, double* flow, double* fhigh, double rate, double scale, int wintype);
|
||||
static double min_notch_width (NBP *a);
|
||||
static int make_nbp (
|
||||
int nn,
|
||||
int* active,
|
||||
float* center,
|
||||
float* width,
|
||||
float* nlow,
|
||||
float* nhigh,
|
||||
float minwidth,
|
||||
double* center,
|
||||
double* width,
|
||||
double* nlow,
|
||||
double* nhigh,
|
||||
double minwidth,
|
||||
int autoincr,
|
||||
float flow,
|
||||
float fhigh,
|
||||
float* bplow,
|
||||
float* bphigh,
|
||||
double flow,
|
||||
double fhigh,
|
||||
double* bplow,
|
||||
double* bphigh,
|
||||
int* havnotch
|
||||
);
|
||||
static void calc_nbp_lightweight (NBP *a);
|
||||
|
146
wdsp/nob.cpp
146
wdsp/nob.cpp
@ -43,6 +43,7 @@ void NOB::init_nob (NOB *a)
|
||||
{
|
||||
int i;
|
||||
double coef;
|
||||
|
||||
a->adv_slew_count = (int)(a->advslewtime * a->samplerate);
|
||||
a->adv_count = (int)(a->advtime * a->samplerate);
|
||||
a->hang_count = (int)(a->hangtime * a->samplerate);
|
||||
@ -50,15 +51,19 @@ void NOB::init_nob (NOB *a)
|
||||
a->max_imp_seq = (int)(a->max_imp_seq_time * a->samplerate);
|
||||
a->backmult = exp (-1.0 / (a->samplerate * a->backtau));
|
||||
a->ombackmult = 1.0 - a->backmult;
|
||||
|
||||
if (a->adv_slew_count > 0)
|
||||
{
|
||||
coef = PI / (a->adv_slew_count + 1);
|
||||
|
||||
for (i = 0; i < a->adv_slew_count; i++)
|
||||
a->awave[i] = 0.5 * cos ((i + 1) * coef);
|
||||
}
|
||||
|
||||
if (a->hang_slew_count > 0)
|
||||
{
|
||||
coef = PI / a->hang_slew_count;
|
||||
|
||||
for (i = 0; i < a->hang_slew_count; i++)
|
||||
a->hwave[i] = 0.5 * cos (i * coef);
|
||||
}
|
||||
@ -150,10 +155,10 @@ void NOB::flush_nob (NOB *a)
|
||||
a->avg = 1.0;
|
||||
a->bfb_in_idx = a->filterlen - 1;
|
||||
a->ffb_in_idx = a->filterlen - 1;
|
||||
memset (a->dline, 0, a->dline_size * sizeof (wcomplex));
|
||||
memset (a->imp, 0, a->dline_size * sizeof (int));
|
||||
memset (a->bfbuff, 0, a->filterlen * sizeof (wcomplex));
|
||||
memset (a->ffbuff, 0, a->filterlen * sizeof (wcomplex));
|
||||
std::fill(a->dline, a->dline + a->dline_size * 2, 0);
|
||||
std::fill(a->imp, a->imp + a->dline_size, 0);
|
||||
std::fill(a->bfbuff, a->bfbuff + a->filterlen * 2, 0);
|
||||
std::fill(a->ffbuff, a->ffbuff + a->filterlen * 2, 0);
|
||||
}
|
||||
|
||||
void NOB::xnob (NOB *a)
|
||||
@ -179,14 +184,20 @@ void NOB::xnob (NOB *a)
|
||||
a->dline[2 * a->in_idx + 1] = a->in[2 * i + 1];
|
||||
mag = sqrt(a->dline[2 * a->in_idx + 0] * a->dline[2 * a->in_idx + 0] + a->dline[2 * a->in_idx + 1] * a->dline[2 * a->in_idx + 1]);
|
||||
a->avg = a->backmult * a->avg + a->ombackmult * mag;
|
||||
|
||||
if (mag > (a->avg * a->threshold))
|
||||
a->imp[a->in_idx] = 1;
|
||||
else
|
||||
a->imp[a->in_idx] = 0;
|
||||
if ((bf_idx = a->out_idx + a->adv_slew_count) >= a->dline_size) bf_idx -= a->dline_size;
|
||||
|
||||
if ((bf_idx = a->out_idx + a->adv_slew_count) >= a->dline_size)
|
||||
bf_idx -= a->dline_size;
|
||||
|
||||
if (a->imp[bf_idx] == 0)
|
||||
{
|
||||
if (++a->bfb_in_idx == a->filterlen) a->bfb_in_idx -= a->filterlen;
|
||||
if (++a->bfb_in_idx == a->filterlen)
|
||||
a->bfb_in_idx -= a->filterlen;
|
||||
|
||||
a->bfbuff[2 * a->bfb_in_idx + 0] = a->dline[2 * bf_idx + 0];
|
||||
a->bfbuff[2 * a->bfb_in_idx + 1] = a->dline[2 * bf_idx + 1];
|
||||
}
|
||||
@ -199,31 +210,41 @@ void NOB::xnob (NOB *a)
|
||||
a->out[2 * i + 1] = a->dline[2 * a->out_idx + 1];
|
||||
a->Ilast = a->dline[2 * a->out_idx + 0];
|
||||
a->Qlast = a->dline[2 * a->out_idx + 1];
|
||||
|
||||
if (a->imp[a->scan_idx] > 0)
|
||||
{
|
||||
a->time = 0;
|
||||
|
||||
if (a->adv_slew_count > 0)
|
||||
a->state = 1;
|
||||
else if (a->adv_count > 0)
|
||||
a->state = 2;
|
||||
else
|
||||
a->state = 3;
|
||||
|
||||
tidx = a->scan_idx;
|
||||
a->blank_count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
len = 0;
|
||||
hcount = 0;
|
||||
|
||||
while ((a->imp[tidx] > 0 || hcount > 0) && a->blank_count < a->max_imp_seq)
|
||||
{
|
||||
a->blank_count++;
|
||||
if (hcount > 0) hcount--;
|
||||
if (a->imp[tidx] > 0) hcount = a->hang_count + a->hang_slew_count;
|
||||
if (++tidx >= a->dline_size) tidx -= a->dline_size;
|
||||
if (hcount > 0)
|
||||
hcount--;
|
||||
if (a->imp[tidx] > 0)
|
||||
hcount = a->hang_count + a->hang_slew_count;
|
||||
if (++tidx >= a->dline_size)
|
||||
tidx -= a->dline_size;
|
||||
}
|
||||
|
||||
j = 1;
|
||||
len = 0;
|
||||
lidx = tidx;
|
||||
|
||||
while (j <= a->adv_slew_count + a->adv_count && len == 0)
|
||||
{
|
||||
if (a->imp[lidx] == 1)
|
||||
@ -231,16 +252,22 @@ void NOB::xnob (NOB *a)
|
||||
len = j;
|
||||
tidx = lidx;
|
||||
}
|
||||
if (++lidx >= a->dline_size) lidx -= a->dline_size;
|
||||
|
||||
if (++lidx >= a->dline_size)
|
||||
lidx -= a->dline_size;
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
if((a->blank_count += len) > a->max_imp_seq)
|
||||
{
|
||||
a->blank_count = a->max_imp_seq;
|
||||
a->overflow = 1;
|
||||
break;
|
||||
}
|
||||
} while (len != 0);
|
||||
}
|
||||
while (len != 0);
|
||||
|
||||
if (a->overflow == 0)
|
||||
{
|
||||
a->blank_count -= a->hang_slew_count;
|
||||
@ -252,37 +279,53 @@ void NOB::xnob (NOB *a)
|
||||
bfboutidx = a->bfb_in_idx;
|
||||
a->I1 = 0.0;
|
||||
a->Q1 = 0.0;
|
||||
|
||||
for (k = 0; k < a->filterlen; k++)
|
||||
{
|
||||
a->I1 += a->fcoefs[k] * a->bfbuff[2 * bfboutidx + 0];
|
||||
a->Q1 += a->fcoefs[k] * a->bfbuff[2 * bfboutidx + 1];
|
||||
if (--bfboutidx < 0) bfboutidx += a->filterlen;
|
||||
|
||||
if (--bfboutidx < 0)
|
||||
bfboutidx += a->filterlen;
|
||||
}
|
||||
}
|
||||
|
||||
if (a->mode == 2 || a->mode == 3 || a->mode == 4)
|
||||
{
|
||||
if ((ff_idx = a->scan_idx + a->blank_count) >= a->dline_size) ff_idx -= a->dline_size;
|
||||
if ((ff_idx = a->scan_idx + a->blank_count) >= a->dline_size)
|
||||
ff_idx -= a->dline_size;
|
||||
|
||||
ffcount = 0;
|
||||
|
||||
while (ffcount < a->filterlen)
|
||||
{
|
||||
if (a->imp[ff_idx] == 0)
|
||||
{
|
||||
if (++a->ffb_in_idx == a->filterlen) a->ffb_in_idx -= a->filterlen;
|
||||
if (++a->ffb_in_idx == a->filterlen)
|
||||
a->ffb_in_idx -= a->filterlen;
|
||||
|
||||
a->ffbuff[2 * a->ffb_in_idx + 0] = a->dline[2 * ff_idx + 0];
|
||||
a->ffbuff[2 * a->ffb_in_idx + 1] = a->dline[2 * ff_idx + 1];
|
||||
++ffcount;
|
||||
}
|
||||
if (++ff_idx >= a->dline_size) ff_idx -= a->dline_size;
|
||||
|
||||
if (++ff_idx >= a->dline_size)
|
||||
ff_idx -= a->dline_size;
|
||||
}
|
||||
if ((ffboutidx = a->ffb_in_idx + 1) >= a->filterlen) ffboutidx -= a->filterlen;
|
||||
|
||||
if ((ffboutidx = a->ffb_in_idx + 1) >= a->filterlen)
|
||||
ffboutidx -= a->filterlen;
|
||||
|
||||
a->I2 = 0.0;
|
||||
a->Q2 = 0.0;
|
||||
|
||||
for (k = 0; k < a->filterlen; k++)
|
||||
{
|
||||
a->I2 += a->fcoefs[k] * a->ffbuff[2 * ffboutidx + 0];
|
||||
a->Q2 += a->fcoefs[k] * a->ffbuff[2 * ffboutidx + 1];
|
||||
if (++ffboutidx >= a->filterlen) ffboutidx -= a->filterlen;
|
||||
|
||||
if (++ffboutidx >= a->filterlen)
|
||||
ffboutidx -= a->filterlen;
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,7 +366,9 @@ void NOB::xnob (NOB *a)
|
||||
else
|
||||
{
|
||||
if (a->adv_slew_count > 0)
|
||||
{
|
||||
a->state = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
a->state = 6;
|
||||
@ -332,23 +377,29 @@ void NOB::xnob (NOB *a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: // slew output in advance of blanking period
|
||||
{
|
||||
scale = 0.5 + a->awave[a->time];
|
||||
a->out[2 * i + 0] = a->Ilast * scale + (1.0 - scale) * a->I;
|
||||
a->out[2 * i + 1] = a->Qlast * scale + (1.0 - scale) * a->Q;
|
||||
|
||||
if (++a->time == a->adv_slew_count)
|
||||
{
|
||||
a->time = 0;
|
||||
|
||||
if (a->adv_count > 0)
|
||||
a->state = 2;
|
||||
else
|
||||
a->state = 3;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: // initial advance period
|
||||
{
|
||||
a->out[2 * i + 0] = a->I;
|
||||
@ -361,8 +412,10 @@ void NOB::xnob (NOB *a)
|
||||
a->state = 3;
|
||||
a->time = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: // impulse & hang period
|
||||
{
|
||||
a->out[2 * i + 0] = a->I;
|
||||
@ -378,52 +431,69 @@ void NOB::xnob (NOB *a)
|
||||
a->time = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
a->state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: // slew output after blanking period
|
||||
{
|
||||
scale = 0.5 - a->hwave[a->time];
|
||||
a->out[2 * i + 0] = a->Inext * scale + (1.0 - scale) * a->I;
|
||||
a->out[2 * i + 1] = a->Qnext * scale + (1.0 - scale) * a->Q;
|
||||
|
||||
if (++a->time == a->hang_slew_count)
|
||||
a->state = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 5:
|
||||
{
|
||||
scale = 0.5 + a->awave[a->time];
|
||||
a->out[2 * i + 0] = a->Ilast * scale;
|
||||
a->out[2 * i + 1] = a->Qlast * scale;
|
||||
|
||||
if (++a->time == a->adv_slew_count)
|
||||
{
|
||||
a->state = 6;
|
||||
a->time = 0;
|
||||
a->blank_count += a->adv_count + a->filterlen;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 6:
|
||||
{
|
||||
a->out[2 * i + 0] = 0.0;
|
||||
a->out[2 * i + 1] = 0.0;
|
||||
|
||||
if (++a->time == a->blank_count)
|
||||
a->state = 7;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 7:
|
||||
{
|
||||
a->out[2 * i + 0] = 0.0;
|
||||
a->out[2 * i + 1] = 0.0;
|
||||
staydown = 0;
|
||||
a->time = 0;
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count + a->hang_count) >= a->dline_size) tidx -= a->dline_size;
|
||||
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count + a->hang_count) >= a->dline_size)
|
||||
tidx -= a->dline_size;
|
||||
|
||||
while (a->time++ <= a->adv_count + a->adv_slew_count + a->hang_slew_count + a->hang_count) // CHECK EXACT COUNTS!!!!!!!!!!!!!!!!!!!!!!!
|
||||
{
|
||||
if (a->imp[tidx] == 1) staydown = 1;
|
||||
if (--tidx < 0) tidx += a->dline_size;
|
||||
}
|
||||
|
||||
if (staydown == 0)
|
||||
{
|
||||
if (a->hang_count > 0)
|
||||
@ -435,8 +505,13 @@ void NOB::xnob (NOB *a)
|
||||
{
|
||||
a->state = 9;
|
||||
a->time = 0;
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count + a->hang_count - a->adv_count - a->adv_slew_count) >= a->dline_size) tidx -= a->dline_size;
|
||||
if (tidx < 0) tidx += a->dline_size;
|
||||
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count + a->hang_count - a->adv_count - a->adv_slew_count) >= a->dline_size)
|
||||
tidx -= a->dline_size;
|
||||
|
||||
if (tidx < 0)
|
||||
tidx += a->dline_size;
|
||||
|
||||
a->Inext = a->dline[2 * tidx + 0];
|
||||
a->Qnext = a->dline[2 * tidx + 1];
|
||||
}
|
||||
@ -446,20 +521,28 @@ void NOB::xnob (NOB *a)
|
||||
a->overflow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
a->out[2 * i + 0] = 0.0;
|
||||
a->out[2 * i + 1] = 0.0;
|
||||
|
||||
if (++a->time == a->hang_count)
|
||||
{
|
||||
if (a->hang_slew_count > 0)
|
||||
{
|
||||
a->state = 9;
|
||||
a->time = 0;
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count - a->adv_count - a->adv_slew_count) >= a->dline_size) tidx -= a->dline_size;
|
||||
if (tidx < 0) tidx += a->dline_size;
|
||||
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count - a->adv_count - a->adv_slew_count) >= a->dline_size)
|
||||
tidx -= a->dline_size;
|
||||
|
||||
if (tidx < 0)
|
||||
tidx += a->dline_size;
|
||||
|
||||
a->Inext = a->dline[2 * tidx + 0];
|
||||
a->Qnext = a->dline[2 * tidx + 1];
|
||||
}
|
||||
@ -469,8 +552,10 @@ void NOB::xnob (NOB *a)
|
||||
a->overflow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 9:
|
||||
{
|
||||
scale = 0.5 - a->hwave[a->time];
|
||||
@ -482,16 +567,25 @@ void NOB::xnob (NOB *a)
|
||||
a->state = 0;
|
||||
a->overflow = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (++a->in_idx == a->dline_size) a->in_idx = 0;
|
||||
if (++a->scan_idx == a->dline_size) a->scan_idx = 0;
|
||||
if (++a->out_idx == a->dline_size) a->out_idx = 0;
|
||||
|
||||
if (++a->in_idx == a->dline_size)
|
||||
a->in_idx = 0;
|
||||
|
||||
if (++a->scan_idx == a->dline_size)
|
||||
a->scan_idx = 0;
|
||||
|
||||
if (++a->out_idx == a->dline_size)
|
||||
a->out_idx = 0;
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->buffsize * sizeof (wcomplex));
|
||||
{
|
||||
std::copy(a->in, a->in + a->buffsize * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void NOB::setBuffers_nob (NOB *a, float* in, float* out)
|
||||
|
@ -83,8 +83,8 @@ void OSCTRL::destroy_osctrl (OSCTRL *a)
|
||||
|
||||
void OSCTRL::flush_osctrl (OSCTRL *a)
|
||||
{
|
||||
memset (a->dl, 0, a->dl_len * sizeof (wcomplex));
|
||||
memset (a->dlenv, 0, a->pn * sizeof (float));
|
||||
std::fill(a->dl, a->dl + a->dl_len * 2, 0);
|
||||
std::fill(a->dlenv, a->dlenv + a->pn, 0);
|
||||
}
|
||||
|
||||
void OSCTRL::xosctrl (OSCTRL *a)
|
||||
@ -116,7 +116,7 @@ void OSCTRL::xosctrl (OSCTRL *a)
|
||||
}
|
||||
}
|
||||
else if (a->inbuff != a->outbuff)
|
||||
memcpy (a->outbuff, a->inbuff, a->size * sizeof (wcomplex));
|
||||
std::copy(a->inbuff, a->inbuff + a->size * 2, a->outbuff);
|
||||
}
|
||||
|
||||
void OSCTRL::setBuffers_osctrl (OSCTRL *a, float* in, float* out)
|
||||
|
@ -37,9 +37,9 @@ PANEL* PANEL::create_panel (
|
||||
int size,
|
||||
float* in,
|
||||
float* out,
|
||||
float gain1,
|
||||
float gain2I,
|
||||
float gain2Q,
|
||||
double gain1,
|
||||
double gain2I,
|
||||
double gain2Q,
|
||||
int inselect,
|
||||
int copy
|
||||
)
|
||||
@ -70,9 +70,9 @@ void PANEL::flush_panel (PANEL *)
|
||||
void PANEL::xpanel (PANEL *a)
|
||||
{
|
||||
int i;
|
||||
float I, Q;
|
||||
float gainI = a->gain1 * a->gain2I;
|
||||
float gainQ = a->gain1 * a->gain2Q;
|
||||
double I, Q;
|
||||
double gainI = a->gain1 * a->gain2I;
|
||||
double gainQ = a->gain1 * a->gain2Q;
|
||||
// inselect is either 0(neither), 1(Q), 2(I), or 3(both)
|
||||
switch (a->copy)
|
||||
{
|
||||
@ -147,20 +147,20 @@ void PANEL::SetPanelSelect (RXA& rxa, int select)
|
||||
rxa.panel.p->inselect = select;
|
||||
}
|
||||
|
||||
void PANEL::SetPanelGain1 (RXA& rxa, float gain)
|
||||
void PANEL::SetPanelGain1 (RXA& rxa, double gain)
|
||||
{
|
||||
rxa.panel.p->gain1 = gain;
|
||||
}
|
||||
|
||||
void PANEL::SetPanelGain2 (RXA& rxa, float gainI, float gainQ)
|
||||
void PANEL::SetPanelGain2 (RXA& rxa, double gainI, double gainQ)
|
||||
{
|
||||
rxa.panel.p->gain2I = gainI;
|
||||
rxa.panel.p->gain2Q = gainQ;
|
||||
}
|
||||
|
||||
void PANEL::SetPanelPan (RXA& rxa, float pan)
|
||||
void PANEL::SetPanelPan (RXA& rxa, double pan)
|
||||
{
|
||||
float gain1, gain2;
|
||||
double gain1, gain2;
|
||||
|
||||
if (pan <= 0.5)
|
||||
{
|
||||
@ -198,7 +198,7 @@ void PANEL::SetPanelRun (TXA& txa, int run)
|
||||
txa.panel.p->run = run;
|
||||
}
|
||||
|
||||
void PANEL::SetPanelGain1 (TXA& txa, float gain)
|
||||
void PANEL::SetPanelGain1 (TXA& txa, double gain)
|
||||
{
|
||||
txa.panel.p->gain1 = gain;
|
||||
//print_message ("micgainset.txt", "Set MIC Gain to", (int)(100.0 * gain), 0, 0);
|
||||
|
@ -42,9 +42,9 @@ public:
|
||||
int size;
|
||||
float* in;
|
||||
float* out;
|
||||
float gain1;
|
||||
float gain2I;
|
||||
float gain2Q;
|
||||
double gain1;
|
||||
double gain2I;
|
||||
double gain2Q;
|
||||
int inselect;
|
||||
int copy;
|
||||
|
||||
@ -53,9 +53,9 @@ public:
|
||||
int size,
|
||||
float* in,
|
||||
float* out,
|
||||
float gain1,
|
||||
float gain2I,
|
||||
float gain2Q,
|
||||
double gain1,
|
||||
double gain2I,
|
||||
double gain2Q,
|
||||
int inselect,
|
||||
int copy
|
||||
);
|
||||
@ -68,14 +68,14 @@ public:
|
||||
// RXA Properties
|
||||
static void SetPanelRun (RXA& rxa, int run);
|
||||
static void SetPanelSelect (RXA& rxa, int select);
|
||||
static void SetPanelGain1 (RXA& rxa, float gain);
|
||||
static void SetPanelGain2 (RXA& rxa, float gainI, float gainQ);
|
||||
static void SetPanelPan (RXA& rxa, float pan);
|
||||
static void SetPanelGain1 (RXA& rxa, double gain);
|
||||
static void SetPanelGain2 (RXA& rxa, double gainI, double gainQ);
|
||||
static void SetPanelPan (RXA& rxa, double pan);
|
||||
static void SetPanelCopy (RXA& rxa, int copy);
|
||||
static void SetPanelBinaural (RXA& rxa, int bin);
|
||||
// TXA Properties
|
||||
static void SetPanelRun (TXA& txa, int run);
|
||||
static void SetPanelGain1 (TXA& txa, float gain);
|
||||
static void SetPanelGain1 (TXA& txa, double gain);
|
||||
static void SetPanelSelect (TXA& txa, int select);
|
||||
};
|
||||
|
||||
|
@ -42,43 +42,63 @@ void RESAMPLE::calc_resample (RESAMPLE *a)
|
||||
int x, y, z;
|
||||
int i, j, k;
|
||||
int min_rate;
|
||||
float full_rate;
|
||||
float fc_norm_high, fc_norm_low;
|
||||
double full_rate;
|
||||
double fc_norm_high, fc_norm_low;
|
||||
float* impulse;
|
||||
a->fc = a->fcin;
|
||||
a->ncoef = a->ncoefin;
|
||||
x = a->in_rate;
|
||||
y = a->out_rate;
|
||||
|
||||
while (y != 0)
|
||||
{
|
||||
z = y;
|
||||
y = x % y;
|
||||
x = z;
|
||||
}
|
||||
|
||||
a->L = a->out_rate / x;
|
||||
a->M = a->in_rate / x;
|
||||
if (a->in_rate < a->out_rate) min_rate = a->in_rate;
|
||||
else min_rate = a->out_rate;
|
||||
if (a->fc == 0.0) a->fc = 0.45 * (float)min_rate;
|
||||
full_rate = (float)(a->in_rate * a->L);
|
||||
|
||||
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
|
||||
min_rate = a->out_rate;
|
||||
|
||||
if (a->fc == 0.0)
|
||||
a->fc = 0.45 * (float)min_rate;
|
||||
|
||||
full_rate = (double) (a->in_rate * a->L);
|
||||
fc_norm_high = a->fc / full_rate;
|
||||
|
||||
if (a->fc_low < 0.0)
|
||||
fc_norm_low = - fc_norm_high;
|
||||
else
|
||||
fc_norm_low = a->fc_low / full_rate;
|
||||
if (a->ncoef == 0) a->ncoef = (int)(140.0 * full_rate / min_rate);
|
||||
|
||||
if (a->ncoef == 0)
|
||||
a->ncoef = (int)(140.0 * full_rate / min_rate);
|
||||
|
||||
a->ncoef = (a->ncoef / a->L + 1) * a->L;
|
||||
a->cpp = a->ncoef / a->L;
|
||||
a->h = new double[a->ncoef]; // (float *)malloc0(a->ncoef * sizeof(float));
|
||||
impulse = FIR::fir_bandpass(a->ncoef, fc_norm_low, fc_norm_high, 1.0, 1, 0, a->gain * (float)a->L);
|
||||
impulse = FIR::fir_bandpass(a->ncoef, fc_norm_low, fc_norm_high, 1.0, 1, 0, a->gain * (double)a->L);
|
||||
i = 0;
|
||||
|
||||
for (j = 0; j < a->L; j++)
|
||||
{
|
||||
for (k = 0; k < a->ncoef; k += a->L)
|
||||
a->h[i++] = impulse[j + k];
|
||||
}
|
||||
|
||||
a->ringsize = a->cpp;
|
||||
a->ring = new double[a->ringsize]; // (float *)malloc0(a->ringsize * sizeof(complex));
|
||||
a->idx_in = a->ringsize - 1;
|
||||
a->phnum = 0;
|
||||
|
||||
delete[] (impulse);
|
||||
}
|
||||
|
||||
@ -135,6 +155,7 @@ void RESAMPLE::flush_resample (RESAMPLE *a)
|
||||
int RESAMPLE::xresample (RESAMPLE *a)
|
||||
{
|
||||
int outsamps = 0;
|
||||
|
||||
if (a->run)
|
||||
{
|
||||
int i, j, n;
|
||||
@ -145,28 +166,39 @@ int RESAMPLE::xresample (RESAMPLE *a)
|
||||
{
|
||||
a->ring[2 * a->idx_in + 0] = a->in[2 * i + 0];
|
||||
a->ring[2 * a->idx_in + 1] = a->in[2 * i + 1];
|
||||
|
||||
while (a->phnum < a->L)
|
||||
{
|
||||
I = 0.0;
|
||||
Q = 0.0;
|
||||
n = a->cpp * a->phnum;
|
||||
|
||||
for (j = 0; j < a->cpp; j++)
|
||||
{
|
||||
if ((idx_out = a->idx_in + j) >= a->ringsize) idx_out -= a->ringsize;
|
||||
if ((idx_out = a->idx_in + j) >= a->ringsize)
|
||||
idx_out -= a->ringsize;
|
||||
|
||||
I += a->h[n + j] * a->ring[2 * idx_out + 0];
|
||||
Q += a->h[n + j] * a->ring[2 * idx_out + 1];
|
||||
}
|
||||
|
||||
a->out[2 * outsamps + 0] = I;
|
||||
a->out[2 * outsamps + 1] = Q;
|
||||
outsamps++;
|
||||
a->phnum += a->M;
|
||||
}
|
||||
|
||||
a->phnum -= a->L;
|
||||
if (--a->idx_in < 0) a->idx_in = a->ringsize - 1;
|
||||
|
||||
if (--a->idx_in < 0)
|
||||
a->idx_in = a->ringsize - 1;
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
return outsamps;
|
||||
}
|
||||
|
||||
@ -196,7 +228,7 @@ void RESAMPLE::setOutRate_resample(RESAMPLE *a, int rate)
|
||||
calc_resample (a);
|
||||
}
|
||||
|
||||
void RESAMPLE::setFCLow_resample (RESAMPLE *a, float fc_low)
|
||||
void RESAMPLE::setFCLow_resample (RESAMPLE *a, double fc_low)
|
||||
{
|
||||
if (fc_low != a->fc_low)
|
||||
{
|
||||
@ -206,7 +238,7 @@ void RESAMPLE::setFCLow_resample (RESAMPLE *a, float fc_low)
|
||||
}
|
||||
}
|
||||
|
||||
void RESAMPLE::setBandwidth_resample (RESAMPLE *a, float fc_low, float fc_high)
|
||||
void RESAMPLE::setBandwidth_resample (RESAMPLE *a, double fc_low, double fc_high)
|
||||
{
|
||||
if (fc_low != a->fc_low || fc_high != a->fcin)
|
||||
{
|
||||
@ -241,130 +273,4 @@ void RESAMPLE::destroy_resampleV (void* ptr)
|
||||
destroy_resample ( (RESAMPLE*) ptr );
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* *
|
||||
* VERSION FOR NON-COMPLEX FLOATS *
|
||||
* *
|
||||
************************************************************************************************/
|
||||
|
||||
RESAMPLEF* RESAMPLEF::create_resampleF ( int run, int size, float* in, float* out, int in_rate, int out_rate)
|
||||
{
|
||||
RESAMPLEF *a = new RESAMPLEF;
|
||||
int x, y, z;
|
||||
int i, j, k;
|
||||
int min_rate;
|
||||
float full_rate;
|
||||
float fc;
|
||||
float fc_norm;
|
||||
float* impulse;
|
||||
a->run = run;
|
||||
a->size = size;
|
||||
a->in = in;
|
||||
a->out = out;
|
||||
x = in_rate;
|
||||
y = out_rate;
|
||||
while (y != 0)
|
||||
{
|
||||
z = y;
|
||||
y = x % y;
|
||||
x = z;
|
||||
}
|
||||
a->L = out_rate / x;
|
||||
a->M = in_rate / x;
|
||||
if (in_rate < out_rate) min_rate = in_rate;
|
||||
else min_rate = out_rate;
|
||||
fc = 0.45 * (float)min_rate;
|
||||
full_rate = (float)(in_rate * a->L);
|
||||
fc_norm = fc / full_rate;
|
||||
a->ncoef = (int)(60.0 / fc_norm);
|
||||
a->ncoef = (a->ncoef / a->L + 1) * a->L;
|
||||
a->cpp = a->ncoef / a->L;
|
||||
a->h = new float[a->ncoef]; // (float *) malloc0 (a->ncoef * sizeof (float));
|
||||
impulse = FIR::fir_bandpass (a->ncoef, -fc_norm, +fc_norm, 1.0, 1, 0, (float)a->L);
|
||||
i = 0;
|
||||
for (j = 0; j < a->L; j ++)
|
||||
for (k = 0; k < a->ncoef; k += a->L)
|
||||
a->h[i++] = impulse[j + k];
|
||||
a->ringsize = a->cpp;
|
||||
a->ring = new float[a->ringsize]; //(float *) malloc0 (a->ringsize * sizeof (float));
|
||||
a->idx_in = a->ringsize - 1;
|
||||
a->phnum = 0;
|
||||
delete[] (impulse);
|
||||
return a;
|
||||
}
|
||||
|
||||
void RESAMPLEF::destroy_resampleF (RESAMPLEF *a)
|
||||
{
|
||||
delete[] (a->ring);
|
||||
delete[] (a->h);
|
||||
delete (a);
|
||||
}
|
||||
|
||||
void RESAMPLEF::flush_resampleF (RESAMPLEF *a)
|
||||
{
|
||||
memset (a->ring, 0, a->ringsize * sizeof (float));
|
||||
a->idx_in = a->ringsize - 1;
|
||||
a->phnum = 0;
|
||||
}
|
||||
|
||||
int RESAMPLEF::xresampleF (RESAMPLEF *a)
|
||||
{
|
||||
int outsamps = 0;
|
||||
if (a->run)
|
||||
{
|
||||
int i, j, n;
|
||||
int idx_out;
|
||||
float I;
|
||||
|
||||
for (i = 0; i < a->size; i++)
|
||||
{
|
||||
a->ring[a->idx_in] = (float)a->in[i];
|
||||
|
||||
while (a->phnum < a->L)
|
||||
{
|
||||
I = 0.0;
|
||||
n = a->cpp * a->phnum;
|
||||
for (j = 0; j < a->cpp; j++)
|
||||
{
|
||||
if ((idx_out = a->idx_in + j) >= a->ringsize) idx_out -= a->ringsize;
|
||||
I += a->h[n + j] * a->ring[idx_out];
|
||||
}
|
||||
a->out[outsamps] = (float)I;
|
||||
|
||||
outsamps++;
|
||||
a->phnum += a->M;
|
||||
}
|
||||
a->phnum -= a->L;
|
||||
if (--a->idx_in < 0) a->idx_in = a->ringsize - 1;
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (float));
|
||||
return outsamps;
|
||||
}
|
||||
|
||||
// Exported calls
|
||||
|
||||
|
||||
void* RESAMPLEF::create_resampleFV (int in_rate, int out_rate)
|
||||
{
|
||||
return (void *) create_resampleF (1, 0, 0, 0, in_rate, out_rate);
|
||||
}
|
||||
|
||||
|
||||
void RESAMPLEF::xresampleFV (float* input, float* output, int numsamps, int* outsamps, void* ptr)
|
||||
{
|
||||
RESAMPLEF *a = (RESAMPLEF*) ptr;
|
||||
a->in = input;
|
||||
a->out = output;
|
||||
a->size = numsamps;
|
||||
*outsamps = xresampleF(a);
|
||||
}
|
||||
|
||||
|
||||
void RESAMPLEF::destroy_resampleFV (void* ptr)
|
||||
{
|
||||
destroy_resampleF ( (RESAMPLEF*) ptr );
|
||||
}
|
||||
|
||||
} // namespace WDSP
|
||||
|
@ -80,8 +80,8 @@ public:
|
||||
static void setSize_resample(RESAMPLE *a, int size);
|
||||
static void setInRate_resample(RESAMPLE *a, int rate);
|
||||
static void setOutRate_resample(RESAMPLE *a, int rate);
|
||||
static void setFCLow_resample (RESAMPLE *a, float fc_low);
|
||||
static void setBandwidth_resample (RESAMPLE *a, float fc_low, float fc_high);
|
||||
static void setFCLow_resample (RESAMPLE *a, double fc_low);
|
||||
static void setBandwidth_resample (RESAMPLE *a, double fc_low, double fc_high);
|
||||
// Exported calls
|
||||
static void* create_resampleV (int in_rate, int out_rate);
|
||||
static void xresampleV (float* input, float* output, int numsamps, int* outsamps, void* ptr);
|
||||
@ -92,46 +92,6 @@ private:
|
||||
static void decalc_resample (RESAMPLE *a);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/************************************************************************************************
|
||||
* *
|
||||
* VERSION FOR NON-COMPLEX FLOATS *
|
||||
* *
|
||||
************************************************************************************************/
|
||||
|
||||
#ifndef wdsp_resampleF_h
|
||||
#define wdsp_resampleF_h
|
||||
|
||||
#include "export.h"
|
||||
|
||||
class WDSP_API RESAMPLEF
|
||||
{
|
||||
public:
|
||||
int run; // run
|
||||
int size; // number of input samples per buffer
|
||||
float* in; // input buffer for resampler
|
||||
float* out; // output buffer for resampler
|
||||
int idx_in; // index for input into ring
|
||||
int ncoef; // number of coefficients
|
||||
int L; // interpolation factor
|
||||
int M; // decimation factor
|
||||
float* h; // coefficients
|
||||
int ringsize; // number of values the ring buffer holds
|
||||
float* ring; // ring buffer
|
||||
int cpp; // coefficients of the phase
|
||||
int phnum; // phase number
|
||||
|
||||
static RESAMPLEF* create_resampleF (int run, int size, float* in, float* out, int in_rate, int out_rate);
|
||||
static void destroy_resampleF (RESAMPLEF *a);
|
||||
static void flush_resampleF (RESAMPLEF *a);
|
||||
static int xresampleF (RESAMPLEF *a);
|
||||
// Exported calls
|
||||
static void* create_resampleFV (int in_rate, int out_rate);
|
||||
static void xresampleFV (float* input, float* output, int numsamps, int* outsamps, void* ptr);
|
||||
static void destroy_resampleFV (void* ptr);
|
||||
};
|
||||
|
||||
} // namespace WDSP
|
||||
|
||||
#endif
|
||||
|
185
wdsp/resamplef.cpp
Normal file
185
wdsp/resamplef.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
/* resample.c
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
#include "comm.hpp"
|
||||
#include "fir.hpp"
|
||||
#include "resamplef.hpp"
|
||||
|
||||
namespace WDSP {
|
||||
|
||||
/************************************************************************************************
|
||||
* *
|
||||
* VERSION FOR NON-COMPLEX FLOATS *
|
||||
* *
|
||||
************************************************************************************************/
|
||||
|
||||
RESAMPLEF* RESAMPLEF::create_resampleF ( int run, int size, float* in, float* out, int in_rate, int out_rate)
|
||||
{
|
||||
RESAMPLEF *a = new RESAMPLEF;
|
||||
int x, y, z;
|
||||
int i, j, k;
|
||||
int min_rate;
|
||||
float full_rate;
|
||||
float fc;
|
||||
float fc_norm;
|
||||
float* impulse;
|
||||
a->run = run;
|
||||
a->size = size;
|
||||
a->in = in;
|
||||
a->out = out;
|
||||
x = in_rate;
|
||||
y = out_rate;
|
||||
|
||||
while (y != 0)
|
||||
{
|
||||
z = y;
|
||||
y = x % y;
|
||||
x = z;
|
||||
}
|
||||
|
||||
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
|
||||
min_rate = out_rate;
|
||||
|
||||
fc = 0.45 * (float)min_rate;
|
||||
full_rate = (float)(in_rate * a->L);
|
||||
fc_norm = fc / full_rate;
|
||||
a->ncoef = (int)(60.0 / fc_norm);
|
||||
a->ncoef = (a->ncoef / a->L + 1) * a->L;
|
||||
a->cpp = a->ncoef / a->L;
|
||||
a->h = new float[a->ncoef]; // (float *) malloc0 (a->ncoef * sizeof (float));
|
||||
impulse = FIR::fir_bandpass (a->ncoef, -fc_norm, +fc_norm, 1.0, 1, 0, (float)a->L);
|
||||
i = 0;
|
||||
|
||||
for (j = 0; j < a->L; j ++)
|
||||
{
|
||||
for (k = 0; k < a->ncoef; k += a->L)
|
||||
a->h[i++] = impulse[j + k];
|
||||
}
|
||||
|
||||
a->ringsize = a->cpp;
|
||||
a->ring = new float[a->ringsize]; //(float *) malloc0 (a->ringsize * sizeof (float));
|
||||
a->idx_in = a->ringsize - 1;
|
||||
a->phnum = 0;
|
||||
|
||||
delete[] (impulse);
|
||||
return a;
|
||||
}
|
||||
|
||||
void RESAMPLEF::destroy_resampleF (RESAMPLEF *a)
|
||||
{
|
||||
delete[] (a->ring);
|
||||
delete[] (a->h);
|
||||
delete (a);
|
||||
}
|
||||
|
||||
void RESAMPLEF::flush_resampleF (RESAMPLEF *a)
|
||||
{
|
||||
memset (a->ring, 0, a->ringsize * sizeof (float));
|
||||
a->idx_in = a->ringsize - 1;
|
||||
a->phnum = 0;
|
||||
}
|
||||
|
||||
int RESAMPLEF::xresampleF (RESAMPLEF *a)
|
||||
{
|
||||
int outsamps = 0;
|
||||
|
||||
if (a->run)
|
||||
{
|
||||
int i, j, n;
|
||||
int idx_out;
|
||||
float I;
|
||||
|
||||
for (i = 0; i < a->size; i++)
|
||||
{
|
||||
a->ring[a->idx_in] = (float)a->in[i];
|
||||
|
||||
while (a->phnum < a->L)
|
||||
{
|
||||
I = 0.0;
|
||||
n = a->cpp * a->phnum;
|
||||
|
||||
for (j = 0; j < a->cpp; j++)
|
||||
{
|
||||
if ((idx_out = a->idx_in + j) >= a->ringsize)
|
||||
idx_out -= a->ringsize;
|
||||
|
||||
I += a->h[n + j] * a->ring[idx_out];
|
||||
}
|
||||
|
||||
a->out[outsamps] = (float)I;
|
||||
|
||||
outsamps++;
|
||||
a->phnum += a->M;
|
||||
}
|
||||
|
||||
a->phnum -= a->L;
|
||||
|
||||
if (--a->idx_in < 0)
|
||||
a->idx_in = a->ringsize - 1;
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
{
|
||||
memcpy (a->out, a->in, a->size * sizeof (float));
|
||||
}
|
||||
|
||||
return outsamps;
|
||||
}
|
||||
|
||||
// Exported calls
|
||||
|
||||
|
||||
void* RESAMPLEF::create_resampleFV (int in_rate, int out_rate)
|
||||
{
|
||||
return (void *) create_resampleF (1, 0, 0, 0, in_rate, out_rate);
|
||||
}
|
||||
|
||||
|
||||
void RESAMPLEF::xresampleFV (float* input, float* output, int numsamps, int* outsamps, void* ptr)
|
||||
{
|
||||
RESAMPLEF *a = (RESAMPLEF*) ptr;
|
||||
a->in = input;
|
||||
a->out = output;
|
||||
a->size = numsamps;
|
||||
*outsamps = xresampleF(a);
|
||||
}
|
||||
|
||||
|
||||
void RESAMPLEF::destroy_resampleFV (void* ptr)
|
||||
{
|
||||
destroy_resampleF ( (RESAMPLEF*) ptr );
|
||||
}
|
||||
|
||||
} // namespace WDSP
|
70
wdsp/resamplef.hpp
Normal file
70
wdsp/resamplef.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
/* resample.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
|
||||
|
||||
*/
|
||||
|
||||
/************************************************************************************************
|
||||
* *
|
||||
* VERSION FOR NON-COMPLEX FLOATS *
|
||||
* *
|
||||
************************************************************************************************/
|
||||
|
||||
#ifndef wdsp_resampleF_h
|
||||
#define wdsp_resampleF_h
|
||||
|
||||
#include "export.h"
|
||||
|
||||
namespace WDSP {
|
||||
|
||||
class WDSP_API RESAMPLEF
|
||||
{
|
||||
public:
|
||||
int run; // run
|
||||
int size; // number of input samples per buffer
|
||||
float* in; // input buffer for resampler
|
||||
float* out; // output buffer for resampler
|
||||
int idx_in; // index for input into ring
|
||||
int ncoef; // number of coefficients
|
||||
int L; // interpolation factor
|
||||
int M; // decimation factor
|
||||
float* h; // coefficients
|
||||
int ringsize; // number of values the ring buffer holds
|
||||
float* ring; // ring buffer
|
||||
int cpp; // coefficients of the phase
|
||||
int phnum; // phase number
|
||||
|
||||
static RESAMPLEF* create_resampleF (int run, int size, float* in, float* out, int in_rate, int out_rate);
|
||||
static void destroy_resampleF (RESAMPLEF *a);
|
||||
static void flush_resampleF (RESAMPLEF *a);
|
||||
static int xresampleF (RESAMPLEF *a);
|
||||
// Exported calls
|
||||
static void* create_resampleFV (int in_rate, int out_rate);
|
||||
static void xresampleFV (float* input, float* output, int numsamps, int* outsamps, void* ptr);
|
||||
static void destroy_resampleFV (void* ptr);
|
||||
};
|
||||
|
||||
} // namespace WDSP
|
||||
|
||||
#endif
|
@ -334,8 +334,8 @@ void RMATCH::xrmatchIN (void* b, float* in)
|
||||
second = 0;
|
||||
}
|
||||
|
||||
memcpy (a->baux, a->ring + 2 * a->iout, first * sizeof (wcomplex));
|
||||
memcpy (a->baux + 2 * first, a->ring, second * sizeof (wcomplex));
|
||||
std::copy(a->ring + 2 * a->iout, a->ring + 2 * a->iout + first * 2, a->baux);
|
||||
std::copy(a->ring, a->ring + second * 2, a->baux + 2 * first);
|
||||
// a->iout = (a->iout + ovfl + a->rsize / 2) % a->rsize;
|
||||
a->iout = (a->iout + ovfl) % a->rsize; //
|
||||
}
|
||||
@ -351,8 +351,8 @@ void RMATCH::xrmatchIN (void* b, float* in)
|
||||
second = 0;
|
||||
}
|
||||
|
||||
memcpy (a->ring + 2 * a->iin, a->resout, first * sizeof (wcomplex));
|
||||
memcpy (a->ring, a->resout + 2 * first, second * sizeof (wcomplex));
|
||||
std::copy(a->resout, a->resout + first * 2, a->ring + 2 * a->iin);
|
||||
std::copy(a->resout + 2 * first, a->resout + 2 * first + second * 2, a->ring);
|
||||
|
||||
if (a->ucnt >= 0)
|
||||
upslew(a, newsamps);
|
||||
@ -427,8 +427,8 @@ void RMATCH::dslew (RMATCH *a)
|
||||
first = zeros;
|
||||
second = 0;
|
||||
}
|
||||
memset (a->ring + 2 * i, 0, first * sizeof (wcomplex));
|
||||
memset (a->ring, 0, second * sizeof (wcomplex));
|
||||
std::fill(a->ring + 2 * i, a->ring + 2 * i + first * 2, 0);
|
||||
std::fill(a->ring, a->ring + second * 2, 0);
|
||||
n += zeros; //
|
||||
} //
|
||||
// a->n_ring = a->outsize + a->rsize / 2;
|
||||
@ -464,8 +464,8 @@ void RMATCH::xrmatchOUT (void* b, float* out)
|
||||
second = 0;
|
||||
}
|
||||
|
||||
memcpy (a->out, a->ring + 2 * a->iout, first * sizeof (wcomplex));
|
||||
memcpy (a->out + 2 * first, a->ring, second * sizeof (wcomplex));
|
||||
std::copy(a->ring + 2 * a->iout, a->ring + 2 * a->iout + first * 2, a->out);
|
||||
std::copy(a->ring, a->ring + second * 2, a->out + 2 * first);
|
||||
a->iout = (a->iout + a->outsize) % a->rsize;
|
||||
a->n_ring -= a->outsize;
|
||||
a->dlast[0] = a->out[2 * (a->outsize - 1) + 0];
|
||||
|
@ -38,14 +38,14 @@ void SHIFT::calc_shift (SHIFT *a)
|
||||
a->sin_delta = sin (a->delta);
|
||||
}
|
||||
|
||||
SHIFT* SHIFT::create_shift (int run, int size, float* in, float* out, int rate, float fshift)
|
||||
SHIFT* SHIFT::create_shift (int run, int size, float* in, float* out, int rate, double fshift)
|
||||
{
|
||||
SHIFT *a = new SHIFT;
|
||||
a->run = run;
|
||||
a->size = size;
|
||||
a->in = in;
|
||||
a->out = out;
|
||||
a->rate = (float)rate;
|
||||
a->rate = (double) rate;
|
||||
a->shift = fshift;
|
||||
a->phase = 0.0;
|
||||
calc_shift (a);
|
||||
@ -67,9 +67,10 @@ void SHIFT::xshift (SHIFT *a)
|
||||
if (a->run)
|
||||
{
|
||||
int i;
|
||||
float I1, Q1, t1, t2;
|
||||
float cos_phase = cos (a->phase);
|
||||
float sin_phase = sin (a->phase);
|
||||
double I1, Q1, t1, t2;
|
||||
double cos_phase = cos (a->phase);
|
||||
double sin_phase = sin (a->phase);
|
||||
|
||||
for (i = 0; i < a->size; i++)
|
||||
{
|
||||
I1 = a->in[2 * i + 0];
|
||||
@ -81,12 +82,18 @@ void SHIFT::xshift (SHIFT *a)
|
||||
cos_phase = t1 * a->cos_delta - t2 * a->sin_delta;
|
||||
sin_phase = t1 * a->sin_delta + t2 * a->cos_delta;
|
||||
a->phase += a->delta;
|
||||
if (a->phase >= TWOPI) a->phase -= TWOPI;
|
||||
if (a->phase < 0.0 ) a->phase += TWOPI;
|
||||
|
||||
if (a->phase >= TWOPI)
|
||||
a->phase -= TWOPI;
|
||||
|
||||
if (a->phase < 0.0 )
|
||||
a->phase += TWOPI;
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
{
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void SHIFT::setBuffers_shift(SHIFT *a, float* in, float* out)
|
||||
@ -119,7 +126,7 @@ void SHIFT::SetShiftRun (RXA& rxa, int run)
|
||||
rxa.shift.p->run = run;
|
||||
}
|
||||
|
||||
void SHIFT::SetShiftFreq (RXA& rxa, float fshift)
|
||||
void SHIFT::SetShiftFreq (RXA& rxa, double fshift)
|
||||
{
|
||||
rxa.shift.p->shift = fshift;
|
||||
calc_shift (rxa.shift.p);
|
||||
|
@ -41,14 +41,14 @@ public:
|
||||
int size;
|
||||
float* in;
|
||||
float* out;
|
||||
float rate;
|
||||
float shift;
|
||||
float phase;
|
||||
float delta;
|
||||
float cos_delta;
|
||||
float sin_delta;
|
||||
double rate;
|
||||
double shift;
|
||||
double phase;
|
||||
double delta;
|
||||
double cos_delta;
|
||||
double sin_delta;
|
||||
|
||||
static SHIFT* create_shift (int run, int size, float* in, float* out, int rate, float fshift);
|
||||
static SHIFT* create_shift (int run, int size, float* in, float* out, int rate, double fshift);
|
||||
static void destroy_shift (SHIFT *a);
|
||||
static void flush_shift (SHIFT *a);
|
||||
static void xshift (SHIFT *a);
|
||||
@ -57,7 +57,7 @@ public:
|
||||
static void setSize_shift (SHIFT *a, int size);
|
||||
// RXA Properties
|
||||
static void SetShiftRun (RXA& rxa, int run);
|
||||
static void SetShiftFreq (RXA& rxa, float fshift);
|
||||
static void SetShiftFreq (RXA& rxa, double fshift);
|
||||
|
||||
private:
|
||||
static void calc_shift (SHIFT *a);
|
||||
|
@ -101,9 +101,9 @@ void SIPHON::destroy_siphon (SIPHON *a)
|
||||
|
||||
void SIPHON::flush_siphon (SIPHON *a)
|
||||
{
|
||||
memset (a->sipbuff, 0, a->sipsize * sizeof (wcomplex));
|
||||
memset (a->sipout , 0, a->sipsize * sizeof (wcomplex));
|
||||
memset (a->specout, 0, a->fftsize * sizeof (wcomplex));
|
||||
std::fill(a->sipbuff, a->sipbuff + a->sipsize * 2, 0);
|
||||
std::fill(a->sipout, a->sipout + a->sipsize * 2, 0);
|
||||
std::fill(a->specout, a->specout + a->fftsize * 2, 0);
|
||||
a->idx = 0;
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ void SIPHON::xsiphon (SIPHON *a, int pos)
|
||||
{
|
||||
case 0:
|
||||
if (a->insize >= a->sipsize)
|
||||
memcpy (a->sipbuff, &(a->in[2 * (a->insize - a->sipsize)]), a->sipsize * sizeof (wcomplex));
|
||||
std::copy(&(a->in[2 * (a->insize - a->sipsize)]), &(a->in[2 * (a->insize - a->sipsize)]) + a->sipsize * 2, a->sipbuff);
|
||||
else
|
||||
{
|
||||
if (a->insize > (a->sipsize - a->idx))
|
||||
@ -130,8 +130,8 @@ void SIPHON::xsiphon (SIPHON *a, int pos)
|
||||
first = a->insize;
|
||||
second = 0;
|
||||
}
|
||||
memcpy (a->sipbuff + 2 * a->idx, a->in, first * sizeof (wcomplex));
|
||||
memcpy (a->sipbuff, a->in + 2 * first, second * sizeof (wcomplex));
|
||||
std::copy(a->in, a->in + first * 2, a->sipbuff + 2 * a->idx);
|
||||
std::copy(a->in + 2 * first, a->in + 2 * first + second * 2, a->sipbuff);
|
||||
if ((a->idx += a->insize) >= a->sipsize) a->idx -= a->sipsize;
|
||||
}
|
||||
break;
|
||||
@ -166,11 +166,11 @@ void SIPHON::suck (SIPHON *a)
|
||||
int j = (a->idx - a->outsize) & mask;
|
||||
int size = a->sipsize - j;
|
||||
if (size >= a->outsize)
|
||||
memcpy (a->sipout, &(a->sipbuff[2 * j]), a->outsize * sizeof (wcomplex));
|
||||
std::copy(&(a->sipbuff[2 * j]), &(a->sipbuff[2 * j]) + a->outsize * 2, a->sipout);
|
||||
else
|
||||
{
|
||||
memcpy (a->sipout, &(a->sipbuff[2 * j]), size * sizeof (wcomplex));
|
||||
memcpy (&(a->sipout[2 * size]), a->sipbuff, (a->outsize - size) * sizeof (wcomplex));
|
||||
std::copy(&(a->sipbuff[2 * j]), &(a->sipbuff[2 * j]) + size * 2, a->sipout);
|
||||
std::copy(a->sipbuff, a->sipbuff + (a->outsize - size) * 2, &(a->sipout[2 * size]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ void USLEW::xuslew (USLEW *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void USLEW::setBuffers_uslew (USLEW *a, float* in, float* out)
|
||||
|
@ -240,8 +240,8 @@ void SNBA::flush_snba (SNBA *d)
|
||||
memset (d->sdet.vp, 0, d->xsize * sizeof (double));
|
||||
memset (d->sdet.vpwr, 0, d->xsize * sizeof (double));
|
||||
|
||||
memset (d->inbuff, 0, d->isize * sizeof (wcomplex));
|
||||
memset (d->outbuff, 0, d->isize * sizeof (wcomplex));
|
||||
std::fill(d->inbuff, d->inbuff + d->isize * 2, 0);
|
||||
std::fill(d->outbuff, d->outbuff + d->isize * 2, 0);
|
||||
|
||||
RESAMPLE::flush_resample (d->inresamp);
|
||||
RESAMPLE::flush_resample (d->outresamp);
|
||||
@ -273,9 +273,12 @@ void SNBA::ATAc0 (int n, int nr, double* A, double* r)
|
||||
{
|
||||
int i, j;
|
||||
memset(r, 0, n * sizeof (double));
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (j = 0; j < nr; j++)
|
||||
r[i] += A[j * n + i] * A[j * n + 0];
|
||||
}
|
||||
}
|
||||
|
||||
void SNBA::multA1TA2(double* a1, double* a2, int m, int n, int q, double* c)
|
||||
@ -425,7 +428,7 @@ void SNBA::det(SNBA *d, int asize, double* v, int* detout)
|
||||
else if (d->sdet.vpwr[i] <= 2.0 * t1)
|
||||
t2 += 2.0 * t1 - d->sdet.vpwr[i];
|
||||
}
|
||||
t2 *= d->sdet.k2 / (double)(d->xsize - asize);
|
||||
t2 *= d->sdet.k2 / (double) (d->xsize - asize);
|
||||
|
||||
for (i = asize; i < d->xsize; i++)
|
||||
{
|
||||
@ -444,8 +447,11 @@ void SNBA::det(SNBA *d, int asize, double* v, int* detout)
|
||||
switch (bstate)
|
||||
{
|
||||
case 0:
|
||||
if (detout[i] == 1) bstate = 1;
|
||||
if (detout[i] == 1)
|
||||
bstate = 1;
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (detout[i] == 0)
|
||||
{
|
||||
@ -453,37 +459,51 @@ void SNBA::det(SNBA *d, int asize, double* v, int* detout)
|
||||
bsamp = i;
|
||||
bcount = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
++bcount;
|
||||
|
||||
if (bcount > d->sdet.b)
|
||||
{
|
||||
if (detout[i] == 1)
|
||||
bstate = 1;
|
||||
else
|
||||
bstate = 0;
|
||||
}
|
||||
else if (detout[i] == 1)
|
||||
{
|
||||
for (j = bsamp; j < bsamp + bcount - 1; j++)
|
||||
detout[j] = 1;
|
||||
bstate = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = asize; i < d->xsize; i++)
|
||||
{
|
||||
if (detout[i] == 1)
|
||||
{
|
||||
for (j = i - 1; j > i - 1 - d->sdet.pre; j--)
|
||||
if (j >= asize) detout[j] = 1;
|
||||
{
|
||||
if (j >= asize)
|
||||
detout[j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = d->xsize - 1; i >= asize; i--)
|
||||
{
|
||||
if (detout[i] == 1)
|
||||
{
|
||||
for (j = i + 1; j < i + 1 + d->sdet.post; j++)
|
||||
if (j < d->xsize) detout[j] = 1;
|
||||
{
|
||||
if (j < d->xsize)
|
||||
detout[j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -510,6 +530,7 @@ int SNBA::scanFrame(
|
||||
int nextlist[MAXIMP];
|
||||
memset (befimp, 0, MAXIMP * sizeof (int));
|
||||
memset (aftimp, 0, MAXIMP * sizeof (int));
|
||||
|
||||
while (i < xsize && nimp < MAXIMP)
|
||||
{
|
||||
if (det[i] == 1 && inflag == 0)
|
||||
@ -530,16 +551,20 @@ int SNBA::scanFrame(
|
||||
if (nimp > 0)
|
||||
aftimp[nimp - 1]++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0; i < nimp; i++)
|
||||
{
|
||||
if (befimp[i] < aftimp[i])
|
||||
p_opt[i] = befimp[i];
|
||||
else
|
||||
p_opt[i] = aftimp[i];
|
||||
|
||||
if (p_opt[i] > pval)
|
||||
p_opt[i] = pval;
|
||||
|
||||
if (p_opt[i] < (int)(pmultmin * limp[i]))
|
||||
p_opt[i] = -1;
|
||||
}
|
||||
@ -549,6 +574,7 @@ int SNBA::scanFrame(
|
||||
merit[i] = (double)p_opt[i] / (double)limp[i];
|
||||
nextlist[i] = i;
|
||||
}
|
||||
|
||||
for (j = 0; j < nimp - 1; j++)
|
||||
{
|
||||
for (k = 0; k < nimp - j - 1; k++)
|
||||
@ -564,9 +590,15 @@ int SNBA::scanFrame(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i = 1;
|
||||
|
||||
if (nimp > 0)
|
||||
while (merit[i] == merit[0] && i < nimp) i++;
|
||||
{
|
||||
while (merit[i] == merit[0] && i < nimp)
|
||||
i++;
|
||||
}
|
||||
|
||||
for (j = 0; j < i - 1; j++)
|
||||
{
|
||||
for (k = 0; k < i - j - 1; k++)
|
||||
@ -582,6 +614,7 @@ int SNBA::scanFrame(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*next = nextlist[0];
|
||||
return nimp;
|
||||
}
|
||||
@ -673,7 +706,9 @@ void SNBA::xsnba (SNBA *d)
|
||||
RESAMPLE::xresample (d->outresamp);
|
||||
}
|
||||
else if (d->out != d->in)
|
||||
memcpy (d->out, d->in, d->bsize * sizeof (wcomplex));
|
||||
{
|
||||
std::copy(d->in, d->in + d->bsize * 2, d->out);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************************************
|
||||
@ -685,6 +720,7 @@ void SNBA::xsnba (SNBA *d)
|
||||
void SNBA::SetSNBARun (RXA& rxa, int run)
|
||||
{
|
||||
SNBA *a = rxa.snba.p;
|
||||
|
||||
if (a->run != run)
|
||||
{
|
||||
RXA::bpsnbaCheck (rxa, rxa.mode, rxa.ndb.p->master_run);
|
||||
|
@ -229,7 +229,7 @@ void SSQL::destroy_ssql (SSQL *a)
|
||||
void SSQL::flush_ssql (SSQL *a)
|
||||
{
|
||||
|
||||
memset (a->b1, 0, a->size * sizeof (wcomplex));
|
||||
std::fill(a->b1, a->b1 + a->size * 2, 0);
|
||||
CBL::flush_cbl (a->dcbl);
|
||||
memset (a->ibuff, 0, a->size * sizeof (float));
|
||||
memset (a->ftovbuff, 0, a->size * sizeof (float));
|
||||
@ -317,7 +317,7 @@ void SSQL::xssql (SSQL *a)
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof(wcomplex));
|
||||
std::copy(a->in, a->in + a->size * 2, a->out);
|
||||
}
|
||||
|
||||
void SSQL::setBuffers_ssql (SSQL *a, float* in, float* out)
|
||||
|
@ -120,7 +120,7 @@ void VARSAMP::destroy_varsamp (VARSAMP *a)
|
||||
|
||||
void VARSAMP::flush_varsamp (VARSAMP *a)
|
||||
{
|
||||
memset (a->ring, 0, a->rsize * sizeof (wcomplex));
|
||||
std::fill(a->ring, a->ring + a->rsize * 2, 0);
|
||||
a->idx_in = a->rsize - 1;
|
||||
a->h_offset = 0.0;
|
||||
a->isamps = 0.0;
|
||||
@ -191,7 +191,7 @@ int VARSAMP::xvarsamp (VARSAMP *a, float var)
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
memcpy (a->out, a->in, a->size * sizeof (wcomplex));
|
||||
std::copy( a->in, a->in + a->size * 2, a->out);
|
||||
return outsamps;
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ WCPAGC* WCPAGC::create_wcpagc (
|
||||
a->in = in;
|
||||
a->out = out;
|
||||
a->io_buffsize = io_buffsize;
|
||||
a->sample_rate = (float)sample_rate;
|
||||
a->sample_rate = (double) sample_rate;
|
||||
a->tau_attack = tau_attack;
|
||||
a->tau_decay = tau_decay;
|
||||
a->n_tau = n_tau;
|
||||
@ -121,7 +121,7 @@ WCPAGC* WCPAGC::create_wcpagc (
|
||||
|
||||
void WCPAGC::loadWcpAGC (WCPAGC *a)
|
||||
{
|
||||
float tmp;
|
||||
double tmp;
|
||||
//calculate internal parameters
|
||||
a->attack_buffsize = (int)ceil(a->sample_rate * a->n_tau * a->tau_attack);
|
||||
a->in_index = a->attack_buffsize + a->out_index;
|
||||
@ -131,24 +131,22 @@ void WCPAGC::loadWcpAGC (WCPAGC *a)
|
||||
a->fast_backmult = 1.0 - exp(-1.0 / (a->sample_rate * a->tau_fast_backaverage));
|
||||
a->onemfast_backmult = 1.0 - a->fast_backmult;
|
||||
|
||||
a->out_target = a->out_targ * (1.0 - exp(-(float)a->n_tau)) * 0.9999;
|
||||
a->out_target = a->out_targ * (1.0 - exp(-(double)a->n_tau)) * 0.9999;
|
||||
a->min_volts = a->out_target / (a->var_gain * a->max_gain);
|
||||
a->inv_out_target = 1.0 / a->out_target;
|
||||
|
||||
tmp = log10(a->out_target / (a->max_input * a->var_gain * a->max_gain));
|
||||
|
||||
if (tmp == 0.0)
|
||||
tmp = 1e-16;
|
||||
|
||||
a->slope_constant = (a->out_target * (1.0 - 1.0 / a->var_gain)) / tmp;
|
||||
|
||||
a->inv_max_input = 1.0 / a->max_input;
|
||||
|
||||
tmp = pow (10.0, (a->hang_thresh - 1.0) / 0.125);
|
||||
a->hang_level = (a->max_input * tmp + (a->out_target /
|
||||
(a->var_gain * a->max_gain)) * (1.0 - tmp)) * 0.637;
|
||||
|
||||
a->hang_backmult = 1.0 - exp(-1.0 / (a->sample_rate * a->tau_hang_backmult));
|
||||
a->onemhang_backmult = 1.0 - a->hang_backmult;
|
||||
|
||||
a->hang_decay_mult = 1.0 - exp(-1.0 / (a->sample_rate * a->tau_hang_decay));
|
||||
}
|
||||
|
||||
@ -160,15 +158,16 @@ void WCPAGC::destroy_wcpagc (WCPAGC *a)
|
||||
|
||||
void WCPAGC::flush_wcpagc (WCPAGC *a)
|
||||
{
|
||||
memset ((void *)a->ring, 0, sizeof(float) * RB_SIZE * 2);
|
||||
memset ((void *)a->ring, 0, sizeof(double) * RB_SIZE * 2);
|
||||
a->ring_max = 0.0;
|
||||
memset ((void *)a->abs_ring, 0, sizeof(float)* RB_SIZE);
|
||||
memset ((void *)a->abs_ring, 0, sizeof(double)* RB_SIZE);
|
||||
}
|
||||
|
||||
void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
{
|
||||
int i, j, k;
|
||||
float mult;
|
||||
double mult;
|
||||
|
||||
if (a->run)
|
||||
{
|
||||
if (a->mode == 0)
|
||||
@ -178,6 +177,7 @@ void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
a->out[2 * i + 0] = a->fixed_gain * a->in[2 * i + 0];
|
||||
a->out[2 * i + 1] = a->fixed_gain * a->in[2 * i + 1];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -185,18 +185,20 @@ void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
{
|
||||
if (++a->out_index >= a->ring_buffsize)
|
||||
a->out_index -= a->ring_buffsize;
|
||||
|
||||
if (++a->in_index >= a->ring_buffsize)
|
||||
a->in_index -= a->ring_buffsize;
|
||||
|
||||
a->out_sample[0] = a->ring[2 * a->out_index + 0];
|
||||
a->out_sample[1] = a->ring[2 * a->out_index + 1];
|
||||
a->abs_out_sample = a->abs_ring[a->out_index];
|
||||
a->ring[2 * a->in_index + 0] = a->in[2 * i + 0];
|
||||
a->ring[2 * a->in_index + 1] = a->in[2 * i + 1];
|
||||
double xr = a->ring[2 * a->in_index + 0] = a->in[2 * i + 0];
|
||||
double xi = a->ring[2 * a->in_index + 1] = a->in[2 * i + 1];
|
||||
|
||||
if (a->pmode == 0)
|
||||
a->abs_ring[a->in_index] = std::max(fabs(a->ring[2 * a->in_index + 0]), fabs(a->ring[2 * a->in_index + 1]));
|
||||
a->abs_ring[a->in_index] = std::max(fabs(xr), fabs(xi));
|
||||
else
|
||||
a->abs_ring[a->in_index] = sqrt(a->ring[2 * a->in_index + 0] * a->ring[2 * a->in_index + 0] + a->ring[2 * a->in_index + 1] * a->ring[2 * a->in_index + 1]);
|
||||
a->abs_ring[a->in_index] = sqrt(xr*xr + xi*xi);
|
||||
|
||||
a->fast_backaverage = a->fast_backmult * a->abs_out_sample + a->onemfast_backmult * a->fast_backaverage;
|
||||
a->hang_backaverage = a->hang_backmult * a->abs_out_sample + a->onemhang_backmult * a->hang_backaverage;
|
||||
@ -205,6 +207,7 @@ void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
{
|
||||
a->ring_max = 0.0;
|
||||
k = a->out_index;
|
||||
|
||||
for (j = 0; j < a->attack_buffsize; j++)
|
||||
{
|
||||
if (++k == a->ring_buffsize)
|
||||
@ -213,6 +216,7 @@ void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
a->ring_max = a->abs_ring[k];
|
||||
}
|
||||
}
|
||||
|
||||
if (a->abs_ring[a->in_index] > a->ring_max)
|
||||
a->ring_max = a->abs_ring[a->in_index];
|
||||
|
||||
@ -252,6 +256,7 @@ void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
if (a->ring_max >= a->volts)
|
||||
@ -288,6 +293,7 @@ void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (a->ring_max >= a->volts)
|
||||
@ -306,6 +312,7 @@ void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
if (a->ring_max >= a->volts)
|
||||
@ -320,6 +327,7 @@ void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
if (a->ring_max >= a->volts)
|
||||
@ -338,6 +346,7 @@ void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
|
||||
if (a->volts < a->min_volts)
|
||||
a->volts = a->min_volts;
|
||||
|
||||
a->gain = a->volts * a->inv_out_target;
|
||||
mult = (a->out_target - a->slope_constant * std::min (0.0, log10(a->inv_max_input * a->volts))) / a->volts;
|
||||
a->out[2 * i + 0] = a->out_sample[0] * mult;
|
||||
@ -345,7 +354,9 @@ void WCPAGC::xwcpagc (WCPAGC *a)
|
||||
}
|
||||
}
|
||||
else if (a->out != a->in)
|
||||
memcpy(a->out, a->in, a->io_buffsize * sizeof (wcomplex));
|
||||
{
|
||||
std::copy(a->in, a->in + a->io_buffsize * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void WCPAGC::setBuffers_wcpagc (WCPAGC *a, float* in, float* out)
|
||||
@ -432,16 +443,16 @@ void WCPAGC::SetAGCHang (RXA& rxa, int hang)
|
||||
loadWcpAGC ( rxa.agc.p );
|
||||
}
|
||||
|
||||
void WCPAGC::GetAGCHangLevel(RXA& rxa, float *hangLevel)
|
||||
void WCPAGC::GetAGCHangLevel(RXA& rxa, double *hangLevel)
|
||||
//for line on bandscope
|
||||
{
|
||||
*hangLevel = 20.0 * log10( rxa.agc.p->hang_level / 0.637 );
|
||||
}
|
||||
|
||||
void WCPAGC::SetAGCHangLevel(RXA& rxa, float hangLevel)
|
||||
void WCPAGC::SetAGCHangLevel(RXA& rxa, double hangLevel)
|
||||
//for line on bandscope
|
||||
{
|
||||
float convert, tmp;
|
||||
double convert, tmp;
|
||||
|
||||
if (rxa.agc.p->max_input > rxa.agc.p->min_volts)
|
||||
{
|
||||
@ -458,59 +469,59 @@ void WCPAGC::SetAGCHangLevel(RXA& rxa, float hangLevel)
|
||||
void WCPAGC::GetAGCHangThreshold(RXA& rxa, int *hangthreshold)
|
||||
//for slider in setup
|
||||
{
|
||||
*hangthreshold = (int)(100.0 * rxa.agc.p->hang_thresh);
|
||||
*hangthreshold = (int) (100.0 * rxa.agc.p->hang_thresh);
|
||||
}
|
||||
|
||||
void WCPAGC::SetAGCHangThreshold (RXA& rxa, int hangthreshold)
|
||||
//For slider in setup
|
||||
{
|
||||
rxa.agc.p->hang_thresh = (float)hangthreshold / 100.0;
|
||||
rxa.agc.p->hang_thresh = (double) hangthreshold / 100.0;
|
||||
loadWcpAGC ( rxa.agc.p );
|
||||
}
|
||||
|
||||
void WCPAGC::GetAGCThresh(RXA& rxa, float *thresh, float size, float rate)
|
||||
void WCPAGC::GetAGCThresh(RXA& rxa, double *thresh, double size, double rate)
|
||||
//for line on bandscope.
|
||||
{
|
||||
float noise_offset;
|
||||
double noise_offset;
|
||||
noise_offset = 10.0 * log10((rxa.nbp0.p->fhigh - rxa.nbp0.p->flow) * size / rate);
|
||||
*thresh = 20.0 * log10( rxa.agc.p->min_volts ) - noise_offset;
|
||||
}
|
||||
|
||||
void WCPAGC::SetAGCThresh(RXA& rxa, float thresh, float size, float rate)
|
||||
void WCPAGC::SetAGCThresh(RXA& rxa, double thresh, double size, double rate)
|
||||
//for line on bandscope
|
||||
{
|
||||
float noise_offset;
|
||||
double noise_offset;
|
||||
noise_offset = 10.0 * log10((rxa.nbp0.p->fhigh - rxa.nbp0.p->flow) * size / rate);
|
||||
rxa.agc.p->max_gain = rxa.agc.p->out_target / (rxa.agc.p->var_gain * pow (10.0, (thresh + noise_offset) / 20.0));
|
||||
loadWcpAGC ( rxa.agc.p );
|
||||
}
|
||||
|
||||
void WCPAGC::GetAGCTop(RXA& rxa, float *max_agc)
|
||||
void WCPAGC::GetAGCTop(RXA& rxa, double *max_agc)
|
||||
//for AGC Max Gain in setup
|
||||
{
|
||||
*max_agc = 20 * log10 (rxa.agc.p->max_gain);
|
||||
}
|
||||
|
||||
void WCPAGC::SetAGCTop (RXA& rxa, float max_agc)
|
||||
void WCPAGC::SetAGCTop (RXA& rxa, double max_agc)
|
||||
//for AGC Max Gain in setup
|
||||
{
|
||||
rxa.agc.p->max_gain = pow (10.0, (float)max_agc / 20.0);
|
||||
rxa.agc.p->max_gain = pow (10.0, (double) max_agc / 20.0);
|
||||
loadWcpAGC ( rxa.agc.p );
|
||||
}
|
||||
|
||||
void WCPAGC::SetAGCSlope (RXA& rxa, int slope)
|
||||
{
|
||||
rxa.agc.p->var_gain = pow (10.0, (float)slope / 20.0 / 10.0);
|
||||
rxa.agc.p->var_gain = pow (10.0, (double) slope / 20.0 / 10.0);
|
||||
loadWcpAGC ( rxa.agc.p );
|
||||
}
|
||||
|
||||
void WCPAGC::SetAGCFixed (RXA& rxa, float fixed_agc)
|
||||
void WCPAGC::SetAGCFixed (RXA& rxa, double fixed_agc)
|
||||
{
|
||||
rxa.agc.p->fixed_gain = pow (10.0, (float)fixed_agc / 20.0);
|
||||
rxa.agc.p->fixed_gain = pow (10.0, (double) fixed_agc / 20.0);
|
||||
loadWcpAGC ( rxa.agc.p );
|
||||
}
|
||||
|
||||
void WCPAGC::SetAGCMaxInputLevel (RXA& rxa, float level)
|
||||
void WCPAGC::SetAGCMaxInputLevel (RXA& rxa, double level)
|
||||
{
|
||||
rxa.agc.p->max_input = level;
|
||||
loadWcpAGC ( rxa.agc.p );
|
||||
@ -529,25 +540,25 @@ void WCPAGC::SetALCSt (TXA& txa, int state)
|
||||
|
||||
void WCPAGC::SetALCAttack (TXA& txa, int attack)
|
||||
{
|
||||
txa.alc.p->tau_attack = (float)attack / 1000.0;
|
||||
txa.alc.p->tau_attack = (double) attack / 1000.0;
|
||||
loadWcpAGC(txa.alc.p);
|
||||
}
|
||||
|
||||
void WCPAGC::SetALCDecay (TXA& txa, int decay)
|
||||
{
|
||||
txa.alc.p->tau_decay = (float)decay / 1000.0;
|
||||
txa.alc.p->tau_decay = (double) decay / 1000.0;
|
||||
loadWcpAGC(txa.alc.p);
|
||||
}
|
||||
|
||||
void WCPAGC::SetALCHang (TXA& txa, int hang)
|
||||
{
|
||||
txa.alc.p->hangtime = (float)hang / 1000.0;
|
||||
txa.alc.p->hangtime = (double) hang / 1000.0;
|
||||
loadWcpAGC(txa.alc.p);
|
||||
}
|
||||
|
||||
void WCPAGC::SetALCMaxGain (TXA& txa, float maxgain)
|
||||
void WCPAGC::SetALCMaxGain (TXA& txa, double maxgain)
|
||||
{
|
||||
txa.alc.p->max_gain = pow (10.0,(float)maxgain / 20.0);
|
||||
txa.alc.p->max_gain = pow (10.0,(double) maxgain / 20.0);
|
||||
loadWcpAGC(txa.alc.p);
|
||||
}
|
||||
|
||||
@ -558,25 +569,25 @@ void WCPAGC::SetLevelerSt (TXA& txa, int state)
|
||||
|
||||
void WCPAGC::SetLevelerAttack (TXA& txa, int attack)
|
||||
{
|
||||
txa.leveler.p->tau_attack = (float)attack / 1000.0;
|
||||
txa.leveler.p->tau_attack = (double) attack / 1000.0;
|
||||
loadWcpAGC(txa.leveler.p);
|
||||
}
|
||||
|
||||
void WCPAGC::SetLevelerDecay (TXA& txa, int decay)
|
||||
{
|
||||
txa.leveler.p->tau_decay = (float)decay / 1000.0;
|
||||
txa.leveler.p->tau_decay = (double) decay / 1000.0;
|
||||
loadWcpAGC(txa.leveler.p);
|
||||
}
|
||||
|
||||
void WCPAGC::SetLevelerHang (TXA& txa, int hang)
|
||||
{
|
||||
txa.leveler.p->hangtime = (float)hang / 1000.0;
|
||||
txa.leveler.p->hangtime = (double) hang / 1000.0;
|
||||
loadWcpAGC(txa.leveler.p);
|
||||
}
|
||||
|
||||
void WCPAGC::SetLevelerTop (TXA& txa, float maxgain)
|
||||
void WCPAGC::SetLevelerTop (TXA& txa, double maxgain)
|
||||
{
|
||||
txa.leveler.p->max_gain = pow (10.0,(float)maxgain / 20.0);
|
||||
txa.leveler.p->max_gain = pow (10.0,(double) maxgain / 20.0);
|
||||
loadWcpAGC(txa.leveler.p);
|
||||
}
|
||||
|
||||
|
@ -139,20 +139,20 @@ public:
|
||||
static void setSize_wcpagc (WCPAGC *a, int size);
|
||||
// RXA Properties
|
||||
static void SetAGCMode (RXA& rxa, int mode);
|
||||
static void SetAGCFixed (RXA& rxa, float fixed_agc);
|
||||
static void SetAGCFixed (RXA& rxa, double fixed_agc);
|
||||
static void SetAGCAttack (RXA& rxa, int attack);
|
||||
static void SetAGCDecay (RXA& rxa, int decay);
|
||||
static void SetAGCHang (RXA& rxa, int hang);
|
||||
static void GetAGCHangLevel(RXA& rxa, float *hangLevel);
|
||||
static void SetAGCHangLevel(RXA& rxa, float hangLevel);
|
||||
static void GetAGCHangLevel(RXA& rxa, double *hangLevel);
|
||||
static void SetAGCHangLevel(RXA& rxa, double hangLevel);
|
||||
static void GetAGCHangThreshold(RXA& rxa, int *hangthreshold);
|
||||
static void SetAGCHangThreshold (RXA& rxa, int hangthreshold);
|
||||
static void GetAGCTop(RXA& rxa, float *max_agc);
|
||||
static void SetAGCTop (RXA& rxa, float max_agc);
|
||||
static void GetAGCTop(RXA& rxa, double *max_agc);
|
||||
static void SetAGCTop (RXA& rxa, double max_agc);
|
||||
static void SetAGCSlope (RXA& rxa, int slope);
|
||||
static void SetAGCThresh(RXA& rxa, float thresh, float size, float rate);
|
||||
static void GetAGCThresh(RXA& rxa, float *thresh, float size, float rate);
|
||||
static void SetAGCMaxInputLevel (RXA& rxa, float level);
|
||||
static void SetAGCThresh(RXA& rxa, double thresh, double size, double rate);
|
||||
static void GetAGCThresh(RXA& rxa, double *thresh, double size, double rate);
|
||||
static void SetAGCMaxInputLevel (RXA& rxa, double level);
|
||||
// TXA Properties
|
||||
static void SetALCSt (TXA& txa, int state);
|
||||
static void SetALCAttack (TXA& txa, int attack);
|
||||
@ -162,8 +162,8 @@ public:
|
||||
static void SetLevelerAttack (TXA& txa, int attack);
|
||||
static void SetLevelerDecay (TXA& txa, int decay);
|
||||
static void SetLevelerHang (TXA& txa, int hang);
|
||||
static void SetLevelerTop (TXA& txa, float maxgain);
|
||||
static void SetALCMaxGain (TXA& txa, float maxgain);
|
||||
static void SetLevelerTop (TXA& txa, double maxgain);
|
||||
static void SetALCMaxGain (TXA& txa, double maxgain);
|
||||
|
||||
private:
|
||||
static void loadWcpAGC (WCPAGC *a);
|
||||
|
Loading…
x
Reference in New Issue
Block a user