From bb35db0703a15a043e206557d064d801de2b14a4 Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 21 Jul 2020 02:08:58 +0200 Subject: [PATCH] Channel Analyzer: fixed rational downsampler --- .../chanalyzer/chanalyzerbaseband.cpp | 10 +- .../channelrx/chanalyzer/chanalyzerbaseband.h | 1 - .../channelrx/chanalyzer/chanalyzergui.cpp | 14 +-- plugins/channelrx/chanalyzer/chanalyzergui.h | 2 +- .../channelrx/chanalyzer/chanalyzersink.cpp | 92 +++++++++++++------ plugins/channelrx/chanalyzer/chanalyzersink.h | 8 +- 6 files changed, 77 insertions(+), 50 deletions(-) diff --git a/plugins/channelrx/chanalyzer/chanalyzerbaseband.cpp b/plugins/channelrx/chanalyzer/chanalyzerbaseband.cpp index 0eb425dab..fe25313ce 100644 --- a/plugins/channelrx/chanalyzer/chanalyzerbaseband.cpp +++ b/plugins/channelrx/chanalyzer/chanalyzerbaseband.cpp @@ -137,7 +137,7 @@ bool ChannelAnalyzerBaseband::handleMessage(const Message& cmd) qDebug() << "ChannelAnalyzerBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate(); m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(notif.getSampleRate())); m_channelizer->setBasebandSampleRate(notif.getSampleRate()); - int desiredSampleRate = getSinkSampleRate(m_settings); + int desiredSampleRate = m_channelizer->getBasebandSampleRate() / (1<setChannelization(desiredSampleRate, m_settings.m_inputFrequencyOffset); m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), desiredSampleRate, m_channelizer->getChannelFrequencyOffset()); @@ -156,7 +156,7 @@ void ChannelAnalyzerBaseband::applySettings(const ChannelAnalyzerSettings& setti || (settings.m_rationalDownSamplerRate != m_settings.m_rationalDownSamplerRate) || (settings.m_rationalDownSample != m_settings.m_rationalDownSample) || force) { - int desiredSampleRate = getSinkSampleRate(settings); + int desiredSampleRate = m_channelizer->getBasebandSampleRate() / (1<setChannelization(desiredSampleRate, settings.m_inputFrequencyOffset); m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), desiredSampleRate, m_channelizer->getChannelFrequencyOffset()); } @@ -165,12 +165,6 @@ void ChannelAnalyzerBaseband::applySettings(const ChannelAnalyzerSettings& setti m_settings = settings; } -int ChannelAnalyzerBaseband::getSinkSampleRate(ChannelAnalyzerSettings settings) -{ - int normalSinkSampleRate = m_channelizer->getBasebandSampleRate() / (1<getChannelSampleRate(); diff --git a/plugins/channelrx/chanalyzer/chanalyzerbaseband.h b/plugins/channelrx/chanalyzer/chanalyzerbaseband.h index 4a22d9a47..cde93301f 100644 --- a/plugins/channelrx/chanalyzer/chanalyzerbaseband.h +++ b/plugins/channelrx/chanalyzer/chanalyzerbaseband.h @@ -84,7 +84,6 @@ private: bool handleMessage(const Message& cmd); void applySettings(const ChannelAnalyzerSettings& settings, bool force = false); - int getSinkSampleRate(ChannelAnalyzerSettings settngs); private slots: void handleInputMessages(); diff --git a/plugins/channelrx/chanalyzer/chanalyzergui.cpp b/plugins/channelrx/chanalyzer/chanalyzergui.cpp index d2fd7648d..9c063f600 100644 --- a/plugins/channelrx/chanalyzer/chanalyzergui.cpp +++ b/plugins/channelrx/chanalyzer/chanalyzergui.cpp @@ -274,13 +274,6 @@ void ChannelAnalyzerGUI::on_useRationalDownsampler_toggled(bool checked) applySettings(); } -int ChannelAnalyzerGUI::getSinkSampleRate() -{ - return m_settings.m_rationalDownSample ? - m_settings.m_rationalDownSamplerRate - : m_basebandSampleRate / (1<real(), it->imag()); c *= m_nco.nextIQ(); - if (m_interpolatorDistance == 1) + if (m_decimator.getDecim() == 1) { processOneSample(c, sideband); } else { - if (m_settings.m_rationalDownSample) + if (m_decimator.decimate(c, ci)) { - if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci)) + if (m_settings.m_rationalDownSample) + { + Complex cj; + + if (m_interpolator.decimate(&m_interpolatorDistanceRemain, ci, &cj)) + { + processOneSample(cj, sideband); + m_interpolatorDistanceRemain += m_interpolatorDistance; + } + } + else { processOneSample(ci, sideband); - m_interpolatorDistanceRemain += m_interpolatorDistance; } } - else - { - if (m_decimator.decimate(c, ci)) { - processOneSample(ci, sideband); - } - } - } + } } if (m_sampleSink) { @@ -146,6 +147,7 @@ void ChannelAnalyzerSink::applyChannelSettings(int channelSampleRate, int sinkSa << " channelSampleRate: " << channelSampleRate << " sinkSampleRate: " << sinkSampleRate << " channelFrequencyOffset: " << channelFrequencyOffset; + bool doApplySampleRate = false; if ((m_channelFrequencyOffset != channelFrequencyOffset) || (m_channelSampleRate != channelSampleRate) || force) @@ -156,13 +158,9 @@ void ChannelAnalyzerSink::applyChannelSettings(int channelSampleRate, int sinkSa if ((m_channelSampleRate != channelSampleRate) || (m_sinkSampleRate != sinkSampleRate) || force) { - m_interpolator.create(16, channelSampleRate, channelSampleRate / 2.2f); + m_interpolator.create(16, sinkSampleRate, sinkSampleRate / 4.0f); m_interpolatorDistanceRemain = 0; - m_interpolatorDistance = (Real) channelSampleRate / (Real) sinkSampleRate; - - setFilters(sinkSampleRate, m_settings.m_bandwidth, m_settings.m_lowCutoff); - m_pll.setSampleRate(sinkSampleRate); - m_fll.setSampleRate(sinkSampleRate); + m_interpolatorDistance = (Real) sinkSampleRate / (Real) m_settings.m_rationalDownSamplerRate; int decim = channelSampleRate / sinkSampleRate; m_decimator.setLog2Decim(0); @@ -178,11 +176,17 @@ void ChannelAnalyzerSink::applyChannelSettings(int channelSampleRate, int sinkSa decim >>= 1; } + + doApplySampleRate = true; } m_channelSampleRate = channelSampleRate; m_channelFrequencyOffset = channelFrequencyOffset; m_sinkSampleRate = sinkSampleRate; + + if (doApplySampleRate) { + applySampleRate(); + } } void ChannelAnalyzerSink::setFilters(int sampleRate, float bandwidth, float lowCutoff) @@ -216,29 +220,25 @@ void ChannelAnalyzerSink::applySettings(const ChannelAnalyzerSettings& settings, { qDebug() << "ChannelAnalyzerSink::applySettings:" << " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset - << " m_rationalDownSample: " << settings.m_rationalDownSample - << " m_rationalDownSamplerRate: " << settings.m_rationalDownSamplerRate << " m_rcc: " << settings.m_rrc << " m_rrcRolloff: " << settings.m_rrcRolloff / 100.0 << " m_bandwidth: " << settings.m_bandwidth << " m_lowCutoff: " << settings.m_lowCutoff << " m_log2Decim: " << settings.m_log2Decim + << " m_rationalDownSample: " << settings.m_rationalDownSample + << " m_rationalDownSamplerRate: " << settings.m_rationalDownSamplerRate << " m_ssb: " << settings.m_ssb << " m_pll: " << settings.m_pll << " m_fll: " << settings.m_fll << " m_pllPskOrder: " << settings.m_pllPskOrder << " m_inputType: " << (int) settings.m_inputType; + bool doApplySampleRate = false; if ((settings.m_bandwidth != m_settings.m_bandwidth) || - (settings.m_lowCutoff != m_settings.m_lowCutoff)|| force) + (settings.m_lowCutoff != m_settings.m_lowCutoff) || + (settings.m_rrcRolloff != m_settings.m_rrcRolloff) || force) { - setFilters(m_sinkSampleRate, settings.m_bandwidth, settings.m_lowCutoff); - } - - if ((settings.m_rrcRolloff != m_settings.m_rrcRolloff) || force) - { - float sinkSampleRate = (float) m_sinkSampleRate; - RRCFilter->create_rrc_filter(settings.m_bandwidth / sinkSampleRate, settings.m_rrcRolloff / 100.0); + doApplySampleRate = true; } if (settings.m_pll != m_settings.m_pll || force) @@ -264,7 +264,20 @@ void ChannelAnalyzerSink::applySettings(const ChannelAnalyzerSettings& settings, } } + if ((settings.m_rationalDownSample != m_settings.m_rationalDownSample) || + (settings.m_rationalDownSamplerRate != m_settings.m_rationalDownSamplerRate) || force) + { + m_interpolator.create(16, m_sinkSampleRate, m_sinkSampleRate / 4.0f); + m_interpolatorDistanceRemain = 0; + m_interpolatorDistance = (Real) m_sinkSampleRate / (Real) settings.m_rationalDownSamplerRate; + doApplySampleRate = true; + } + m_settings = settings; + + if (doApplySampleRate) { + applySampleRate(); + } } Real ChannelAnalyzerSink::getPllFrequency() const @@ -277,3 +290,22 @@ Real ChannelAnalyzerSink::getPllFrequency() const return 0.0; } } + +int ChannelAnalyzerSink::getActualSampleRate() +{ + if (m_settings.m_rationalDownSample) { + return m_settings.m_rationalDownSamplerRate; + } else { + return m_sinkSampleRate; + } +} + +void ChannelAnalyzerSink::applySampleRate() +{ + int sampleRate = getActualSampleRate(); + qDebug("ChannelAnalyzerSink::applySampleRate: sampleRate: %d m_interpolatorDistance: %f", sampleRate, m_interpolatorDistance); + setFilters(sampleRate, m_settings.m_bandwidth, m_settings.m_lowCutoff); + m_pll.setSampleRate(sampleRate); + m_fll.setSampleRate(sampleRate); + RRCFilter->create_rrc_filter(m_settings.m_bandwidth / (float) sampleRate, m_settings.m_rrcRolloff / 100.0); +} \ No newline at end of file diff --git a/plugins/channelrx/chanalyzer/chanalyzersink.h b/plugins/channelrx/chanalyzer/chanalyzersink.h index 4f9ca989a..1e5269c19 100644 --- a/plugins/channelrx/chanalyzer/chanalyzersink.h +++ b/plugins/channelrx/chanalyzer/chanalyzersink.h @@ -65,11 +65,11 @@ private: double m_magsq; NCOF m_nco; + Interpolator m_interpolator; + Real m_interpolatorDistance; + Real m_interpolatorDistanceRemain; PhaseLockComplex m_pll; FreqLockComplex m_fll; - Interpolator m_interpolator; - Real m_interpolatorDistance; - Real m_interpolatorDistanceRemain; DecimatorC m_decimator; fftfilt* SSBFilter; @@ -84,6 +84,8 @@ private: void setFilters(int sampleRate, float bandwidth, float lowCutoff); void processOneSample(Complex& c, fftfilt::cmplx *sideband); + int getActualSampleRate(); + void applySampleRate(); inline void feedOneSample(const fftfilt::cmplx& s, const fftfilt::cmplx& pll) {