diff --git a/plugins/channelrx/freqtracker/freqtracker.cpp b/plugins/channelrx/freqtracker/freqtracker.cpp index 5cd70d82c..a92893056 100644 --- a/plugins/channelrx/freqtracker/freqtracker.cpp +++ b/plugins/channelrx/freqtracker/freqtracker.cpp @@ -84,7 +84,8 @@ FreqTracker::FreqTracker(DeviceSourceAPI *deviceAPI) : m_deviceAPI->addThreadedSink(m_threadedChannelizer); m_deviceAPI->addChannelAPI(this); - m_pll.computeCoefficients(0.05, 0.707, 1000); + m_pll.computeCoefficients(0.002f, 0.5f, 10.0f); // bandwidth, damping factor, loop gain + m_rrcFilter = new fftfilt(m_settings.m_rfBandwidth / m_channelSampleRate, 2*1024); m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); @@ -105,6 +106,7 @@ FreqTracker::~FreqTracker() m_deviceAPI->removeThreadedSink(m_threadedChannelizer); delete m_threadedChannelizer; delete m_channelizer; + delete m_rrcFilter; } void FreqTracker::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) @@ -149,44 +151,60 @@ void FreqTracker::feed(const SampleVector::const_iterator& begin, const SampleVe void FreqTracker::processOneSample(Complex &ci) { - Real re = ci.real() / SDR_RX_SCALEF; - Real im = ci.imag() / SDR_RX_SCALEF; - Real magsq = re*re + im*im; - m_movingAverage(magsq); - m_magsq = m_movingAverage.asDouble(); - m_magsqSum += magsq; + fftfilt::cmplx *sideband; + int n_out; - if (magsq > m_magsqPeak) + if (m_settings.m_rrc) { - m_magsqPeak = magsq; - } - - m_magsqCount++; - - if (m_magsq < m_squelchLevel) - { - if (m_squelchCount > 0) { - m_squelchCount--; - } + n_out = m_rrcFilter->runFilt(ci, &sideband); } else { - if (m_squelchCount < m_channelSampleRate / 10) { - m_squelchCount++; - } + n_out = 1; + sideband = &ci; } - m_squelchOpen = (m_squelchCount >= m_channelSampleRate / 20); - - if (m_squelchOpen) + for (int i = 0; i < n_out; i++) { - if (m_settings.m_trackerType == FreqTrackerSettings::TrackerFLL) + Real re = sideband[i].real() / SDR_RX_SCALEF; + Real im = sideband[i].imag() / SDR_RX_SCALEF; + Real magsq = re*re + im*im; + m_movingAverage(magsq); + m_magsq = m_movingAverage.asDouble(); + m_magsqSum += magsq; + + if (magsq > m_magsqPeak) { - m_fll.feed(re, im); + m_magsqPeak = magsq; } - else if (m_settings.m_trackerType == FreqTrackerSettings::TrackerPLL) + + m_magsqCount++; + + if (m_magsq < m_squelchLevel) { - m_pll.feed(re, im); + if (m_squelchCount > 0) { + m_squelchCount--; + } + } + else + { + if (m_squelchCount < m_channelSampleRate / 10) { + m_squelchCount++; + } + } + + m_squelchOpen = (m_squelchCount >= m_channelSampleRate / 20); + + if (m_squelchOpen) + { + if (m_settings.m_trackerType == FreqTrackerSettings::TrackerFLL) + { + m_fll.feed(re, im); + } + else if (m_settings.m_trackerType == FreqTrackerSettings::TrackerPLL) + { + m_pll.feed(re, im); + } } } } @@ -338,17 +356,12 @@ void FreqTracker::applySettings(const FreqTrackerSettings& settings, bool force) { reverseAPIKeys.append("tracking"); m_avgDeltaFreq = 0.0; + m_lastCorrAbs = 0; if (settings.m_tracking) { m_pll.reset(); m_fll.reset(); - m_lastCorrAbs = 0; - connectTimer(); - } - else - { - disconnectTimer(); } } @@ -363,6 +376,12 @@ void FreqTracker::applySettings(const FreqTrackerSettings& settings, bool force) } else if (settings.m_trackerType == FreqTrackerSettings::TrackerPLL) { m_pll.reset(); } + + if (settings.m_trackerType == FreqTrackerSettings::TrackerNone) { + disconnectTimer(); + } else { + connectTimer(); + } } if ((m_settings.m_pllPskOrder != settings.m_pllPskOrder) || force) @@ -377,8 +396,10 @@ void FreqTracker::applySettings(const FreqTrackerSettings& settings, bool force) if ((m_settings.m_rrc != settings.m_rrc) || force) { reverseAPIKeys.append("rrc"); } - if ((m_settings.m_rrcRolloff != settings.m_rrcRolloff) || force) { + if ((m_settings.m_rrcRolloff != settings.m_rrcRolloff) || force) + { reverseAPIKeys.append("rrcRolloff"); + updateInterpolator = true; } if (settings.m_useReverseAPI) @@ -406,20 +427,23 @@ void FreqTracker::setInterpolator() m_interpolator.create(16, m_inputSampleRate, m_settings.m_rfBandwidth / 2.2f); m_interpolatorDistanceRemain = 0; m_interpolatorDistance = (Real) m_inputSampleRate / (Real) m_channelSampleRate; + m_rrcFilter->create_rrc_filter(m_settings.m_rfBandwidth / m_channelSampleRate, m_settings.m_rrcRolloff / 100.0); m_settingsMutex.unlock(); } void FreqTracker::configureChannelizer() { - m_channelSampleRate = m_deviceSampleRate / (1<configure(m_channelizer->getInputMessageQueue(), m_channelSampleRate, m_settings.m_inputFrequencyOffset); @@ -682,7 +706,7 @@ void FreqTracker::networkManagerFinished(QNetworkReply *reply) void FreqTracker::tick() { - if (getSquelchOpen() && (m_settings.m_trackerType != FreqTrackerSettings::TrackerNone)) { + if (getSquelchOpen()) { m_avgDeltaFreq = 0.1*getFrequency() + 0.9*m_avgDeltaFreq; } @@ -692,7 +716,7 @@ void FreqTracker::tick() } else { - if (getSquelchOpen() && (m_settings.m_trackerType != FreqTrackerSettings::TrackerNone)) + if ((m_settings.m_tracking) && getSquelchOpen()) { int decayAmount = m_channelSampleRate < 100 ? 1 : m_channelSampleRate / 100; diff --git a/plugins/channelrx/freqtracker/freqtracker.h b/plugins/channelrx/freqtracker/freqtracker.h index 4bbd76fd0..0216ba990 100644 --- a/plugins/channelrx/freqtracker/freqtracker.h +++ b/plugins/channelrx/freqtracker/freqtracker.h @@ -25,7 +25,7 @@ #include "dsp/basebandsamplesink.h" #include "channel/channelsinkapi.h" -#include "dsp/nco.h" +#include "dsp/ncof.h" #include "dsp/interpolator.h" #include "util/movingaverage.h" #include "dsp/agc.h" @@ -196,20 +196,20 @@ private: DownChannelizer* m_channelizer; FreqTrackerSettings m_settings; - int m_deviceSampleRate; + uint32_t m_deviceSampleRate; int m_inputSampleRate; int m_inputFrequencyOffset; uint32_t m_channelSampleRate; bool m_running; - NCO m_nco; + NCOF m_nco; PhaseLockComplex m_pll; FreqLockComplex m_fll; Interpolator m_interpolator; Real m_interpolatorDistance; Real m_interpolatorDistanceRemain; - fftfilt* RRCFilter; + fftfilt* m_rrcFilter; Real m_squelchLevel; uint32_t m_squelchCount;