mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
Frequency Tracker: add spectrum display. Implements #665
This commit is contained in:
parent
86ce2ca843
commit
b04bb24146
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 57 KiB |
Binary file not shown.
@ -55,12 +55,14 @@ const int FreqTracker::m_udpBlockSize = 512;
|
|||||||
FreqTracker::FreqTracker(DeviceAPI *deviceAPI) :
|
FreqTracker::FreqTracker(DeviceAPI *deviceAPI) :
|
||||||
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink),
|
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink),
|
||||||
m_deviceAPI(deviceAPI),
|
m_deviceAPI(deviceAPI),
|
||||||
|
m_spectrumVis(SDR_RX_SCALEF),
|
||||||
m_basebandSampleRate(0)
|
m_basebandSampleRate(0)
|
||||||
{
|
{
|
||||||
setObjectName(m_channelId);
|
setObjectName(m_channelId);
|
||||||
|
|
||||||
m_thread = new QThread(this);
|
m_thread = new QThread(this);
|
||||||
m_basebandSink = new FreqTrackerBaseband();
|
m_basebandSink = new FreqTrackerBaseband();
|
||||||
|
m_basebandSink->setSpectrumSink(&m_spectrumVis);
|
||||||
propagateMessageQueue(getInputMessageQueue());
|
propagateMessageQueue(getInputMessageQueue());
|
||||||
m_basebandSink->moveToThread(m_thread);
|
m_basebandSink->moveToThread(m_thread);
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
|
||||||
#include "dsp/basebandsamplesink.h"
|
#include "dsp/basebandsamplesink.h"
|
||||||
|
#include "dsp/spectrumvis.h"
|
||||||
#include "channel/channelapi.h"
|
#include "channel/channelapi.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
|
|
||||||
@ -109,6 +110,7 @@ public:
|
|||||||
const QStringList& channelSettingsKeys,
|
const QStringList& channelSettingsKeys,
|
||||||
SWGSDRangel::SWGChannelSettings& response);
|
SWGSDRangel::SWGChannelSettings& response);
|
||||||
|
|
||||||
|
SpectrumVis *getSpectrumVis() { return &m_spectrumVis; }
|
||||||
uint32_t getSampleRate() const { return m_basebandSink->getSampleRate(); }
|
uint32_t getSampleRate() const { return m_basebandSink->getSampleRate(); }
|
||||||
double getMagSq() const { return m_basebandSink->getMagSq(); }
|
double getMagSq() const { return m_basebandSink->getMagSq(); }
|
||||||
bool getSquelchOpen() const { return m_basebandSink->getSquelchOpen(); }
|
bool getSquelchOpen() const { return m_basebandSink->getSquelchOpen(); }
|
||||||
@ -131,6 +133,7 @@ private:
|
|||||||
QThread *m_thread;
|
QThread *m_thread;
|
||||||
FreqTrackerBaseband* m_basebandSink;
|
FreqTrackerBaseband* m_basebandSink;
|
||||||
FreqTrackerSettings m_settings;
|
FreqTrackerSettings m_settings;
|
||||||
|
SpectrumVis m_spectrumVis;
|
||||||
int m_basebandSampleRate; //!< stored from device message used when starting baseband sink
|
int m_basebandSampleRate; //!< stored from device message used when starting baseband sink
|
||||||
static const int m_udpBlockSize;
|
static const int m_udpBlockSize;
|
||||||
QNetworkAccessManager *m_networkManager;
|
QNetworkAccessManager *m_networkManager;
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "freqtrackersink.h"
|
#include "freqtrackersink.h"
|
||||||
|
|
||||||
class DownChannelizer;
|
class DownChannelizer;
|
||||||
|
class SpectrumVis;
|
||||||
|
|
||||||
class FreqTrackerBaseband : public QObject
|
class FreqTrackerBaseband : public QObject
|
||||||
{
|
{
|
||||||
@ -61,6 +62,7 @@ public:
|
|||||||
void reset();
|
void reset();
|
||||||
void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
|
void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
|
||||||
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
|
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
|
||||||
|
void setSpectrumSink(SpectrumVis* spectrumSink) { m_spectrumVis = spectrumSink; m_sink.setSpectrumSink(spectrumSink); }
|
||||||
int getChannelSampleRate() const;
|
int getChannelSampleRate() const;
|
||||||
void setBasebandSampleRate(int sampleRate);
|
void setBasebandSampleRate(int sampleRate);
|
||||||
void setMessageQueueToInput(MessageQueue *messageQueue) { m_sink.setMessageQueueToInput(messageQueue); }
|
void setMessageQueueToInput(MessageQueue *messageQueue) { m_sink.setMessageQueueToInput(messageQueue); }
|
||||||
@ -80,6 +82,7 @@ private:
|
|||||||
MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
|
MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
|
||||||
FreqTrackerSettings m_settings;
|
FreqTrackerSettings m_settings;
|
||||||
unsigned int m_basebandSampleRate;
|
unsigned int m_basebandSampleRate;
|
||||||
|
SpectrumVis *m_spectrumVis;
|
||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
|
|
||||||
bool handleMessage(const Message& cmd);
|
bool handleMessage(const Message& cmd);
|
||||||
|
@ -91,6 +91,8 @@ bool FreqTrackerGUI::handleMessage(const Message& message)
|
|||||||
m_basebandSampleRate = cfg.getSampleRate();
|
m_basebandSampleRate = cfg.getSampleRate();
|
||||||
int sinkSampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim);
|
int sinkSampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim);
|
||||||
ui->channelSampleRateText->setText(tr("%1k").arg(QString::number(sinkSampleRate / 1000.0f, 'g', 5)));
|
ui->channelSampleRateText->setText(tr("%1k").arg(QString::number(sinkSampleRate / 1000.0f, 'g', 5)));
|
||||||
|
ui->glSpectrum->setSampleRate(sinkSampleRate);
|
||||||
|
m_pllChannelMarker.setBandwidth(sinkSampleRate/1000);
|
||||||
|
|
||||||
if (sinkSampleRate > 1000) {
|
if (sinkSampleRate > 1000) {
|
||||||
ui->rfBW->setMaximum(sinkSampleRate/100);
|
ui->rfBW->setMaximum(sinkSampleRate/100);
|
||||||
@ -151,6 +153,8 @@ void FreqTrackerGUI::on_log2Decim_currentIndexChanged(int index)
|
|||||||
m_settings.m_log2Decim = index < 0 ? 0 : index > 6 ? 6 : index;
|
m_settings.m_log2Decim = index < 0 ? 0 : index > 6 ? 6 : index;
|
||||||
int sinkSampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim);
|
int sinkSampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim);
|
||||||
ui->channelSampleRateText->setText(tr("%1k").arg(QString::number(sinkSampleRate / 1000.0f, 'g', 5)));
|
ui->channelSampleRateText->setText(tr("%1k").arg(QString::number(sinkSampleRate / 1000.0f, 'g', 5)));
|
||||||
|
ui->glSpectrum->setSampleRate(sinkSampleRate);
|
||||||
|
m_pllChannelMarker.setBandwidth(sinkSampleRate/1000);
|
||||||
|
|
||||||
if (sinkSampleRate > 1000) {
|
if (sinkSampleRate > 1000) {
|
||||||
ui->rfBW->setMaximum(sinkSampleRate/100);
|
ui->rfBW->setMaximum(sinkSampleRate/100);
|
||||||
@ -288,6 +292,7 @@ FreqTrackerGUI::FreqTrackerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B
|
|||||||
m_pluginAPI(pluginAPI),
|
m_pluginAPI(pluginAPI),
|
||||||
m_deviceUISet(deviceUISet),
|
m_deviceUISet(deviceUISet),
|
||||||
m_channelMarker(this),
|
m_channelMarker(this),
|
||||||
|
m_pllChannelMarker(this),
|
||||||
m_basebandSampleRate(0),
|
m_basebandSampleRate(0),
|
||||||
m_doApplySettings(true),
|
m_doApplySettings(true),
|
||||||
m_squelchOpen(false),
|
m_squelchOpen(false),
|
||||||
@ -300,6 +305,8 @@ FreqTrackerGUI::FreqTrackerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B
|
|||||||
|
|
||||||
m_freqTracker = reinterpret_cast<FreqTracker*>(rxChannel);
|
m_freqTracker = reinterpret_cast<FreqTracker*>(rxChannel);
|
||||||
m_freqTracker->setMessageQueueToGUI(getInputMessageQueue());
|
m_freqTracker->setMessageQueueToGUI(getInputMessageQueue());
|
||||||
|
m_spectrumVis = m_freqTracker->getSpectrumVis();
|
||||||
|
m_spectrumVis->setGLSpectrum(ui->glSpectrum);
|
||||||
|
|
||||||
connect(&MainCore::instance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); // 50 ms
|
connect(&MainCore::instance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); // 50 ms
|
||||||
|
|
||||||
@ -318,10 +325,23 @@ FreqTrackerGUI::FreqTrackerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B
|
|||||||
|
|
||||||
setTitleColor(m_channelMarker.getColor());
|
setTitleColor(m_channelMarker.getColor());
|
||||||
m_settings.setChannelMarker(&m_channelMarker);
|
m_settings.setChannelMarker(&m_channelMarker);
|
||||||
|
m_settings.setSpectrumGUI(ui->spectrumGUI);
|
||||||
|
|
||||||
m_deviceUISet->addChannelMarker(&m_channelMarker);
|
m_deviceUISet->addChannelMarker(&m_channelMarker);
|
||||||
m_deviceUISet->addRollupWidget(this);
|
m_deviceUISet->addRollupWidget(this);
|
||||||
|
|
||||||
|
ui->glSpectrum->setCenterFrequency(0);
|
||||||
|
m_pllChannelMarker.blockSignals(true);
|
||||||
|
m_pllChannelMarker.setColor(Qt::gray);
|
||||||
|
m_pllChannelMarker.setCenterFrequency(0);
|
||||||
|
m_pllChannelMarker.setBandwidth(35);
|
||||||
|
m_pllChannelMarker.setTitle("Tracker");
|
||||||
|
m_pllChannelMarker.setMovable(false);
|
||||||
|
m_pllChannelMarker.blockSignals(false);
|
||||||
|
m_pllChannelMarker.setVisible(true);
|
||||||
|
ui->glSpectrum->addChannelMarker(&m_pllChannelMarker);
|
||||||
|
ui->spectrumGUI->setBuddies(m_spectrumVis, ui->glSpectrum);
|
||||||
|
|
||||||
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
|
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
|
||||||
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
||||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||||
@ -445,6 +465,7 @@ void FreqTrackerGUI::tick()
|
|||||||
int freq = m_freqTracker->getAvgDeltaFreq();
|
int freq = m_freqTracker->getAvgDeltaFreq();
|
||||||
QLocale loc;
|
QLocale loc;
|
||||||
ui->trackingFrequencyText->setText(tr("%1 Hz").arg(loc.toString(freq)));
|
ui->trackingFrequencyText->setText(tr("%1 Hz").arg(loc.toString(freq)));
|
||||||
|
m_pllChannelMarker.setCenterFrequency(freq);
|
||||||
|
|
||||||
if (m_settings.m_tracking) {
|
if (m_settings.m_tracking) {
|
||||||
ui->tracking->setToolTip("Tracking on");
|
ui->tracking->setToolTip("Tracking on");
|
||||||
|
@ -28,9 +28,9 @@
|
|||||||
|
|
||||||
class PluginAPI;
|
class PluginAPI;
|
||||||
class DeviceUISet;
|
class DeviceUISet;
|
||||||
|
|
||||||
class FreqTracker;
|
class FreqTracker;
|
||||||
class BasebandSampleSink;
|
class BasebandSampleSink;
|
||||||
|
class SpectrumVis;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class FreqTrackerGUI;
|
class FreqTrackerGUI;
|
||||||
@ -57,11 +57,13 @@ private:
|
|||||||
PluginAPI* m_pluginAPI;
|
PluginAPI* m_pluginAPI;
|
||||||
DeviceUISet* m_deviceUISet;
|
DeviceUISet* m_deviceUISet;
|
||||||
ChannelMarker m_channelMarker;
|
ChannelMarker m_channelMarker;
|
||||||
|
ChannelMarker m_pllChannelMarker;
|
||||||
FreqTrackerSettings m_settings;
|
FreqTrackerSettings m_settings;
|
||||||
int m_basebandSampleRate;
|
int m_basebandSampleRate;
|
||||||
bool m_doApplySettings;
|
bool m_doApplySettings;
|
||||||
|
|
||||||
FreqTracker* m_freqTracker;
|
FreqTracker* m_freqTracker;
|
||||||
|
SpectrumVis* m_spectrumVis;
|
||||||
bool m_squelchOpen;
|
bool m_squelchOpen;
|
||||||
uint32_t m_tickCount;
|
uint32_t m_tickCount;
|
||||||
MessageQueue m_inputMessageQueue;
|
MessageQueue m_inputMessageQueue;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>360</width>
|
<width>400</width>
|
||||||
<height>327</height>
|
<height>327</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -18,16 +18,10 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>360</width>
|
<width>400</width>
|
||||||
<height>100</height>
|
<height>100</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>360</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>Liberation Sans</family>
|
<family>Liberation Sans</family>
|
||||||
@ -45,7 +39,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>358</width>
|
<width>401</width>
|
||||||
<height>140</height>
|
<height>140</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -686,7 +680,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>150</y>
|
<y>150</y>
|
||||||
<width>351</width>
|
<width>391</width>
|
||||||
<height>171</height>
|
<height>171</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
#include "freqtrackersettings.h"
|
#include "freqtrackersettings.h"
|
||||||
|
|
||||||
FreqTrackerSettings::FreqTrackerSettings() :
|
FreqTrackerSettings::FreqTrackerSettings() :
|
||||||
m_channelMarker(0)
|
m_channelMarker(0),
|
||||||
|
m_spectrumGUI(0)
|
||||||
{
|
{
|
||||||
resetToDefaults();
|
resetToDefaults();
|
||||||
}
|
}
|
||||||
@ -57,6 +58,10 @@ QByteArray FreqTrackerSettings::serialize() const
|
|||||||
s.writeS32(1, m_inputFrequencyOffset);
|
s.writeS32(1, m_inputFrequencyOffset);
|
||||||
s.writeS32(2, m_rfBandwidth/100);
|
s.writeS32(2, m_rfBandwidth/100);
|
||||||
s.writeU32(3, m_log2Decim);
|
s.writeU32(3, m_log2Decim);
|
||||||
|
|
||||||
|
if (m_spectrumGUI) {
|
||||||
|
s.writeBlob(4, m_spectrumGUI->serialize());
|
||||||
|
}
|
||||||
s.writeS32(5, m_squelch);
|
s.writeS32(5, m_squelch);
|
||||||
|
|
||||||
if (m_channelMarker) {
|
if (m_channelMarker) {
|
||||||
@ -105,7 +110,13 @@ bool FreqTrackerSettings::deserialize(const QByteArray& data)
|
|||||||
m_rfBandwidth = 100 * tmp;
|
m_rfBandwidth = 100 * tmp;
|
||||||
d.readU32(3, &utmp, 0);
|
d.readU32(3, &utmp, 0);
|
||||||
m_log2Decim = utmp > 6 ? 6 : utmp;
|
m_log2Decim = utmp > 6 ? 6 : utmp;
|
||||||
d.readS32(4, &tmp, 20);
|
|
||||||
|
if (m_spectrumGUI)
|
||||||
|
{
|
||||||
|
d.readBlob(4, &bytetmp);
|
||||||
|
m_spectrumGUI->deserialize(bytetmp);
|
||||||
|
}
|
||||||
|
|
||||||
d.readS32(5, &tmp, -40);
|
d.readS32(5, &tmp, -40);
|
||||||
m_squelch = tmp;
|
m_squelch = tmp;
|
||||||
d.readBlob(6, &bytetmp);
|
d.readBlob(6, &bytetmp);
|
||||||
|
@ -41,6 +41,7 @@ struct FreqTrackerSettings
|
|||||||
quint32 m_rgbColor;
|
quint32 m_rgbColor;
|
||||||
QString m_title;
|
QString m_title;
|
||||||
Serializable *m_channelMarker;
|
Serializable *m_channelMarker;
|
||||||
|
Serializable *m_spectrumGUI;
|
||||||
float m_alphaEMA; //!< alpha factor for delta frequency EMA
|
float m_alphaEMA; //!< alpha factor for delta frequency EMA
|
||||||
bool m_tracking;
|
bool m_tracking;
|
||||||
TrackerType m_trackerType;
|
TrackerType m_trackerType;
|
||||||
@ -58,6 +59,7 @@ struct FreqTrackerSettings
|
|||||||
FreqTrackerSettings();
|
FreqTrackerSettings();
|
||||||
void resetToDefaults();
|
void resetToDefaults();
|
||||||
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
||||||
|
void setSpectrumGUI(Serializable *spectrumGUI) { m_spectrumGUI = spectrumGUI; }
|
||||||
QByteArray serialize() const;
|
QByteArray serialize() const;
|
||||||
bool deserialize(const QByteArray& data);
|
bool deserialize(const QByteArray& data);
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "dsp/dspengine.h"
|
#include "dsp/dspengine.h"
|
||||||
#include "dsp/dspcommands.h"
|
#include "dsp/dspcommands.h"
|
||||||
#include "dsp/fftfilt.h"
|
#include "dsp/fftfilt.h"
|
||||||
|
#include "dsp/spectrumvis.h"
|
||||||
#include "util/db.h"
|
#include "util/db.h"
|
||||||
#include "util/stepfunctions.h"
|
#include "util/stepfunctions.h"
|
||||||
#include "util/messagequeue.h"
|
#include "util/messagequeue.h"
|
||||||
@ -33,6 +34,8 @@ FreqTrackerSink::FreqTrackerSink() :
|
|||||||
m_channelSampleRate(48000),
|
m_channelSampleRate(48000),
|
||||||
m_inputFrequencyOffset(0),
|
m_inputFrequencyOffset(0),
|
||||||
m_sinkSampleRate(48000),
|
m_sinkSampleRate(48000),
|
||||||
|
m_spectrumSink(nullptr),
|
||||||
|
m_sampleBufferCount(0),
|
||||||
m_squelchOpen(false),
|
m_squelchOpen(false),
|
||||||
m_squelchGate(0),
|
m_squelchGate(0),
|
||||||
m_magsqSum(0.0f),
|
m_magsqSum(0.0f),
|
||||||
@ -52,6 +55,8 @@ FreqTrackerSink::FreqTrackerSink() :
|
|||||||
m_timer = &DSPEngine::instance()->getMasterTimer();
|
m_timer = &DSPEngine::instance()->getMasterTimer();
|
||||||
#endif
|
#endif
|
||||||
m_magsq = 0.0;
|
m_magsq = 0.0;
|
||||||
|
m_sampleBufferSize = m_sinkSampleRate / 20; // 50 ms
|
||||||
|
m_sampleBuffer.resize(m_sampleBufferSize);
|
||||||
|
|
||||||
m_rrcFilter = new fftfilt(m_settings.m_rfBandwidth / m_sinkSampleRate, 2*1024);
|
m_rrcFilter = new fftfilt(m_settings.m_rfBandwidth / m_sinkSampleRate, 2*1024);
|
||||||
m_pll.computeCoefficients(0.002f, 0.5f, 10.0f); // bandwidth, damping factor, loop gain
|
m_pll.computeCoefficients(0.002f, 0.5f, 10.0f); // bandwidth, damping factor, loop gain
|
||||||
@ -102,6 +107,7 @@ void FreqTrackerSink::processOneSample(Complex &ci)
|
|||||||
{
|
{
|
||||||
fftfilt::cmplx *sideband;
|
fftfilt::cmplx *sideband;
|
||||||
int n_out;
|
int n_out;
|
||||||
|
m_sampleBuffer[m_sampleBufferCount++] = Sample(ci.real(), ci.imag());
|
||||||
|
|
||||||
if (m_settings.m_rrc)
|
if (m_settings.m_rrc)
|
||||||
{
|
{
|
||||||
@ -168,7 +174,15 @@ void FreqTrackerSink::processOneSample(Complex &ci)
|
|||||||
m_pll.feed(re, im);
|
m_pll.feed(re, im);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_spectrumSink && (m_sampleBufferCount == m_sampleBufferSize))
|
||||||
|
{
|
||||||
|
m_spectrumSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), false);
|
||||||
|
m_sampleBufferCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Real FreqTrackerSink::getFrequency() const
|
Real FreqTrackerSink::getFrequency() const
|
||||||
@ -215,6 +229,10 @@ void FreqTrackerSink::applyChannelSettings(int sinkSampleRate, int channelSample
|
|||||||
if (useInterpolator) {
|
if (useInterpolator) {
|
||||||
setInterpolator();
|
setInterpolator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_sampleBufferSize = m_sinkSampleRate / 20; // 50 ms
|
||||||
|
m_sampleBuffer.resize(m_sampleBufferSize);
|
||||||
|
m_sampleBufferCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreqTrackerSink::applySettings(const FreqTrackerSettings& settings, bool force)
|
void FreqTrackerSink::applySettings(const FreqTrackerSettings& settings, bool force)
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include "freqtrackersettings.h"
|
#include "freqtrackersettings.h"
|
||||||
|
|
||||||
|
class SpectrumVis;
|
||||||
class fftfilt;
|
class fftfilt;
|
||||||
class MessageQueue;
|
class MessageQueue;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
@ -48,6 +49,7 @@ public:
|
|||||||
|
|
||||||
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
|
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
|
||||||
|
|
||||||
|
void setSpectrumSink(SpectrumVis* spectrumSink) { m_spectrumSink = spectrumSink; }
|
||||||
void applySettings(const FreqTrackerSettings& settings, bool force = false);
|
void applySettings(const FreqTrackerSettings& settings, bool force = false);
|
||||||
void applyChannelSettings(int sinkSampleRate, int channelSampleRate, int channelFrequencyOffset, bool force = false);
|
void applyChannelSettings(int sinkSampleRate, int channelSampleRate, int channelFrequencyOffset, bool force = false);
|
||||||
void setMessageQueueToInput(MessageQueue *messageQueue) { m_messageQueueToInput = messageQueue;}
|
void setMessageQueueToInput(MessageQueue *messageQueue) { m_messageQueueToInput = messageQueue;}
|
||||||
@ -99,6 +101,11 @@ private:
|
|||||||
int m_inputFrequencyOffset;
|
int m_inputFrequencyOffset;
|
||||||
uint32_t m_sinkSampleRate;
|
uint32_t m_sinkSampleRate;
|
||||||
|
|
||||||
|
SpectrumVis* m_spectrumSink;
|
||||||
|
SampleVector m_sampleBuffer;
|
||||||
|
unsigned int m_sampleBufferCount;
|
||||||
|
unsigned int m_sampleBufferSize;
|
||||||
|
|
||||||
NCOF m_nco;
|
NCOF m_nco;
|
||||||
PhaseLockComplex m_pll;
|
PhaseLockComplex m_pll;
|
||||||
FreqLockComplex m_fll;
|
FreqLockComplex m_fll;
|
||||||
@ -138,4 +145,4 @@ private slots:
|
|||||||
void tick();
|
void tick();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDE_FREQTRACKERSINK_H
|
#endif // INCLUDE_FREQTRACKERSINK_H
|
||||||
|
@ -98,4 +98,8 @@ This is the squelch threshold in dB. The average total power received in the sig
|
|||||||
|
|
||||||
<h4>10: Squelch time gate</h4>
|
<h4>10: Squelch time gate</h4>
|
||||||
|
|
||||||
Number of milliseconds following squelch gate opening after which the signal is declared open. 0 means squelch is declared open with no delay and is suitable for burst signals. The value can be varied in steps of 10 ms from 0 to 990 ms.
|
Number of milliseconds following squelch gate opening after which the signal is declared open. 0 means squelch is declared open with no delay and is suitable for burst signals. The value can be varied in steps of 10 ms from 0 to 990 ms.
|
||||||
|
|
||||||
|
<h4>11: Channel spectrum</h4>
|
||||||
|
|
||||||
|
This is the spectrum display of the tracker channel. When the tracker is locked to the signal the center of the channel should fall almost in the middle of the signal spectrum (ideally in the middle when the tracker error is zero). Thus the locking can be followed dynamically and it can be more reliable than the lock indicator. A channel marker shows the tracker offset from the channel center frequency (tracker error). Its width is the tracker error tolerance but is hardly visible since it is 1/1000th of the channel width. Controls on the bottom of the panel are identical to the ones of the main spectrum display.
|
||||||
|
Loading…
Reference in New Issue
Block a user