diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.cpp b/plugins/channelrx/demodadsb/adsbdemodgui.cpp
index eee08a21c..9eae4e952 100644
--- a/plugins/channelrx/demodadsb/adsbdemodgui.cpp
+++ b/plugins/channelrx/demodadsb/adsbdemodgui.cpp
@@ -1214,6 +1214,21 @@ void ADSBDemodGUI::on_threshold_valueChanged(int value)
applySettings();
}
+void ADSBDemodGUI::on_phaseSteps_valueChanged(int value)
+{
+ ui->phaseStepsText->setText(QString("%1").arg(value));
+ m_settings.m_interpolatorPhaseSteps = value;
+ applySettings();
+}
+
+void ADSBDemodGUI::on_tapsPerPhase_valueChanged(int value)
+{
+ Real tapsPerPhase = ((Real)value)/10.0f;
+ ui->tapsPerPhaseText->setText(QString("%1").arg(tapsPerPhase, 0, 'f', 1));
+ m_settings.m_interpolatorTapsPerPhase = tapsPerPhase;
+ applySettings();
+}
+
void ADSBDemodGUI::on_feed_clicked(bool checked)
{
m_settings.m_feedEnabled = checked;
@@ -1927,6 +1942,18 @@ void ADSBDemodGUI::displaySettings()
ui->thresholdText->setText(QString("%1").arg(m_settings.m_correlationThreshold, 0, 'f', 1));
ui->threshold->setValue((int)(m_settings.m_correlationThreshold*10.0f));
+ ui->phaseStepsText->setText(QString("%1").arg(m_settings.m_interpolatorPhaseSteps));
+ ui->phaseSteps->setValue(m_settings.m_interpolatorPhaseSteps);
+ ui->tapsPerPhaseText->setText(QString("%1").arg(m_settings.m_interpolatorTapsPerPhase, 0, 'f', 1));
+ ui->tapsPerPhase->setValue((int)(m_settings.m_interpolatorTapsPerPhase*10.0f));
+ // Enable these controls only for developers
+ if (1)
+ {
+ ui->phaseStepsText->setVisible(false);
+ ui->phaseSteps->setVisible(false);
+ ui->tapsPerPhaseText->setVisible(false);
+ ui->tapsPerPhase->setVisible(false);
+ }
ui->feed->setChecked(m_settings.m_feedEnabled);
ui->flightPaths->setChecked(m_settings.m_flightPaths);
diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.h b/plugins/channelrx/demodadsb/adsbdemodgui.h
index 347003611..04e82c3a8 100644
--- a/plugins/channelrx/demodadsb/adsbdemodgui.h
+++ b/plugins/channelrx/demodadsb/adsbdemodgui.h
@@ -528,6 +528,8 @@ private slots:
void on_deltaFrequency_changed(qint64 value);
void on_rfBW_valueChanged(int value);
void on_threshold_valueChanged(int value);
+ void on_phaseSteps_valueChanged(int value);
+ void on_tapsPerPhase_valueChanged(int value);
void on_adsbData_cellClicked(int row, int column);
void on_adsbData_cellDoubleClicked(int row, int column);
void adsbData_sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex);
diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.ui b/plugins/channelrx/demodadsb/adsbdemodgui.ui
index d02baadfc..95886ee4e 100644
--- a/plugins/channelrx/demodadsb/adsbdemodgui.ui
+++ b/plugins/channelrx/demodadsb/adsbdemodgui.ui
@@ -6,7 +6,7 @@
0
0
- 384
+ 435
1046
@@ -36,7 +36,7 @@
0
0
- 381
+ 431
141
@@ -167,6 +167,13 @@
-
+
-
+
+
+ Qt::Vertical
+
+
+
-
@@ -203,10 +210,17 @@
-
+
-
+
+
+ Qt::Vertical
+
+
+
-
- RFBW
+ BW
@@ -262,6 +276,85 @@
+ -
+
+
+
+ 24
+ 24
+
+
+
+ Interpolator phase steps
+
+
+ 1
+
+
+ 16
+
+
+ 1
+
+
+ 16
+
+
+
+ -
+
+
+
+ 16
+ 0
+
+
+
+ 12
+
+
+
+ -
+
+
+ true
+
+
+
+ 24
+ 24
+
+
+
+ Interpolator taps per phase
+
+
+ 10
+
+
+ 60
+
+
+ 1
+
+
+ 45
+
+
+
+ -
+
+
+
+ 16
+ 0
+
+
+
+ 4.5
+
+
+
-
@@ -547,7 +640,7 @@
0
140
- 381
+ 431
291
@@ -787,7 +880,7 @@
10
450
- 361
+ 421
581
@@ -879,8 +972,21 @@
deltaFrequency
rfBW
+ phaseSteps
+ tapsPerPhase
spb
+ demodModeS
+ correlateFullPreamble
threshold
+ getOSNDB
+ getAirportDB
+ displaySettings
+ flightPaths
+ feed
+ devicesRefresh
+ device
+ adsbData
+ map
diff --git a/plugins/channelrx/demodadsb/adsbdemodsettings.cpp b/plugins/channelrx/demodadsb/adsbdemodsettings.cpp
index 464db1aa7..c8edf7997 100644
--- a/plugins/channelrx/demodadsb/adsbdemodsettings.cpp
+++ b/plugins/channelrx/demodadsb/adsbdemodsettings.cpp
@@ -61,6 +61,8 @@ void ADSBDemodSettings::resetToDefaults()
m_demodModeS = false;
m_deviceIndex = -1;
m_autoResizeTableColumns = false;
+ m_interpolatorPhaseSteps = 4; // Higher than these two values will struggle to run in real-time
+ m_interpolatorTapsPerPhase = 3.5f; // without gaining much improvement in PER
for (int i = 0; i < ADSBDEMOD_COLUMNS; i++)
{
m_columnIndexes[i] = i;
@@ -105,6 +107,8 @@ QByteArray ADSBDemodSettings::serialize() const
s.writeBool(28, m_correlateFullPreamble);
s.writeBool(29, m_demodModeS);
s.writeBool(30, m_autoResizeTableColumns);
+ s.writeS32(31, m_interpolatorPhaseSteps);
+ s.writeFloat(32, m_interpolatorTapsPerPhase);
for (int i = 0; i < ADSBDEMOD_COLUMNS; i++)
s.writeS32(100 + i, m_columnIndexes[i]);
@@ -182,6 +186,8 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
d.readBool(28, &m_correlateFullPreamble, true);
d.readBool(29, &m_demodModeS, false);
d.readBool(30, &m_autoResizeTableColumns, false);
+ d.readS32(31, &m_interpolatorPhaseSteps, 4);
+ d.readFloat(32, &m_interpolatorTapsPerPhase, 3.5f);
for (int i = 0; i < ADSBDEMOD_COLUMNS; i++)
d.readS32(100 + i, &m_columnIndexes[i], i);
diff --git a/plugins/channelrx/demodadsb/adsbdemodsettings.h b/plugins/channelrx/demodadsb/adsbdemodsettings.h
index c8d1d621d..081e5934d 100644
--- a/plugins/channelrx/demodadsb/adsbdemodsettings.h
+++ b/plugins/channelrx/demodadsb/adsbdemodsettings.h
@@ -74,6 +74,8 @@ struct ADSBDemodSettings
bool m_demodModeS; //!< Demodulate all Mode-S frames, not just ADS-B
int m_deviceIndex; //!< Device to set to ATC frequencies
bool m_autoResizeTableColumns;
+ int m_interpolatorPhaseSteps;
+ float m_interpolatorTapsPerPhase;
ADSBDemodSettings();
void resetToDefaults();
diff --git a/plugins/channelrx/demodadsb/adsbdemodsink.cpp b/plugins/channelrx/demodadsb/adsbdemodsink.cpp
index 80ee2a517..1983f82f4 100644
--- a/plugins/channelrx/demodadsb/adsbdemodsink.cpp
+++ b/plugins/channelrx/demodadsb/adsbdemodsink.cpp
@@ -83,33 +83,41 @@ void ADSBDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
processOneSample(magsq);
}
}
- else
+ else if (m_interpolatorDistance == 1.0f) // just apply offset
{
for (SampleVector::const_iterator it = begin; it != end; ++it)
{
Complex c(it->real(), it->imag());
Complex ci;
c *= m_nco.nextIQ();
-
- if (m_interpolatorDistance == 1.0f)
+ processOneSample(complexMagSq(c));
+ }
+ }
+ else if (m_interpolatorDistance < 1.0f) // interpolate
+ {
+ for (SampleVector::const_iterator it = begin; it != end; ++it)
+ {
+ Complex c(it->real(), it->imag());
+ Complex ci;
+ c *= m_nco.nextIQ();
+ while (!m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci))
{
- processOneSample(complexMagSq(c));
+ processOneSample(complexMagSq(ci));
+ m_interpolatorDistanceRemain += m_interpolatorDistance;
}
- else if (m_interpolatorDistance < 1.0f) // interpolate
+ }
+ }
+ else // decimate
+ {
+ for (SampleVector::const_iterator it = begin; it != end; ++it)
+ {
+ Complex c(it->real(), it->imag());
+ Complex ci;
+ c *= m_nco.nextIQ();
+ if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci))
{
- while (!m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci))
- {
- processOneSample(complexMagSq(ci));
- m_interpolatorDistanceRemain += m_interpolatorDistance;
- }
- }
- else // decimate
- {
- if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci))
- {
- processOneSample(complexMagSq(ci));
- m_interpolatorDistanceRemain += m_interpolatorDistance;
- }
+ processOneSample(complexMagSq(ci));
+ m_interpolatorDistanceRemain += m_interpolatorDistance;
}
}
}
@@ -228,7 +236,7 @@ void ADSBDemodSink::applyChannelSettings(int channelSampleRate, int channelFrequ
if ((channelSampleRate != m_channelSampleRate) || force)
{
- m_interpolator.create(16, channelSampleRate, m_settings.m_rfBandwidth / 2.2);
+ m_interpolator.create(m_settings.m_interpolatorPhaseSteps, channelSampleRate, m_settings.m_rfBandwidth / 2.2, m_settings.m_interpolatorTapsPerPhase);
m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) channelSampleRate / (Real) (ADS_B_BITS_PER_SECOND * m_settings.m_samplesPerBit);
}
@@ -249,9 +257,12 @@ void ADSBDemodSink::applySettings(const ADSBDemodSettings& settings, bool force)
<< " force: " << force;
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth)
- || (settings.m_samplesPerBit != m_settings.m_samplesPerBit) || force)
+ || (settings.m_samplesPerBit != m_settings.m_samplesPerBit)
+ || (settings.m_interpolatorPhaseSteps != m_settings.m_interpolatorPhaseSteps)
+ || (settings.m_interpolatorTapsPerPhase != m_settings.m_interpolatorTapsPerPhase)
+ || force)
{
- m_interpolator.create(16, m_channelSampleRate, settings.m_rfBandwidth / 2.2);
+ m_interpolator.create(m_settings.m_interpolatorPhaseSteps, m_channelSampleRate, settings.m_rfBandwidth / 2.2, m_settings.m_interpolatorTapsPerPhase);
m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) m_channelSampleRate / (Real) (ADS_B_BITS_PER_SECOND * settings.m_samplesPerBit);
}