23 #include <QNetworkAccessManager> 24 #include <QNetworkReply> 55 m_deviceAPI(deviceAPI),
56 m_deviceSampleRate(48000),
57 m_inputSampleRate(48000),
58 m_inputFrequencyOffset(0),
59 m_channelSampleRate(48000),
66 m_timerConnected(false),
70 m_settingsMutex(QMutex::Recursive)
74 #ifdef USE_INTERNAL_TIMER 75 #warning "Uses internal timer" 99 #ifdef USE_INTERNAL_TIMER 112 void FreqTracker::feed(
const SampleVector::const_iterator& begin,
const SampleVector::const_iterator& end,
bool firstOfBurst)
123 for (SampleVector::const_iterator it = begin; it != end; ++it)
125 Complex c(it->real(), it->imag());
167 for (
int i = 0;
i < n_out;
i++)
171 Real magsq = re*re + im*im;
230 qDebug(
"FreqTracker::start");
238 qDebug(
"FreqTracker::stop");
260 qDebug() <<
"FreqTracker::handleMessage: DSPSignalNotification:" 273 qDebug() <<
"FreqTracker::handleMessage: MsgChannelizerNotification:" 286 qDebug() <<
"FreqTracker::handleMessage: MsgConfigureFreqTracker";
300 qDebug() <<
"FreqTracker::applyChannelSettings:" 301 <<
" inputSampleRate: " << inputSampleRate
302 <<
" inputFrequencyOffset: " << inputFrequencyOffset;
323 qDebug() <<
"FreqTracker::applySettings:" 329 <<
" m_title: " << settings.
m_title 334 <<
" m_rrc: " << settings.
m_rrc 341 <<
" force: " << force;
344 QList<QString> reverseAPIKeys;
345 bool updateChannelizer =
false;
346 bool updateInterpolator =
false;
350 reverseAPIKeys.append(
"inputFrequencyOffset");
351 updateChannelizer =
true;
356 reverseAPIKeys.append(
"log2Decim");
357 updateChannelizer =
true;
362 updateInterpolator =
true;
363 reverseAPIKeys.append(
"rfBandwidth");
369 reverseAPIKeys.append(
"squelch");
373 reverseAPIKeys.append(
"rgbColor");
376 reverseAPIKeys.append(
"title");
379 reverseAPIKeys.append(
"alphaEMA");
384 reverseAPIKeys.append(
"tracking");
397 reverseAPIKeys.append(
"trackerType");
416 reverseAPIKeys.append(
"pllPskOrder");
424 reverseAPIKeys.append(
"rrc");
428 reverseAPIKeys.append(
"rrcRolloff");
429 updateInterpolator =
true;
433 reverseAPIKeys.append(
"squelchGate");
434 updateInterpolator =
true;
449 if (updateChannelizer) {
451 }
else if (updateInterpolator) {
477 qDebug() <<
"FreqTracker::configureChannelizer:" 500 connect(
m_timer, SIGNAL(timeout()),
this, SLOT(
tick()));
509 disconnect(
m_timer, SIGNAL(timeout()),
this, SLOT(
tick()));
538 QString& errorMessage)
549 const QStringList& channelSettingsKeys,
551 QString& errorMessage)
556 if (channelSettingsKeys.contains(
"inputFrequencyOffset")) {
559 if (channelSettingsKeys.contains(
"rfBandwidth")) {
562 if (channelSettingsKeys.contains(
"log2Decim")) {
565 if (channelSettingsKeys.contains(
"squelch")) {
568 if (channelSettingsKeys.contains(
"rgbColor")) {
571 if (channelSettingsKeys.contains(
"title")) {
574 if (channelSettingsKeys.contains(
"alphaEMA")) {
576 settings.
m_alphaEMA = alphaEMA < 0.01 ? 0.01 : alphaEMA > 1.0 ? 1.0 : alphaEMA;
578 if (channelSettingsKeys.contains(
"tracking")) {
581 if (channelSettingsKeys.contains(
"trackerType"))
588 if (channelSettingsKeys.contains(
"pllPskOrder")) {
591 if (channelSettingsKeys.contains(
"rrc")) {
594 if (channelSettingsKeys.contains(
"rrcRolloff")) {
597 if (channelSettingsKeys.contains(
"squelchGate")) {
600 if (channelSettingsKeys.contains(
"useReverseAPI")) {
603 if (channelSettingsKeys.contains(
"reverseAPIAddress")) {
606 if (channelSettingsKeys.contains(
"reverseAPIPort")) {
609 if (channelSettingsKeys.contains(
"reverseAPIDeviceIndex")) {
612 if (channelSettingsKeys.contains(
"reverseAPIChannelIndex")) {
619 qDebug(
"FreqTracker::webapiSettingsPutPatch: forward to GUI: %p",
m_guiMessageQueue);
633 QString& errorMessage)
678 double magsqAvg, magsqPeak;
700 if (channelSettingsKeys.contains(
"inputFrequencyOffset") || force) {
703 if (channelSettingsKeys.contains(
"rfBandwidth") || force) {
706 if (channelSettingsKeys.contains(
"rgbColor") || force) {
709 if (channelSettingsKeys.contains(
"squelch") || force) {
712 if (channelSettingsKeys.contains(
"title") || force) {
715 if (channelSettingsKeys.contains(
"trackerType") || force) {
719 QString channelSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
725 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
727 QBuffer *buffer=
new QBuffer();
728 buffer->open((QBuffer::ReadWrite));
729 buffer->write(swgChannelSettings->
asJson().toUtf8());
735 delete swgChannelSettings;
740 QNetworkReply::NetworkError replyError = reply->error();
744 qWarning() <<
"FreqTracker::networkManagerFinished:" 745 <<
" error(" << (int) replyError
746 <<
"): " << replyError
747 <<
": " << reply->errorString();
751 QString answer = reply->readAll();
753 qDebug(
"FreqTracker::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
void setTracking(qint32 tracking)
void setOriginatorChannelIndex(qint32 originator_channel_index)
void applySettings(const FreqTrackerSettings &settings, bool force=false)
bool decimate(Real *distance, const Complex &next, Complex *result)
void configure(MessageQueue *messageQueue, int sampleRate, int centerFrequency)
void setAlphaEma(float alpha_ema)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
qint32 getReverseApiPort()
FreqTracker(DeviceAPI *deviceAPI)
void removeChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
static double dbPower(double magsq, double floor=1e-12)
void addChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
void setFreqTrackerReport(SWGFreqTrackerReport *freq_tracker_report)
void setSquelch(qint32 squelch)
void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase=4.5)
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
bool interpolate(Real *distance, const Complex &next, Complex *result)
void setUseReverseApi(qint32 use_reverse_api)
uint16_t m_reverseAPIDeviceIndex
void setReverseApiChannelIndex(qint32 reverse_api_channel_index)
int getDeviceSetIndex() const
ThreadedBasebandSampleSink * m_threadedChannelizer
qint32 getReverseApiChannelIndex()
SWGFreqTrackerReport * getFreqTrackerReport()
int m_squelchGate
in 10s of ms
int runFilt(const cmplx &in, cmplx **out)
int getSampleRate() const
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings &response, const FreqTrackerSettings &settings)
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport &response)
void setRgbColor(qint32 rgb_color)
SWGFreqTrackerSettings * getFreqTrackerSettings()
static MsgSampleRateNotification * create(int sampleRate, int frequencyOffset)
void setReverseApiPort(qint32 reverse_api_port)
void setChannelType(QString *channel_type)
void setOriginatorDeviceSetIndex(qint32 originator_device_set_index)
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
uint32_t m_deviceSampleRate
std::complex< float > cmplx
Complex nextIQ()
Return next complex sample.
void getMagSqLevels(double &avg, double &peak, int &nbSamples)
QString m_reverseAPIAddress
uint32_t m_squelchGate
Squelch gate in samples.
static const QString m_channelIdURI
qint64 getCenterFrequency() const
qint32 m_inputFrequencyOffset
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
MovingAverageUtil< Real, double, 16 > m_movingAverage
void setRrcRolloff(qint32 rrc_rolloff)
virtual void feed(const SampleVector::const_iterator &begin, const SampleVector::const_iterator &end, bool po)
Real m_interpolatorDistance
qint32 getUseReverseApi()
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
static const QString m_channelId
SWGAMDemodSettings * getAmDemodSettings()
static DSPEngine * instance()
QByteArray serialize() const
void setSquelchGate(qint32 squelch_gate)
void setSampleRate(qint32 sample_rate)
TrackerType m_trackerType
bool getSquelchOpen() const
uint16_t m_reverseAPIPort
static bool match(const Message *message)
void processOneSample(Complex &ci)
int m_inputFrequencyOffset
void removeChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Remove a channel sink (Rx)
void setDirection(qint32 direction)
virtual QByteArray serialize() const
virtual QString asJson() override
virtual bool handleMessage(const Message &cmd)
Processing of a message. Returns true if message has actually been processed.
uint16_t m_reverseAPIChannelIndex
qint64 getInputFrequencyOffset()
Interpolator m_interpolator
FreqTrackerSettings m_settings
static const int m_udpBlockSize
virtual bool deserialize(const QByteArray &data)
void addChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Add a channel sink (Rx)
void create_rrc_filter(float fb, float a)
root raised cosine. fb is half the band pass
qint32 getReverseApiDeviceIndex()
void setFreqTrackerSettings(SWGFreqTrackerSettings *freq_tracker_settings)
void setTitle(QString *title)
int getSampleRate() const
uint32_t m_rrcRolloff
in 100ths
void networkManagerFinished(QNetworkReply *reply)
void setFreq(Real freq, Real sampleRate)
void feed(float re, float im)
virtual int webapiSettingsGet(SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
void setReverseApiAddress(QString *reverse_api_address)
void webapiReverseSendSettings(QList< QString > &channelSettingsKeys, const FreqTrackerSettings &settings, bool force)
Real m_interpolatorDistanceRemain
bool deserialize(const QByteArray &data)
void setChannelPowerDb(float channel_power_db)
void setRfBandwidth(float rf_bandwidth)
void configureChannelizer()
void computeCoefficients(Real wn, Real zeta, Real K)
uint32_t m_channelSampleRate
void setPskOrder(unsigned int order)
int getIndexInDeviceSet() const
void setPllPskOrder(qint32 pll_psk_order)
Real getFrequency() const
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
std::complex< Real > Complex
DownChannelizer * m_channelizer
void setTrackerType(qint32 tracker_type)
qint64 getFrequencyOffset() const
QString * getReverseApiAddress()
void setSampleRate(unsigned int sampleRate)
QNetworkAccessManager * m_networkManager
static double powerFromdB(double powerdB)
void feed(float re, float im)
float m_alphaEMA
alpha factor for delta frequency EMA
QNetworkRequest m_networkRequest
void setSquelch(float squelch)
const QTimer & getMasterTimer() const
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force=false)
QString * getReverseApiAddress()
void setChannelSampleRate(qint32 channel_sample_rate)
virtual int webapiSettingsPutPatch(bool force, const QStringList &channelSettingsKeys, SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
void setSampleRate(unsigned int sampleRate)
void setLog2Decim(qint32 log2_decim)
virtual int webapiReportGet(SWGSDRangel::SWGChannelReport &response, QString &errorMessage)
void setInputFrequencyOffset(qint64 input_frequency_offset)