mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-04-10 13:40:37 -04:00
Frequency tracker (5)
This commit is contained in:
parent
459063d4f2
commit
4c278eef8d
@ -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<<m_settings.m_log2Decim);
|
||||
if (m_channelSampleRate != m_deviceSampleRate / (1<<m_settings.m_log2Decim))
|
||||
{
|
||||
m_channelSampleRate = m_deviceSampleRate / (1<<m_settings.m_log2Decim);
|
||||
m_pll.setSampleRate(m_channelSampleRate);
|
||||
m_fll.setSampleRate(m_channelSampleRate);
|
||||
}
|
||||
|
||||
qDebug() << "FreqTracker::configureChannelizer:"
|
||||
<< " sampleRate: " << m_channelSampleRate
|
||||
<< " inputFrequencyOffset: " << m_settings.m_inputFrequencyOffset;
|
||||
|
||||
m_pll.setSampleRate(m_channelSampleRate);
|
||||
m_fll.setSampleRate(m_channelSampleRate);
|
||||
|
||||
m_channelizer->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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user