diff --git a/plugins/channeltx/modnfm/nfmmodgui.cpp b/plugins/channeltx/modnfm/nfmmodgui.cpp
index cf1937b4b..4f8486524 100644
--- a/plugins/channeltx/modnfm/nfmmodgui.cpp
+++ b/plugins/channeltx/modnfm/nfmmodgui.cpp
@@ -202,6 +202,12 @@ void NFMModGUI::on_afBW_valueChanged(int value)
applySettings();
}
+void NFMModGUI::on_preEmphasis_toggled(bool checked)
+{
+ m_settings.m_preEmphasisOn = checked;
+ applySettings();
+}
+
void NFMModGUI::on_fmDev_valueChanged(int value)
{
ui->fmDevText->setText(QString("%1%2k").arg(QChar(0xB1, 0x00)).arg(value / 10.0, 0, 'f', 1));
@@ -352,6 +358,12 @@ void NFMModGUI::on_dcsPositive_toggled(bool checked)
applySettings();
}
+void NFMModGUI::on_bpf_toggled(bool checked)
+{
+ m_settings.m_bpfOn = checked;
+ applySettings();
+}
+
void NFMModGUI::configureFileName()
{
qDebug() << "FileSourceGui::configureFileName: " << m_fileName.toStdString().c_str();
@@ -546,6 +558,7 @@ void NFMModGUI::displaySettings()
ui->afBWText->setText(QString("%1k").arg(m_settings.m_afBandwidth / 1000.0, 0, 'f', 1));
ui->afBW->setValue(m_settings.m_afBandwidth / 100.0);
+ ui->preEmphasis->setChecked(m_settings.m_preEmphasisOn);
ui->fmDevText->setText(QString("%1%2k").arg(QChar(0xB1, 0x00)).arg(m_settings.m_fmDeviation / 2000.0, 0, 'f', 1));
ui->fmDev->setValue(m_settings.m_fmDeviation / 200.0);
@@ -567,6 +580,7 @@ void NFMModGUI::displaySettings()
ui->dcsOn->setEnabled(!m_settings.m_ctcssOn);
ui->dcsCode->setText(tr("%1").arg(m_settings.m_dcsCode, 3, 8, QLatin1Char('0')));
ui->dcsPositive->setChecked(m_settings.m_dcsPositive);
+ ui->bpf->setChecked(m_settings.m_bpfOn);
ui->channelMute->setChecked(m_settings.m_channelMute);
ui->playLoop->setChecked(m_settings.m_playLoop);
@@ -707,6 +721,7 @@ void NFMModGUI::makeUIConnections()
QObject::connect(ui->channelSpacingApply, &QPushButton::clicked, this, &NFMModGUI::on_channelSpacingApply_clicked);
QObject::connect(ui->rfBW, &QSlider::valueChanged, this, &NFMModGUI::on_rfBW_valueChanged);
QObject::connect(ui->afBW, &QSlider::valueChanged, this, &NFMModGUI::on_afBW_valueChanged);
+ QObject::connect(ui->preEmphasis, &QCheckBox::toggled, this, &NFMModGUI::on_preEmphasis_toggled);
QObject::connect(ui->fmDev, &QSlider::valueChanged, this, &NFMModGUI::on_fmDev_valueChanged);
QObject::connect(ui->toneFrequency, &QDial::valueChanged, this, &NFMModGUI::on_toneFrequency_valueChanged);
QObject::connect(ui->volume, &QDial::valueChanged, this, &NFMModGUI::on_volume_valueChanged);
@@ -723,6 +738,7 @@ void NFMModGUI::makeUIConnections()
QObject::connect(ui->dcsOn, &QCheckBox::toggled, this, &NFMModGUI::on_dcsOn_toggled);
QObject::connect(ui->dcsCode, &QLineEdit::editingFinished, this, &NFMModGUI::on_dcsCode_editingFinished);
QObject::connect(ui->dcsPositive, &QCheckBox::toggled, this, &NFMModGUI::on_dcsPositive_toggled);
+ QObject::connect(ui->bpf, &QCheckBox::toggled, this, &NFMModGUI::on_bpf_toggled);
QObject::connect(ui->feedbackEnable, &QToolButton::toggled, this, &NFMModGUI::on_feedbackEnable_toggled);
QObject::connect(ui->feedbackVolume, &QDial::valueChanged, this, &NFMModGUI::on_feedbackVolume_valueChanged);
}
diff --git a/plugins/channeltx/modnfm/nfmmodgui.h b/plugins/channeltx/modnfm/nfmmodgui.h
index 3d20b38e4..d94ef701c 100644
--- a/plugins/channeltx/modnfm/nfmmodgui.h
+++ b/plugins/channeltx/modnfm/nfmmodgui.h
@@ -114,6 +114,7 @@ private slots:
void on_channelSpacingApply_clicked();
void on_rfBW_valueChanged(int value);
void on_afBW_valueChanged(int value);
+ void on_preEmphasis_toggled(bool checked);
void on_fmDev_valueChanged(int value);
void on_toneFrequency_valueChanged(int value);
void on_volume_valueChanged(int value);
@@ -132,6 +133,7 @@ private slots:
void on_dcsOn_toggled(bool checked);
void on_dcsCode_editingFinished();
void on_dcsPositive_toggled(bool checked);
+ void on_bpf_toggled(bool checked);
void on_feedbackEnable_toggled(bool checked);
void on_feedbackVolume_valueChanged(int value);
diff --git a/plugins/channeltx/modnfm/nfmmodgui.ui b/plugins/channeltx/modnfm/nfmmodgui.ui
index 086c4d5da..12c468693 100644
--- a/plugins/channeltx/modnfm/nfmmodgui.ui
+++ b/plugins/channeltx/modnfm/nfmmodgui.ui
@@ -279,6 +279,42 @@
+ -
+
+
+
+ 24
+ 0
+
+
+
+ Pre-emphasis (120us) on/off
+
+
+ P
+
+
+
+ -
+
+
+
+ 24
+ 16777215
+
+
+
+ Audio high pass filter for CTCSS on/off
+
+
+
+
+
+
+ :/filter_highpass.png:/filter_highpass.png
+
+
+
-
diff --git a/plugins/channeltx/modnfm/nfmmodsettings.cpp b/plugins/channeltx/modnfm/nfmmodsettings.cpp
index 956466aaa..e857d5e5d 100644
--- a/plugins/channeltx/modnfm/nfmmodsettings.cpp
+++ b/plugins/channeltx/modnfm/nfmmodsettings.cpp
@@ -66,6 +66,8 @@ void NFMModSettings::resetToDefaults()
m_dcsOn = false;
m_dcsCode = 0023;
m_dcsPositive = false;
+ m_preEmphasisOn = true;
+ m_bpfOn = true;
m_rgbColor = QColor(255, 0, 0).rgb();
m_title = "NFM Modulator";
m_modAFInput = NFMModInputAF::NFMModInputNone;
@@ -98,15 +100,16 @@ QByteArray NFMModSettings::serialize() const
if (m_cwKeyerGUI) {
s.writeBlob(8, m_cwKeyerGUI->serialize());
} else { // standalone operation with presets
- s.writeBlob(6, m_cwKeyerSettings.serialize());
+ s.writeBlob(8, m_cwKeyerSettings.serialize());
}
+ s.writeBool(9, m_ctcssOn);
+ s.writeS32(10, m_ctcssIndex);
+
if (m_channelMarker) {
s.writeBlob(11, m_channelMarker->serialize());
}
- s.writeBool(9, m_ctcssOn);
- s.writeS32(10, m_ctcssIndex);
s.writeString(12, m_title);
s.writeS32(13, (int) m_modAFInput);
s.writeString(14, m_audioDeviceName);
@@ -130,6 +133,8 @@ QByteArray NFMModSettings::serialize() const
s.writeS32(28, m_workspaceIndex);
s.writeBlob(29, m_geometryBytes);
s.writeBool(30, m_hidden);
+ s.writeBool(31, m_preEmphasisOn);
+ s.writeBool(32, m_bpfOn);
return s.final();
}
@@ -217,6 +222,8 @@ bool NFMModSettings::deserialize(const QByteArray& data)
d.readS32(28, &m_workspaceIndex, 0);
d.readBlob(29, &m_geometryBytes);
d.readBool(30, &m_hidden, false);
+ d.readBool(31, &m_preEmphasisOn, true);
+ d.readBool(32, &m_bpfOn, true);
return true;
}
diff --git a/plugins/channeltx/modnfm/nfmmodsettings.h b/plugins/channeltx/modnfm/nfmmodsettings.h
index 9ce5fbf68..d64ab0d40 100644
--- a/plugins/channeltx/modnfm/nfmmodsettings.h
+++ b/plugins/channeltx/modnfm/nfmmodsettings.h
@@ -54,6 +54,8 @@ struct NFMModSettings
bool m_dcsOn;
int m_dcsCode;
bool m_dcsPositive;
+ bool m_preEmphasisOn;
+ bool m_bpfOn;
quint32 m_rgbColor;
QString m_title;
NFMModInputAF m_modAFInput;
diff --git a/plugins/channeltx/modnfm/nfmmodsource.cpp b/plugins/channeltx/modnfm/nfmmodsource.cpp
index 032dc1b27..97a2c64a7 100644
--- a/plugins/channeltx/modnfm/nfmmodsource.cpp
+++ b/plugins/channeltx/modnfm/nfmmodsource.cpp
@@ -144,7 +144,12 @@ void NFMModSource::modulateSample()
Real t0, t1, t;
pullAF(t0);
- m_preemphasisFilter.process(t0, t);
+
+ if (m_settings.m_preEmphasisOn) {
+ m_preemphasisFilter.process(t0, t);
+ } else {
+ t = t0;
+ }
if (m_settings.m_feedbackAudioEnable) {
pushFeedback(t * m_settings.m_feedbackVolumeFactor * 16384.0f);
@@ -156,8 +161,10 @@ void NFMModSource::modulateSample()
t1 = (0.85f * m_bandpass.filter(t) + 0.15f * 0.625f * m_ctcssNco.next()) * 1.2f;
} else if (m_settings.m_dcsOn) {
t1 = (0.9f * m_bandpass.filter(t) + 0.1f * 0.625f * m_dcsMod.next()) * 1.2f;
- } else {
+ } else if (m_settings.m_bpfOn) {
t1 = m_bandpass.filter(t) * 1.2f;
+ } else {
+ t1 = m_lowpass.filter(t) * 1.2f;
}
m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * t1;
@@ -350,7 +357,7 @@ void NFMModSource::applyAudioSampleRate(int sampleRate)
m_interpolatorConsumed = false;
m_interpolatorDistance = (Real) sampleRate / (Real) m_channelSampleRate;
m_interpolator.create(48, sampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
- m_lowpass.create(301, sampleRate, 250.0);
+ m_lowpass.create(301, sampleRate, m_settings.m_afBandwidth);
m_bandpass.create(301, sampleRate, 300.0, m_settings.m_afBandwidth);
m_toneNco.setFreq(m_settings.m_toneFrequency, sampleRate);
m_ctcssNco.setFreq(NFMModSettings::getCTCSSFreq(m_settings.m_ctcssIndex), sampleRate);