SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
freqtrackergui.cpp
Go to the documentation of this file.
1 // Copyright (C) 2019 Edouard Griffiths, F4EXB //
3 // //
4 // This program is free software; you can redistribute it and/or modify //
5 // it under the terms of the GNU General Public License as published by //
6 // the Free Software Foundation as version 3 of the License, or //
7 // (at your option) any later version. //
8 // //
9 // This program is distributed in the hope that it will be useful, //
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
12 // GNU General Public License V3 for more details. //
13 // //
14 // You should have received a copy of the GNU General Public License //
15 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
17 
18 #include <QDockWidget>
19 #include <QMainWindow>
20 #include <QDebug>
21 
22 #include "freqtrackergui.h"
23 
24 #include "device/deviceuiset.h"
25 #include "dsp/downchannelizer.h"
26 #include "dsp/dspengine.h"
28 #include "ui_freqtrackergui.h"
29 #include "plugin/pluginapi.h"
30 #include "util/simpleserializer.h"
31 #include "util/db.h"
33 #include "dsp/dspengine.h"
34 #include "mainwindow.h"
35 #include "gui/crightclickenabler.h"
36 #include "gui/audioselectdialog.h"
37 
38 #include "freqtracker.h"
39 
41 {
42  FreqTrackerGUI* gui = new FreqTrackerGUI(pluginAPI, deviceUISet, rxChannel);
43  return gui;
44 }
45 
47 {
48  delete this;
49 }
50 
51 void FreqTrackerGUI::setName(const QString& name)
52 {
53  setObjectName(name);
54 }
55 
56 QString FreqTrackerGUI::getName() const
57 {
58  return objectName();
59 }
60 
63 }
64 
65 void FreqTrackerGUI::setCenterFrequency(qint64 centerFrequency)
66 {
67  m_channelMarker.setCenterFrequency(centerFrequency);
68  applySettings();
69 }
70 
72 {
75  applySettings(true);
76 }
77 
78 QByteArray FreqTrackerGUI::serialize() const
79 {
80  return m_settings.serialize();
81 }
82 
83 bool FreqTrackerGUI::deserialize(const QByteArray& data)
84 {
85  if(m_settings.deserialize(data)) {
87  applySettings(true);
88  return true;
89  } else {
91  return false;
92  }
93 }
94 
96 {
98  {
99  qDebug("FreqTrackerGUI::handleMessage: FreqTracker::MsgConfigureFreqTracker");
101  m_settings = cfg.getSettings();
102  blockApplySettings(true);
103  displaySettings();
104  blockApplySettings(false);
105  return true;
106  }
108  {
109  if (!m_settings.m_tracking) {
110  qDebug("FreqTrackerGUI::handleMessage: FreqTracker::MsgSampleRateNotification");
111  }
114  ui->channelSampleRateText->setText(tr("%1k").arg(QString::number(m_channelSampleRate / 1000.0f, 'g', 5)));
115  blockApplySettings(true);
117  ui->deltaFrequency->setValue(m_settings.m_inputFrequencyOffset);
119  blockApplySettings(false);
120 
121  if (m_channelSampleRate > 1000) {
122  ui->rfBW->setMaximum(m_channelSampleRate/100);
123  }
124 
125  return true;
126  }
127 
128  return false;
129 }
130 
132 {
133  Message* message;
134 
135  while ((message = getInputMessageQueue()->pop()) != 0)
136  {
137  if (handleMessage(*message))
138  {
139  delete message;
140  }
141  }
142 }
143 
145 {
146  ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
148  applySettings();
149 }
150 
152 {
154 }
155 
157 {
160  applySettings();
161 }
162 
164 {
165  m_settings.m_log2Decim = index < 0 ? 0 : index > 6 ? 6 : index;
166  applySettings();
167 }
168 
170 {
171  ui->rfBWText->setText(QString("%1 kHz").arg(value / 10.0, 0, 'f', 1));
172  m_channelMarker.setBandwidth(value * 100);
173  m_settings.m_rfBandwidth = value * 100;
174  applySettings();
175 }
176 
178 {
179  if (!checked)
180  {
181  ui->tracking->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
182  ui->tracking->setToolTip(tr("PLL for synchronous AM"));
183  }
184 
185  m_settings.m_tracking = checked;
186  applySettings();
187 }
188 
190 {
191  m_settings.m_alphaEMA = value / 100.0;
192  QString alphaEMAStr = QString::number(m_settings.m_alphaEMA, 'f', 2);
193  ui->alphaEMAText->setText(alphaEMAStr);
194  applySettings();
195 }
196 
198 {
200  applySettings();
201 }
202 
204 {
205  if ((index < 0) || (index > 5)) {
206  return;
207  }
208 
209  m_settings.m_pllPskOrder = 1<<index;
210  applySettings();
211 }
212 
214 {
215  m_settings.m_rrc = checked;
216  applySettings();
217 }
218 
220 {
221  m_settings.m_rrcRolloff = value < 0 ? 0 : value > 100 ? 100 : value;
222  QString rolloffStr = QString::number(value/100.0, 'f', 2);
223  ui->rrcRolloffText->setText(rolloffStr);
224  applySettings();
225 }
226 
228 {
229  ui->squelchText->setText(QString("%1 dB").arg(value));
230  m_settings.m_squelch = value;
231  applySettings();
232 }
233 
235 {
236  ui->squelchGateText->setText(QString("%1").arg(value * 10.0f, 0, 'f', 0));
237  m_settings.m_squelchGate = value;
238  applySettings();
239 }
240 
241 void FreqTrackerGUI::onWidgetRolled(QWidget* widget, bool rollDown)
242 {
243  (void) widget;
244  (void) rollDown;
245 }
246 
248 {
250  {
257  dialog.move(p);
258  dialog.exec();
259 
268 
269  setWindowTitle(m_settings.m_title);
271 
272  applySettings();
273  }
274 
276 }
277 
278 FreqTrackerGUI::FreqTrackerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) :
279  RollupWidget(parent),
280  ui(new Ui::FreqTrackerGUI),
281  m_pluginAPI(pluginAPI),
282  m_deviceUISet(deviceUISet),
283  m_channelMarker(this),
285  m_doApplySettings(true),
286  m_squelchOpen(false),
287  m_tickCount(0)
288 {
289  ui->setupUi(this);
290  setAttribute(Qt::WA_DeleteOnClose, true);
291  connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
292  connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
293 
294  m_freqTracker = reinterpret_cast<FreqTracker*>(rxChannel); //new FreqTracker(m_deviceUISet->m_deviceSourceAPI);
296 
297  connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); // 50 ms
298 
299  ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
300  ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
301  ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
302  ui->channelPowerMeter->setColorTheme(LevelMeterSignalDB::ColorGreenAndBlue);
303 
304  m_channelMarker.blockSignals(true);
305  m_channelMarker.setColor(Qt::yellow);
308  m_channelMarker.setTitle("AM Demodulator");
309  m_channelMarker.blockSignals(false);
310  m_channelMarker.setVisible(true); // activate signal on the last setting only
311 
314 
318 
319  connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
320  connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
321  connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
322 
323  displaySettings();
324  applySettings(true);
325 }
326 
328 {
330  delete m_freqTracker; // TODO: check this: when the GUI closes it has to delete the demodulator
331  delete ui;
332 }
333 
335 {
336  m_doApplySettings = !block;
337 }
338 
340 {
341  if (m_doApplySettings)
342  {
345  }
346 }
347 
349 {
350  m_channelMarker.blockSignals(true);
354  m_channelMarker.blockSignals(false);
355  m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
356 
358  setWindowTitle(m_channelMarker.getTitle());
359 
360  blockApplySettings(true);
361 
362  ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
363  ui->log2Decim->setCurrentIndex(m_settings.m_log2Decim);
364  int displayValue = m_settings.m_rfBandwidth/100.0;
365  ui->rfBW->setValue(displayValue);
366  ui->rfBWText->setText(QString("%1 kHz").arg(displayValue / 10.0, 0, 'f', 1));
367  ui->squelch->setValue(m_settings.m_squelch);
368  ui->squelchText->setText(QString("%1 dB").arg(m_settings.m_squelch));
369  ui->tracking->setChecked(m_settings.m_tracking);
370  ui->trackerType->setCurrentIndex((int) m_settings.m_trackerType);
371  QString alphaEMAStr = QString::number(m_settings.m_alphaEMA, 'f', 2);
372  ui->alphaEMAText->setText(alphaEMAStr);
373  ui->alphaEMA->setValue(m_settings.m_alphaEMA*100.0);
374 
375  int i = 0;
376  for(; ((m_settings.m_pllPskOrder>>i) & 1) == 0; i++);
377  ui->pllPskOrder->setCurrentIndex(i);
378 
379  ui->rrc->setChecked(m_settings.m_rrc);
380  ui->rrcRolloff->setValue(m_settings.m_rrcRolloff);
381  QString rolloffStr = QString::number(m_settings.m_rrcRolloff/100.0, 'f', 2);
382  ui->rrcRolloffText->setText(rolloffStr);
383  ui->squelchGateText->setText(QString("%1").arg(m_settings.m_squelchGate * 10.0f, 0, 'f', 0));
384  ui->squelchGate->setValue(m_settings.m_squelchGate);
385 
386  blockApplySettings(false);
387 }
388 
390 {
392 }
393 
395 {
397 }
398 
400 {
401  double magsqAvg, magsqPeak;
402  int nbMagsqSamples;
403  m_freqTracker->getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples);
404  double powDbAvg = CalcDb::dbPower(magsqAvg);
405  double powDbPeak = CalcDb::dbPower(magsqPeak);
406 
407  ui->channelPowerMeter->levelChanged(
408  (100.0f + powDbAvg) / 100.0f,
409  (100.0f + powDbPeak) / 100.0f,
410  nbMagsqSamples);
411 
412  if (m_tickCount % 4 == 0) {
413  ui->channelPower->setText(QString::number(powDbAvg, 'f', 1));
414  }
415 
416  bool squelchOpen = m_freqTracker->getSquelchOpen();
417 
418  if (squelchOpen) {
419  ui->squelchLabel->setStyleSheet("QLabel { background-color : green; }");
420  } else {
421  ui->squelchLabel->setStyleSheet("QLabel { background:rgb(50,50,50); }");
422  }
423 
424  if (m_freqTracker->getPllLocked()) {
425  ui->tracking->setStyleSheet("QToolButton { background-color : green; }");
426  } else {
427  ui->tracking->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
428  }
429 
430  int freq = m_freqTracker->getAvgDeltaFreq();
431  QLocale loc;
432  ui->trackingFrequencyText->setText(tr("%1 Hz").arg(loc.toString(freq)));
433 
434  if (m_settings.m_tracking) {
435  ui->tracking->setToolTip("Tracking on");
436  } else {
437  ui->tracking->setToolTip("Tracking off");
438  }
439 
440  m_tickCount++;
441 }
442 
static MainWindow * getInstance()
Definition: mainwindow.h:73
const QString & getReverseAPIAddress() const
int getCenterFrequency() const
Definition: channelmarker.h:42
void enterEvent(QEvent *)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void setChannelMarker(Serializable *channelMarker)
static double dbPower(double magsq, double floor=1e-12)
Definition: db.cpp:22
void on_tracking_toggled(bool checked)
void on_pllPskOrder_currentIndexChanged(int index)
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
int m_squelchGate
in 10s of ms
void onWidgetRolled(QWidget *widget, bool rollDown)
Ui::FreqTrackerGUI * ui
void channelMarkerChangedByCursor()
void on_trackerType_currentIndexChanged(int index)
FreqTrackerSettings m_settings
void setReverseAPIChannelIndex(uint16_t channelIndex)
void resetContextMenuType()
Definition: rollupwidget.h:50
void addChannelMarker(ChannelMarker *channelMarker)
Add channel marker to spectrum.
Definition: deviceuiset.cpp:72
void on_rrc_toggled(bool checked)
ContextMenuType m_contextMenuType
Definition: rollupwidget.h:33
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
void setReverseAPIDeviceIndex(uint16_t deviceIndex)
QByteArray serialize() const
void getMagSqLevels(double &avg, double &peak, int &nbSamples)
Definition: freqtracker.h:167
void onMenuDialogCalled(const QPoint &p)
bool getPllLocked() const
Definition: freqtracker.h:163
DeviceUISet * m_deviceUISet
static const QString m_channelIdURI
Definition: freqtracker.h:185
FreqTracker * m_freqTracker
virtual void setMessageQueueToGUI(MessageQueue *queue)
virtual MessageQueue * getInputMessageQueue()
uint32_t m_tickCount
void on_deltaFrequency_changed(qint64 value)
void setTitleColor(const QColor &c)
QByteArray serialize() const
virtual void setCenterFrequency(qint64 centerFrequency)
void setHighlighted(bool highlighted)
FreqTrackerGUI(PluginAPI *pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget *parent=0)
void registerRxChannelInstance(const QString &channelName, PluginInstanceGUI *pluginGUI)
Definition: deviceuiset.cpp:82
int32_t i
Definition: decimators.h:244
void addRollupWidget(QWidget *widget)
Add rollup widget to channel window.
Definition: deviceuiset.cpp:77
bool getSquelchOpen() const
Definition: freqtracker.h:162
void removeRxChannelInstance(PluginInstanceGUI *pluginGUI)
Definition: deviceuiset.cpp:94
virtual ~FreqTrackerGUI()
const QString & getTitle() const
Definition: channelmarker.h:38
PluginAPI * m_pluginAPI
static bool match(const Message *message)
Definition: message.cpp:45
bool getHighlighted() const
Definition: channelmarker.h:61
QString getName() const
bool deserialize(const QByteArray &data)
void on_log2Decim_currentIndexChanged(int index)
void handleInputMessages()
void blockApplySettings(bool block)
void setReverseAPIAddress(const QString &address)
const FreqTrackerSettings & getSettings() const
Definition: freqtracker.h:56
void setHighlighted(bool highlighted)
void setColor(const QColor &color)
static FreqTrackerGUI * create(PluginAPI *pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
ChannelMarker m_channelMarker
void on_rrcRolloff_valueChanged(int value)
uint32_t m_rrcRolloff
in 100ths
void setVisible(bool visible)
void setBandwidth(int bandwidth)
void on_alphaEMA_valueChanged(int value)
const QColor & getColor() const
Definition: channelmarker.h:64
void setTitle(const QString &title)
void on_squelchGate_valueChanged(int value)
bool deserialize(const QByteArray &data)
virtual void destroy()
void setName(const QString &name)
void setCenterFrequency(int centerFrequency)
virtual qint64 getCenterFrequency() const
void leaveEvent(QEvent *)
static MsgConfigureFreqTracker * create(const FreqTrackerSettings &settings, bool force)
Definition: freqtracker.h:59
void widgetRolled(QWidget *widget, bool rollDown)
Real getAvgDeltaFreq() const
Definition: freqtracker.h:165
void on_squelch_valueChanged(int value)
void on_rfBW_valueChanged(int value)
void setUseReverseAPI(bool useReverseAPI)
float m_alphaEMA
alpha factor for delta frequency EMA
virtual bool handleMessage(const Message &message)
void channelMarkerHighlightedByCursor()
void applySettings(bool force=false)