diff --git a/plugins/channelrx/demodnfm/nfmdemodgui.cpp b/plugins/channelrx/demodnfm/nfmdemodgui.cpp
index ec1cfa69c..8568c2cba 100644
--- a/plugins/channelrx/demodnfm/nfmdemodgui.cpp
+++ b/plugins/channelrx/demodnfm/nfmdemodgui.cpp
@@ -107,20 +107,46 @@ void NFMDemodGUI::on_deltaFrequency_changed(qint64 value)
applySettings();
}
-void NFMDemodGUI::on_rfBW_currentIndexChanged(int index)
+void NFMDemodGUI::on_channelSpacing_currentIndexChanged(int index)
{
- qDebug() << "NFMDemodGUI::on_rfBW_currentIndexChanged" << index;
- //ui->rfBWText->setText(QString("%1 k").arg(m_rfBW[value] / 1000.0));
- m_channelMarker.setBandwidth(NFMDemodSettings::getRFBW(index));
m_settings.m_rfBandwidth = NFMDemodSettings::getRFBW(index);
- m_settings.m_fmDeviation = NFMDemodSettings::getFMDev(index);
+ m_settings.m_afBandwidth = NFMDemodSettings::getAFBW(index);
+ m_settings.m_fmDeviation = 2.0 * NFMDemodSettings::getFMDev(index);
+ m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
+ ui->rfBW->blockSignals(true);
+ ui->afBW->blockSignals(true);
+ ui->fmDev->blockSignals(true);
+ ui->rfBWText->setText(QString("%1k").arg(m_settings.m_rfBandwidth / 1000.0, 0, 'f', 1));
+ ui->rfBW->setValue(m_settings.m_rfBandwidth / 100.0);
+ 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->fmDevText->setText(QString("%1k").arg(m_settings.m_fmDeviation / 2000.0, 0, 'f', 1));
+ ui->fmDev->setValue(m_settings.m_fmDeviation / 200.0);
+ ui->rfBW->blockSignals(false);
+ ui->afBW->blockSignals(false);
+ ui->fmDev->blockSignals(false);
+ applySettings();
+}
+
+void NFMDemodGUI::on_rfBW_valueChanged(int value)
+{
+ ui->rfBWText->setText(QString("%1k").arg(value / 10.0, 0, 'f', 1));
+ m_settings.m_rfBandwidth = value * 100.0;
+ m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
applySettings();
}
void NFMDemodGUI::on_afBW_valueChanged(int value)
{
- ui->afBWText->setText(QString("%1 k").arg(value));
- m_settings.m_afBandwidth = value * 1000.0;
+ ui->afBWText->setText(QString("%1k").arg(value / 10.0, 0, 'f', 1));
+ m_settings.m_afBandwidth = value * 100.0;
+ applySettings();
+}
+
+void NFMDemodGUI::on_fmDev_valueChanged(int value)
+{
+ ui->fmDevText->setText(QString("%1k").arg(value / 10.0, 0, 'f', 1));
+ m_settings.m_fmDeviation = value * 200.0;
applySettings();
}
@@ -281,12 +307,14 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
blockApplySettings(true);
- ui->rfBW->clear();
+ ui->channelSpacing->clear();
- for (int i = 0; i < NFMDemodSettings::m_nbRfBW; i++) {
- ui->rfBW->addItem(QString("%1").arg(NFMDemodSettings::getRFBW(i) / 1000.0, 0, 'f', 2));
+ for (int i = 0; i < NFMDemodSettings::m_nbChannelSpacings; i++) {
+ ui->channelSpacing->addItem(QString("%1").arg(NFMDemodSettings::getChannelSpacing(i) / 1000.0, 0, 'f', 2));
}
+ ui->channelSpacing->setCurrentIndex(NFMDemodSettings::getChannelSpacingIndex(12500));
+
int ctcss_nbTones;
const Real *ctcss_tones = m_nfmDemod->getCtcssToneSet(ctcss_nbTones);
@@ -363,10 +391,14 @@ void NFMDemodGUI::displaySettings()
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
- ui->rfBW->setCurrentIndex(NFMDemodSettings::getRFBWIndex(m_settings.m_rfBandwidth));
+ ui->rfBWText->setText(QString("%1k").arg(m_settings.m_rfBandwidth / 1000.0, 0, 'f', 1));
+ ui->rfBW->setValue(m_settings.m_rfBandwidth / 100.0);
- ui->afBWText->setText(QString("%1 k").arg(m_settings.m_afBandwidth / 1000.0));
- ui->afBW->setValue(m_settings.m_afBandwidth / 1000.0);
+ 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->fmDevText->setText(QString("%1k").arg(m_settings.m_fmDeviation / 2000.0, 0, 'f', 1));
+ ui->fmDev->setValue(m_settings.m_fmDeviation / 200.0);
ui->volumeText->setText(QString("%1").arg(m_settings.m_volume*100.0, 0, 'f', 0));
ui->volume->setValue(m_settings.m_volume * 100.0);
diff --git a/plugins/channelrx/demodnfm/nfmdemodgui.h b/plugins/channelrx/demodnfm/nfmdemodgui.h
index 8a75fd5d1..a7e27f43b 100644
--- a/plugins/channelrx/demodnfm/nfmdemodgui.h
+++ b/plugins/channelrx/demodnfm/nfmdemodgui.h
@@ -64,8 +64,10 @@ private:
private slots:
void on_deltaFrequency_changed(qint64 value);
- void on_rfBW_currentIndexChanged(int index);
+ void on_channelSpacing_currentIndexChanged(int index);
+ void on_rfBW_valueChanged(int value);
void on_afBW_valueChanged(int value);
+ void on_fmDev_valueChanged(int value);
void on_volume_valueChanged(int value);
void on_squelchGate_valueChanged(int value);
void on_deltaSquelch_toggled(bool checked);
diff --git a/plugins/channelrx/demodnfm/nfmdemodgui.ui b/plugins/channelrx/demodnfm/nfmdemodgui.ui
index 8d3eb29f8..f424e458e 100644
--- a/plugins/channelrx/demodnfm/nfmdemodgui.ui
+++ b/plugins/channelrx/demodnfm/nfmdemodgui.ui
@@ -7,7 +7,7 @@
0
0
302
- 178
+ 182
@@ -204,14 +204,14 @@
-
-
-
+
- RFBW
+ CS
-
-
+
60
@@ -219,23 +219,58 @@
- RF demodulator bandwidth (kHz)
+ Apply channel spacing settings
-
-
+
+
+ RF
+
+
+
+ -
+
- 10
+ 0
+ 0
+
+
+
+ RF bandwidth (kHz)
+
+
+ 1
+
+
+ 400
+
+
+ 1
+
+
+ 110
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 35
0
- k
+ 20.0k
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -252,23 +287,10 @@
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
- AFBW
+ AF
@@ -287,13 +309,13 @@
1
- 20
+ 200
1
- 3
+ 30
Qt::Horizontal
@@ -304,12 +326,12 @@
- 25
+ 35
0
- 3 k
+ 20.0k
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -321,79 +343,60 @@
-
-
-
+
- Vol
+ FMd
-
-
-
-
- 24
- 24
-
-
-
- Sound volume (%)
-
-
- 200
-
-
- 1
-
-
- 1
-
-
- 100
-
-
-
- -
-
+
0
0
-
+
+ FM peak deviation (kHz)
+
+
+ 1
+
+
+ 200
+
+
+ 1
+
+
+ 25
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
- 30
- 16777215
+ 35
+ 0
-
- Sound volume (%)
-
- 100
+ 20.0k
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
- Sq
+ Sq
@@ -565,17 +568,61 @@
-
-
-
- Qt::Horizontal
+
+
+ Vol
-
+
+
+ -
+
+
- 40
- 20
+ 24
+ 24
-
+
+ Sound volume (%)
+
+
+ 200
+
+
+ 1
+
+
+ 1
+
+
+ 100
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 16777215
+
+
+
+ Sound volume (%)
+
+
+ 100
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
-
diff --git a/plugins/channelrx/demodnfm/nfmdemodsettings.cpp b/plugins/channelrx/demodnfm/nfmdemodsettings.cpp
index de5c3479a..6fd1ac579 100644
--- a/plugins/channelrx/demodnfm/nfmdemodsettings.cpp
+++ b/plugins/channelrx/demodnfm/nfmdemodsettings.cpp
@@ -23,15 +23,23 @@
#include "nfmdemodsettings.h"
-// fixed |Carson (3k) |Carson (6k)
-// | 11F3 16F3 |
-const int NFMDemodSettings::m_rfBW[] = {
- 5000, 6250, 8330, 11000, 16000, 20000, 25000, 40000
+// Standard channel spacings (kHz) using Carson rule
+// beta based ............ 11F3 16F3 (36F9)
+// 5 6.25 7.5 8.33 12.5 25 40 Spacing
+// 0.43 0.43 0.43 0.43 0.83 1.67 1.0 Beta
+const int NFMDemodSettings::m_channelSpacings[] = {
+ 5000, 6250, 7500, 8333, 12500, 25000, 40000
};
-const int NFMDemodSettings::m_fmDev[] = {
- 2500, 2500, 3330, 5000, 10000, 14000, 19000, 28000
+const int NFMDemodSettings::m_rfBW[] = { // RF bandwidth (Hz)
+ 4800, 6000, 7200, 8000, 11000, 16000, 36000
};
-const int NFMDemodSettings::m_nbRfBW = 8;
+const int NFMDemodSettings::m_afBW[] = { // audio bandwidth (Hz)
+ 1700, 2100, 2500, 2800, 3000, 3000, 9000
+};
+const int NFMDemodSettings::m_fmDev[] = { // peak deviation (Hz) - full is double
+ 731, 903, 1075, 1204, 2500, 5000, 9000
+};
+const int NFMDemodSettings::m_nbChannelSpacings = 7;
NFMDemodSettings::NFMDemodSettings() :
m_channelMarker(0)
@@ -44,7 +52,7 @@ void NFMDemodSettings::resetToDefaults()
m_inputFrequencyOffset = 0;
m_rfBandwidth = 12500;
m_afBandwidth = 3000;
- m_fmDeviation = 2000;
+ m_fmDeviation = 5000;
m_squelchGate = 5; // 10s of ms at 48000 Hz sample rate. Corresponds to 2400 for AGC attack
m_deltaSquelch = false;
m_squelch = -30.0;
@@ -68,8 +76,8 @@ QByteArray NFMDemodSettings::serialize() const
{
SimpleSerializer s(1);
s.writeS32(1, m_inputFrequencyOffset);
- s.writeS32(2, getRFBWIndex(m_rfBandwidth));
- s.writeS32(3, m_afBandwidth/1000.0);
+ s.writeReal(2, m_rfBandwidth);
+ s.writeReal(3, m_afBandwidth);
s.writeS32(4, m_volume*10.0);
s.writeS32(5, static_cast(m_squelch));
s.writeBool(6, m_highPass);
@@ -92,6 +100,7 @@ QByteArray NFMDemodSettings::serialize() const
s.writeU32(19, m_reverseAPIDeviceIndex);
s.writeU32(20, m_reverseAPIChannelIndex);
s.writeS32(21, m_streamIndex);
+ s.writeReal(22, m_fmDeviation);
return s.final();
}
@@ -120,11 +129,8 @@ bool NFMDemodSettings::deserialize(const QByteArray& data)
d.readS32(1, &tmp, 0);
m_inputFrequencyOffset = tmp;
- d.readS32(2, &tmp, 4);
- m_rfBandwidth = getRFBW(tmp);
- m_fmDeviation = getFMDev(tmp);
- d.readS32(3, &tmp, 3);
- m_afBandwidth = tmp * 1000.0;
+ d.readReal(2, &m_rfBandwidth, 12500.0);
+ d.readReal(3, &m_afBandwidth, 3000.0);
d.readS32(4, &tmp, 20);
m_volume = tmp / 10.0;
d.readS32(5, &tmp, -30);
@@ -153,6 +159,7 @@ bool NFMDemodSettings::deserialize(const QByteArray& data)
d.readU32(20, &utmp, 0);
m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp;
d.readS32(21, &m_streamIndex, 0);
+ d.readReal(22, &m_fmDeviation, 5000.0);
return true;
}
@@ -163,37 +170,94 @@ bool NFMDemodSettings::deserialize(const QByteArray& data)
}
}
+int NFMDemodSettings::getChannelSpacing(int index)
+{
+ if (index < 0) {
+ return m_channelSpacings[0];
+ } else if (index < m_nbChannelSpacings) {
+ return m_channelSpacings[index];
+ } else {
+ return m_channelSpacings[m_nbChannelSpacings-1];
+ }
+}
+
+int NFMDemodSettings::getChannelSpacingIndex(int channelSpacing)
+{
+ for (int i = 0; i < m_nbChannelSpacings; i++)
+ {
+ if (channelSpacing <= m_channelSpacings[i]) {
+ return i;
+ }
+ }
+
+ return m_nbChannelSpacings-1;
+}
+
int NFMDemodSettings::getRFBW(int index)
{
if (index < 0) {
return m_rfBW[0];
- } else if (index < m_nbRfBW) {
+ } else if (index < m_nbChannelSpacings) {
return m_rfBW[index];
} else {
- return m_rfBW[m_nbRfBW-1];
+ return m_rfBW[m_nbChannelSpacings-1];
}
}
+int NFMDemodSettings::getRFBWIndex(int rfbw)
+{
+ for (int i = 0; i < m_nbChannelSpacings; i++)
+ {
+ if (rfbw <= m_rfBW[i]) {
+ return i;
+ }
+ }
+
+ return m_nbChannelSpacings-1;
+}
+
+int NFMDemodSettings::getAFBW(int index)
+{
+ if (index < 0) {
+ return m_afBW[0];
+ } else if (index < m_nbChannelSpacings) {
+ return m_afBW[index];
+ } else {
+ return m_afBW[m_nbChannelSpacings-1];
+ }
+}
+
+int NFMDemodSettings::getAFBWIndex(int afbw)
+{
+ for (int i = 0; i < m_nbChannelSpacings; i++)
+ {
+ if (afbw <= m_afBW[i]) {
+ return i;
+ }
+ }
+
+ return m_nbChannelSpacings-1;
+}
+
int NFMDemodSettings::getFMDev(int index)
{
if (index < 0) {
return m_fmDev[0];
- } else if (index < m_nbRfBW) {
+ } else if (index < m_nbChannelSpacings) {
return m_fmDev[index];
} else {
- return m_fmDev[m_nbRfBW-1];
+ return m_fmDev[m_nbChannelSpacings-1];
}
}
-int NFMDemodSettings::getRFBWIndex(int rfbw)
+int NFMDemodSettings::getFMDevIndex(int fmDev)
{
- for (int i = 0; i < m_nbRfBW; i++)
+ for (int i = 0; i < m_nbChannelSpacings; i++)
{
- if (rfbw <= m_rfBW[i])
- {
+ if (fmDev <= m_rfBW[i]) {
return i;
}
}
- return m_nbRfBW-1;
+ return m_nbChannelSpacings-1;
}
diff --git a/plugins/channelrx/demodnfm/nfmdemodsettings.h b/plugins/channelrx/demodnfm/nfmdemodsettings.h
index 6d2bc332f..8ae968391 100644
--- a/plugins/channelrx/demodnfm/nfmdemodsettings.h
+++ b/plugins/channelrx/demodnfm/nfmdemodsettings.h
@@ -24,14 +24,16 @@ class Serializable;
struct NFMDemodSettings
{
- static const int m_nbRfBW;
+ static const int m_nbChannelSpacings;
+ static const int m_channelSpacings[];
static const int m_rfBW[];
+ static const int m_afBW[];
static const int m_fmDev[];
int32_t m_inputFrequencyOffset;
Real m_rfBandwidth;
Real m_afBandwidth;
- int m_fmDeviation;
+ Real m_fmDeviation;
int m_squelchGate;
bool m_deltaSquelch;
Real m_squelch; //!< deci-Bels
@@ -58,9 +60,14 @@ struct NFMDemodSettings
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
+ static int getChannelSpacing(int index);
+ static int getChannelSpacingIndex(int channelSpacing);
static int getRFBW(int index);
- static int getFMDev(int index);
static int getRFBWIndex(int rfbw);
+ static int getAFBW(int index);
+ static int getAFBWIndex(int rfbw);
+ static int getFMDev(int index);
+ static int getFMDevIndex(int fmDev);
};
diff --git a/plugins/channelrx/demodnfm/nfmdemodsink.cpp b/plugins/channelrx/demodnfm/nfmdemodsink.cpp
index c5fbadb97..33d96b773 100644
--- a/plugins/channelrx/demodnfm/nfmdemodsink.cpp
+++ b/plugins/channelrx/demodnfm/nfmdemodsink.cpp
@@ -236,7 +236,7 @@ void NFMDemodSink::applyChannelSettings(int channelSampleRate, int channelFreque
if ((channelSampleRate != m_channelSampleRate) || force)
{
- m_interpolator.create(16, channelSampleRate, m_settings.m_fmDeviation);
+ m_interpolator.create(16, channelSampleRate, m_settings.m_rfBandwidth / 2.2);
m_interpolatorDistance = Real(channelSampleRate) / Real(m_audioSampleRate);
m_interpolatorDistanceRemain = m_interpolatorDistance;
@@ -269,7 +269,7 @@ void NFMDemodSink::applySettings(const NFMDemodSettings& settings, bool force)
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
{
- m_interpolator.create(16, m_channelSampleRate, settings.m_fmDeviation);
+ m_interpolator.create(16, m_channelSampleRate, settings.m_rfBandwidth / 2.2);
m_interpolatorDistance = Real(m_channelSampleRate) / Real(m_audioSampleRate);
m_interpolatorDistanceRemain = m_interpolatorDistance;
}
diff --git a/plugins/channeltx/modnfm/nfmmodgui.cpp b/plugins/channeltx/modnfm/nfmmodgui.cpp
index 9f90275fd..62e58f63f 100644
--- a/plugins/channeltx/modnfm/nfmmodgui.cpp
+++ b/plugins/channeltx/modnfm/nfmmodgui.cpp
@@ -137,24 +137,46 @@ void NFMModGUI::on_deltaFrequency_changed(qint64 value)
applySettings();
}
-void NFMModGUI::on_rfBW_currentIndexChanged(int index)
+void NFMModGUI::on_channelSpacing_currentIndexChanged(int index)
{
- m_channelMarker.setBandwidth(NFMModSettings::getRFBW(index));
m_settings.m_rfBandwidth = NFMModSettings::getRFBW(index);
+ m_settings.m_afBandwidth = NFMModSettings::getAFBW(index);
+ m_settings.m_fmDeviation = 2.0 * NFMModSettings::getFMDev(index);
+ m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
+ ui->rfBW->blockSignals(true);
+ ui->afBW->blockSignals(true);
+ ui->fmDev->blockSignals(true);
+ ui->rfBWText->setText(QString("%1k").arg(m_settings.m_rfBandwidth / 1000.0, 0, 'f', 1));
+ ui->rfBW->setValue(m_settings.m_rfBandwidth / 100.0);
+ 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->fmDevText->setText(QString("%1k").arg(m_settings.m_fmDeviation / 2000.0, 0, 'f', 1));
+ ui->fmDev->setValue(m_settings.m_fmDeviation / 200.0);
+ ui->rfBW->blockSignals(false);
+ ui->afBW->blockSignals(false);
+ ui->fmDev->blockSignals(false);
+ applySettings();
+}
+
+void NFMModGUI::on_rfBW_valueChanged(int value)
+{
+ ui->rfBWText->setText(QString("%1k").arg(value / 10.0, 0, 'f', 1));
+ m_settings.m_rfBandwidth = value * 100.0;
+ m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
applySettings();
}
void NFMModGUI::on_afBW_valueChanged(int value)
{
- ui->afBWText->setText(QString("%1k").arg(value));
- m_settings.m_afBandwidth = value * 1000.0;
+ ui->afBWText->setText(QString("%1k").arg(value / 10.0, 0, 'f', 1));
+ m_settings.m_afBandwidth = value * 100.0;
applySettings();
}
void NFMModGUI::on_fmDev_valueChanged(int value)
{
ui->fmDevText->setText(QString("%1k").arg(value / 10.0, 0, 'f', 1));
- m_settings.m_fmDeviation = value * 100.0;
+ m_settings.m_fmDeviation = value * 200.0;
applySettings();
}
@@ -352,15 +374,15 @@ NFMModGUI::NFMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
- blockApplySettings(true);
+ ui->channelSpacing->blockSignals(true);
+ ui->channelSpacing->clear();
- ui->rfBW->clear();
- for (int i = 0; i < NFMModSettings::m_nbRfBW; i++) {
- ui->rfBW->addItem(QString("%1").arg(NFMModSettings::getRFBW(i) / 1000.0, 0, 'f', 2));
+ for (int i = 0; i < NFMModSettings::m_nbChannelSpacings; i++) {
+ ui->channelSpacing->addItem(QString("%1").arg(NFMModSettings::getChannelSpacing(i) / 1000.0, 0, 'f', 2));
}
- ui->rfBW->setCurrentIndex(6);
- blockApplySettings(false);
+ ui->channelSpacing->setCurrentIndex(NFMModSettings::getChannelSpacingIndex(25000));
+ ui->channelSpacing->blockSignals(false);
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
@@ -439,7 +461,6 @@ void NFMModGUI::displaySettings()
m_channelMarker.blockSignals(true);
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
m_channelMarker.setTitle(m_settings.m_title);
- m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
m_channelMarker.blockSignals(false);
m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
@@ -451,13 +472,14 @@ void NFMModGUI::displaySettings()
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
- ui->rfBW->setCurrentIndex(NFMModSettings::getRFBWIndex(m_settings.m_rfBandwidth));
+ ui->rfBWText->setText(QString("%1k").arg(m_settings.m_rfBandwidth / 1000.0, 0, 'f', 1));
+ ui->rfBW->setValue(m_settings.m_rfBandwidth / 100.0);
- ui->afBWText->setText(QString("%1k").arg(m_settings.m_afBandwidth / 1000.0));
- ui->afBW->setValue(m_settings.m_afBandwidth / 1000.0);
+ 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->fmDevText->setText(QString("%1k").arg(m_settings.m_fmDeviation / 1000.0, 0, 'f', 1));
- ui->fmDev->setValue(m_settings.m_fmDeviation / 100.0);
+ ui->fmDevText->setText(QString("%1k").arg(m_settings.m_fmDeviation / 2000.0, 0, 'f', 1));
+ ui->fmDev->setValue(m_settings.m_fmDeviation / 200.0);
ui->volumeText->setText(QString("%1").arg(m_settings.m_volumeFactor, 0, 'f', 1));
ui->volume->setValue(m_settings.m_volumeFactor * 10.0);
diff --git a/plugins/channeltx/modnfm/nfmmodgui.h b/plugins/channeltx/modnfm/nfmmodgui.h
index 7606ba076..b44a1a70c 100644
--- a/plugins/channeltx/modnfm/nfmmodgui.h
+++ b/plugins/channeltx/modnfm/nfmmodgui.h
@@ -89,7 +89,8 @@ private slots:
void handleSourceMessages();
void on_deltaFrequency_changed(qint64 value);
- void on_rfBW_currentIndexChanged(int index);
+ void on_channelSpacing_currentIndexChanged(int index);
+ void on_rfBW_valueChanged(int value);
void on_afBW_valueChanged(int value);
void on_fmDev_valueChanged(int value);
void on_toneFrequency_valueChanged(int value);
diff --git a/plugins/channeltx/modnfm/nfmmodgui.ui b/plugins/channeltx/modnfm/nfmmodgui.ui
index ea064368f..59ae43e78 100644
--- a/plugins/channeltx/modnfm/nfmmodgui.ui
+++ b/plugins/channeltx/modnfm/nfmmodgui.ui
@@ -186,35 +186,22 @@
-
-
-
+
- RFBW
+ CS
-
-
+
60
16777215
-
-
- -
-
-
-
- 10
- 0
-
-
-
- k
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+ Apply channel spacing settings
@@ -235,19 +222,19 @@
-
- Audio bandwidth
+ Audio bandwidth (kHz)
1
- 20
+ 200
1
- 3
+ 30
Qt::Horizontal
@@ -258,12 +245,12 @@
- 25
+ 35
0
- 3k
+ 20.0k
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -274,6 +261,51 @@
-
+
-
+
+
+ RFBW
+
+
+
+ -
+
+
+ RF bandwidth (kHz)
+
+
+ 1
+
+
+ 480
+
+
+ 1
+
+
+ 160
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 35
+ 0
+
+
+
+ 25.0k
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
-
@@ -296,10 +328,10 @@
- Modulation percentage
+ FM peak deviation (kHz)
- 300
+ 200
1
@@ -316,7 +348,7 @@
- 30
+ 35
0
diff --git a/plugins/channeltx/modnfm/nfmmodsettings.cpp b/plugins/channeltx/modnfm/nfmmodsettings.cpp
index a20842346..b8b245899 100644
--- a/plugins/channeltx/modnfm/nfmmodsettings.cpp
+++ b/plugins/channeltx/modnfm/nfmmodsettings.cpp
@@ -24,10 +24,23 @@
#include "settings/serializable.h"
#include "nfmmodsettings.h"
-const int NFMModSettings::m_rfBW[] = {
- 3000, 4000, 5000, 6250, 8330, 10000, 12500, 15000, 20000, 25000, 40000
+// Standard channel spacings (kHz) using Carson rule
+// beta based ............ 11F3 16F3 (36F9)
+// 5 6.25 7.5 8.33 12.5 25 40 Spacing
+// 0.43 0.43 0.43 0.43 0.83 1.67 1.0 Beta
+const int NFMModSettings::m_channelSpacings[] = {
+ 5000, 6250, 7500, 8333, 12500, 25000, 40000
};
-const int NFMModSettings::m_nbRfBW = 11;
+const int NFMModSettings::m_rfBW[] = { // RF bandwidth (Hz)
+ 4800, 6000, 7200, 8000, 11000, 16000, 36000
+};
+const int NFMModSettings::m_afBW[] = { // audio bandwidth (Hz)
+ 1700, 2100, 2500, 2800, 3000, 3000, 9000
+};
+const int NFMModSettings::m_fmDev[] = { // peak deviation (Hz) - full is double
+ 731, 903, 1075, 1204, 2500, 5000, 9000
+};
+const int NFMModSettings::m_nbChannelSpacings = 7;
NFMModSettings::NFMModSettings() :
@@ -41,8 +54,8 @@ void NFMModSettings::resetToDefaults()
{
m_afBandwidth = 3000;
m_inputFrequencyOffset = 0;
- m_rfBandwidth = 12500.0f;
- m_fmDeviation = 3000.0f;
+ m_rfBandwidth = 16000.0f;
+ m_fmDeviation = 10000.0f; //!< full deviation
m_toneFrequency = 1000.0f;
m_volumeFactor = 1.0f;
m_channelMute = false;
@@ -124,7 +137,7 @@ bool NFMModSettings::deserialize(const QByteArray& data)
m_inputFrequencyOffset = tmp;
d.readReal(2, &m_rfBandwidth, 12500.0);
d.readReal(3, &m_afBandwidth, 1000.0);
- d.readReal(4, &m_fmDeviation, 3000.0);
+ d.readReal(4, &m_fmDeviation, 10000.0);
d.readU32(5, &m_rgbColor);
d.readReal(6, &m_toneFrequency, 1000.0);
d.readReal(7, &m_volumeFactor, 1.0);
@@ -184,28 +197,96 @@ bool NFMModSettings::deserialize(const QByteArray& data)
}
}
+int NFMModSettings::getChannelSpacing(int index)
+{
+ if (index < 0) {
+ return m_channelSpacings[0];
+ } else if (index < m_nbChannelSpacings) {
+ return m_channelSpacings[index];
+ } else {
+ return m_channelSpacings[m_nbChannelSpacings-1];
+ }
+}
+
+int NFMModSettings::getChannelSpacingIndex(int channelSpacing)
+{
+ for (int i = 0; i < m_nbChannelSpacings; i++)
+ {
+ if (channelSpacing <= m_channelSpacings[i]) {
+ return i;
+ }
+ }
+
+ return m_nbChannelSpacings-1;
+}
+
int NFMModSettings::getRFBW(int index)
{
if (index < 0) {
return m_rfBW[0];
- } else if (index < m_nbRfBW) {
+ } else if (index < m_nbChannelSpacings) {
return m_rfBW[index];
} else {
- return m_rfBW[m_nbRfBW-1];
+ return m_rfBW[m_nbChannelSpacings-1];
}
}
int NFMModSettings::getRFBWIndex(int rfbw)
{
- for (int i = 0; i < m_nbRfBW; i++)
+ for (int i = 0; i < m_nbChannelSpacings; i++)
{
- if (rfbw <= m_rfBW[i])
- {
+ if (rfbw <= m_rfBW[i]) {
return i;
}
}
- return m_nbRfBW-1;
+ return m_nbChannelSpacings-1;
+}
+
+int NFMModSettings::getAFBW(int index)
+{
+ if (index < 0) {
+ return m_afBW[0];
+ } else if (index < m_nbChannelSpacings) {
+ return m_afBW[index];
+ } else {
+ return m_afBW[m_nbChannelSpacings-1];
+ }
+}
+
+int NFMModSettings::getAFBWIndex(int afbw)
+{
+ for (int i = 0; i < m_nbChannelSpacings; i++)
+ {
+ if (afbw <= m_afBW[i]) {
+ return i;
+ }
+ }
+
+ return m_nbChannelSpacings-1;
+}
+
+int NFMModSettings::getFMDev(int index)
+{
+ if (index < 0) {
+ return m_fmDev[0];
+ } else if (index < m_nbChannelSpacings) {
+ return m_fmDev[index];
+ } else {
+ return m_fmDev[m_nbChannelSpacings-1];
+ }
+}
+
+int NFMModSettings::getFMDevIndex(int fmDev)
+{
+ for (int i = 0; i < m_nbChannelSpacings; i++)
+ {
+ if (fmDev <= m_fmDev[i]) {
+ return i;
+ }
+ }
+
+ return m_nbChannelSpacings-1;
}
int NFMModSettings::getNbCTCSSFreq()
diff --git a/plugins/channeltx/modnfm/nfmmodsettings.h b/plugins/channeltx/modnfm/nfmmodsettings.h
index 9a72a093f..2f55f9f16 100644
--- a/plugins/channeltx/modnfm/nfmmodsettings.h
+++ b/plugins/channeltx/modnfm/nfmmodsettings.h
@@ -35,8 +35,11 @@ struct NFMModSettings
NFMModInputCWTone
} NFMModInputAF;
- static const int m_nbRfBW;
+ static const int m_nbChannelSpacings;
+ static const int m_channelSpacings[];
static const int m_rfBW[];
+ static const int m_afBW[];
+ static const int m_fmDev[];
qint64 m_inputFrequencyOffset;
Real m_rfBandwidth;
@@ -76,8 +79,14 @@ struct NFMModSettings
const CWKeyerSettings& getCWKeyerSettings() const { return m_cwKeyerSettings; }
void setCWKeyerSettings(const CWKeyerSettings& cwKeyerSettings) { m_cwKeyerSettings = cwKeyerSettings; }
+ static int getChannelSpacing(int index);
+ static int getChannelSpacingIndex(int channelSpacing);
static int getRFBW(int index);
static int getRFBWIndex(int rfbw);
+ static int getAFBW(int index);
+ static int getAFBWIndex(int afbw);
+ static int getFMDev(int index);
+ static int getFMDevIndex(int fmDev);
static int getNbCTCSSFreq();
static float getCTCSSFreq(int index);
static int getCTCSSFreqIndex(float ctcssFreq);