mirror of https://github.com/f4exb/sdrangel.git
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->addThreadedSink(m_threadedChannelizer);
|
||||||
m_deviceAPI->addChannelAPI(this);
|
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();
|
m_networkManager = new QNetworkAccessManager();
|
||||||
connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
|
connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
|
||||||
|
@ -105,6 +106,7 @@ FreqTracker::~FreqTracker()
|
||||||
m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
|
m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
|
||||||
delete m_threadedChannelizer;
|
delete m_threadedChannelizer;
|
||||||
delete m_channelizer;
|
delete m_channelizer;
|
||||||
|
delete m_rrcFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreqTracker::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst)
|
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)
|
void FreqTracker::processOneSample(Complex &ci)
|
||||||
{
|
{
|
||||||
Real re = ci.real() / SDR_RX_SCALEF;
|
fftfilt::cmplx *sideband;
|
||||||
Real im = ci.imag() / SDR_RX_SCALEF;
|
int n_out;
|
||||||
Real magsq = re*re + im*im;
|
|
||||||
m_movingAverage(magsq);
|
|
||||||
m_magsq = m_movingAverage.asDouble();
|
|
||||||
m_magsqSum += magsq;
|
|
||||||
|
|
||||||
if (magsq > m_magsqPeak)
|
if (m_settings.m_rrc)
|
||||||
{
|
{
|
||||||
m_magsqPeak = magsq;
|
n_out = m_rrcFilter->runFilt(ci, &sideband);
|
||||||
}
|
|
||||||
|
|
||||||
m_magsqCount++;
|
|
||||||
|
|
||||||
if (m_magsq < m_squelchLevel)
|
|
||||||
{
|
|
||||||
if (m_squelchCount > 0) {
|
|
||||||
m_squelchCount--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_squelchCount < m_channelSampleRate / 10) {
|
n_out = 1;
|
||||||
m_squelchCount++;
|
sideband = &ci;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_squelchOpen = (m_squelchCount >= m_channelSampleRate / 20);
|
for (int i = 0; i < n_out; i++)
|
||||||
|
|
||||||
if (m_squelchOpen)
|
|
||||||
{
|
{
|
||||||
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");
|
reverseAPIKeys.append("tracking");
|
||||||
m_avgDeltaFreq = 0.0;
|
m_avgDeltaFreq = 0.0;
|
||||||
|
m_lastCorrAbs = 0;
|
||||||
|
|
||||||
if (settings.m_tracking)
|
if (settings.m_tracking)
|
||||||
{
|
{
|
||||||
m_pll.reset();
|
m_pll.reset();
|
||||||
m_fll.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) {
|
} else if (settings.m_trackerType == FreqTrackerSettings::TrackerPLL) {
|
||||||
m_pll.reset();
|
m_pll.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.m_trackerType == FreqTrackerSettings::TrackerNone) {
|
||||||
|
disconnectTimer();
|
||||||
|
} else {
|
||||||
|
connectTimer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_settings.m_pllPskOrder != settings.m_pllPskOrder) || force)
|
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) {
|
if ((m_settings.m_rrc != settings.m_rrc) || force) {
|
||||||
reverseAPIKeys.append("rrc");
|
reverseAPIKeys.append("rrc");
|
||||||
}
|
}
|
||||||
if ((m_settings.m_rrcRolloff != settings.m_rrcRolloff) || force) {
|
if ((m_settings.m_rrcRolloff != settings.m_rrcRolloff) || force)
|
||||||
|
{
|
||||||
reverseAPIKeys.append("rrcRolloff");
|
reverseAPIKeys.append("rrcRolloff");
|
||||||
|
updateInterpolator = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.m_useReverseAPI)
|
if (settings.m_useReverseAPI)
|
||||||
|
@ -406,20 +427,23 @@ void FreqTracker::setInterpolator()
|
||||||
m_interpolator.create(16, m_inputSampleRate, m_settings.m_rfBandwidth / 2.2f);
|
m_interpolator.create(16, m_inputSampleRate, m_settings.m_rfBandwidth / 2.2f);
|
||||||
m_interpolatorDistanceRemain = 0;
|
m_interpolatorDistanceRemain = 0;
|
||||||
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) m_channelSampleRate;
|
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();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreqTracker::configureChannelizer()
|
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:"
|
qDebug() << "FreqTracker::configureChannelizer:"
|
||||||
<< " sampleRate: " << m_channelSampleRate
|
<< " sampleRate: " << m_channelSampleRate
|
||||||
<< " inputFrequencyOffset: " << m_settings.m_inputFrequencyOffset;
|
<< " inputFrequencyOffset: " << m_settings.m_inputFrequencyOffset;
|
||||||
|
|
||||||
m_pll.setSampleRate(m_channelSampleRate);
|
|
||||||
m_fll.setSampleRate(m_channelSampleRate);
|
|
||||||
|
|
||||||
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
||||||
m_channelSampleRate,
|
m_channelSampleRate,
|
||||||
m_settings.m_inputFrequencyOffset);
|
m_settings.m_inputFrequencyOffset);
|
||||||
|
@ -682,7 +706,7 @@ void FreqTracker::networkManagerFinished(QNetworkReply *reply)
|
||||||
|
|
||||||
void FreqTracker::tick()
|
void FreqTracker::tick()
|
||||||
{
|
{
|
||||||
if (getSquelchOpen() && (m_settings.m_trackerType != FreqTrackerSettings::TrackerNone)) {
|
if (getSquelchOpen()) {
|
||||||
m_avgDeltaFreq = 0.1*getFrequency() + 0.9*m_avgDeltaFreq;
|
m_avgDeltaFreq = 0.1*getFrequency() + 0.9*m_avgDeltaFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,7 +716,7 @@ void FreqTracker::tick()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (getSquelchOpen() && (m_settings.m_trackerType != FreqTrackerSettings::TrackerNone))
|
if ((m_settings.m_tracking) && getSquelchOpen())
|
||||||
{
|
{
|
||||||
int decayAmount = m_channelSampleRate < 100 ? 1 : m_channelSampleRate / 100;
|
int decayAmount = m_channelSampleRate < 100 ? 1 : m_channelSampleRate / 100;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
#include "dsp/basebandsamplesink.h"
|
#include "dsp/basebandsamplesink.h"
|
||||||
#include "channel/channelsinkapi.h"
|
#include "channel/channelsinkapi.h"
|
||||||
#include "dsp/nco.h"
|
#include "dsp/ncof.h"
|
||||||
#include "dsp/interpolator.h"
|
#include "dsp/interpolator.h"
|
||||||
#include "util/movingaverage.h"
|
#include "util/movingaverage.h"
|
||||||
#include "dsp/agc.h"
|
#include "dsp/agc.h"
|
||||||
|
@ -196,20 +196,20 @@ private:
|
||||||
DownChannelizer* m_channelizer;
|
DownChannelizer* m_channelizer;
|
||||||
FreqTrackerSettings m_settings;
|
FreqTrackerSettings m_settings;
|
||||||
|
|
||||||
int m_deviceSampleRate;
|
uint32_t m_deviceSampleRate;
|
||||||
int m_inputSampleRate;
|
int m_inputSampleRate;
|
||||||
int m_inputFrequencyOffset;
|
int m_inputFrequencyOffset;
|
||||||
uint32_t m_channelSampleRate;
|
uint32_t m_channelSampleRate;
|
||||||
bool m_running;
|
bool m_running;
|
||||||
|
|
||||||
NCO m_nco;
|
NCOF m_nco;
|
||||||
PhaseLockComplex m_pll;
|
PhaseLockComplex m_pll;
|
||||||
FreqLockComplex m_fll;
|
FreqLockComplex m_fll;
|
||||||
Interpolator m_interpolator;
|
Interpolator m_interpolator;
|
||||||
Real m_interpolatorDistance;
|
Real m_interpolatorDistance;
|
||||||
Real m_interpolatorDistanceRemain;
|
Real m_interpolatorDistanceRemain;
|
||||||
|
|
||||||
fftfilt* RRCFilter;
|
fftfilt* m_rrcFilter;
|
||||||
|
|
||||||
Real m_squelchLevel;
|
Real m_squelchLevel;
|
||||||
uint32_t m_squelchCount;
|
uint32_t m_squelchCount;
|
||||||
|
|
Loading…
Reference in New Issue