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.
nfmdemodgui.cpp
Go to the documentation of this file.
1 #include "nfmdemodgui.h"
2 
3 #include "device/deviceuiset.h"
4 #include <QDockWidget>
5 #include <QMainWindow>
6 #include <QDebug>
7 
8 #include "ui_nfmdemodgui.h"
9 #include "plugin/pluginapi.h"
10 #include "util/simpleserializer.h"
11 #include "util/db.h"
13 #include "gui/crightclickenabler.h"
14 #include "gui/audioselectdialog.h"
15 #include "dsp/dspengine.h"
16 #include "mainwindow.h"
17 #include "nfmdemod.h"
18 
20 {
21  NFMDemodGUI* gui = new NFMDemodGUI(pluginAPI, deviceUISet, rxChannel);
22  return gui;
23 }
24 
26 {
27  delete this;
28 }
29 
30 void NFMDemodGUI::setName(const QString& name)
31 {
32  setObjectName(name);
33 }
34 
35 QString NFMDemodGUI::getName() const
36 {
37  return objectName();
38 }
39 
41 {
43 }
44 
45 void NFMDemodGUI::setCenterFrequency(qint64 centerFrequency)
46 {
47  m_channelMarker.setCenterFrequency(centerFrequency);
48  applySettings();
49 }
50 
52 {
55  applySettings();
56 }
57 
58 QByteArray NFMDemodGUI::serialize() const
59 {
60  return m_settings.serialize();
61 }
62 
63 bool NFMDemodGUI::deserialize(const QByteArray& data)
64 {
65  if(m_settings.deserialize(data)) {
67  applySettings(true);
68  return true;
69  } else {
71  return false;
72  }
73 }
74 
75 bool NFMDemodGUI::handleMessage(const Message& message)
76 {
78  {
79  //qDebug("NFMDemodGUI::handleMessage: NFMDemod::MsgReportCTCSSFreq");
81  setCtcssFreq(report.getFrequency());
82  //qDebug("NFMDemodGUI::handleMessage: MsgReportCTCSSFreq: %f", report.getFrequency());
83  return true;
84  }
85  else if (NFMDemod::MsgConfigureNFMDemod::match(message))
86  {
87  qDebug("NFMDemodGUI::handleMessage: NFMDemod::MsgConfigureNFMDemod");
89  m_settings = cfg.getSettings();
90  blockApplySettings(true);
92  blockApplySettings(false);
93  return true;
94  }
95 
96  return false;
97 }
98 
100 {
101  Message* message;
102 
103  while ((message = getInputMessageQueue()->pop()) != 0)
104  {
105  if (handleMessage(*message))
106  {
107  delete message;
108  }
109  }
110 }
111 
113 {
114  ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
116  applySettings();
117 }
118 
120 {
122 }
123 
125 {
128  applySettings();
129 }
130 
132 {
133  qDebug() << "NFMDemodGUI::on_rfBW_currentIndexChanged" << index;
134  //ui->rfBWText->setText(QString("%1 k").arg(m_rfBW[value] / 1000.0));
138  applySettings();
139 }
140 
142 {
143  ui->afBWText->setText(QString("%1 k").arg(value));
144  m_settings.m_afBandwidth = value * 1000.0;
145  applySettings();
146 }
147 
149 {
150  ui->volumeText->setText(QString("%1").arg(value / 10.0, 0, 'f', 1));
151  m_settings.m_volume = value / 10.0;
152  applySettings();
153 }
154 
156 {
157  ui->squelchGateText->setText(QString("%1").arg(value * 10.0f, 0, 'f', 0));
158  m_settings.m_squelchGate = value;
159  applySettings();
160 }
161 
163 {
164  if (checked)
165  {
166  ui->squelchText->setText(QString("%1").arg((-ui->squelch->value()) / 1.0, 0, 'f', 0));
167  ui->squelchText->setToolTip(tr("Squelch AF balance threshold (%)"));
168  ui->squelch->setToolTip(tr("Squelch AF balance threshold (%)"));
169  }
170  else
171  {
172  ui->squelchText->setText(QString("%1").arg(ui->squelch->value() / 1.0, 0, 'f', 0));
173  ui->squelchText->setToolTip(tr("Squelch power threshold (dB)"));
174  ui->squelch->setToolTip(tr("Squelch power threshold (dB)"));
175  }
176  m_settings.m_deltaSquelch = checked;
177  applySettings();
178 }
179 
181 {
182  if (ui->deltaSquelch->isChecked())
183  {
184  ui->squelchText->setText(QString("%1").arg(-value / 1.0, 0, 'f', 0));
185  ui->squelchText->setToolTip(tr("Squelch AF balance threshold (%)"));
186  ui->squelch->setToolTip(tr("Squelch AF balance threshold (%)"));
187  }
188  else
189  {
190  ui->squelchText->setText(QString("%1").arg(value / 1.0, 0, 'f', 0));
191  ui->squelchText->setToolTip(tr("Squelch power threshold (dB)"));
192  ui->squelch->setToolTip(tr("Squelch power threshold (dB)"));
193  }
194  m_settings.m_squelch = value * 1.0;
195  applySettings();
196 }
197 
199 {
200  m_settings.m_ctcssOn = checked;
201  applySettings();
202 }
203 
205 {
206  m_settings.m_highPass = checked;
207  applySettings();
208 }
209 
211 {
212  m_settings.m_audioMute = checked;
213  applySettings();
214 }
215 
217 {
218  m_settings.m_ctcssIndex = index;
219  applySettings();
220 }
221 
222 void NFMDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown)
223 {
224  (void) widget;
225  (void) rollDown;
226  /*
227  if((widget == ui->spectrumContainer) && (m_nfmDemod != NULL))
228  m_nfmDemod->setSpectrum(m_threadedSampleSink->getMessageQueue(), rollDown);
229  */
230 }
231 
232 void NFMDemodGUI::onMenuDialogCalled(const QPoint &p)
233 {
235  {
242  dialog.move(p);
243  dialog.exec();
244 
253 
254  setWindowTitle(m_settings.m_title);
256 
257  applySettings();
258  }
259 
261 }
262 
263 NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) :
264  RollupWidget(parent),
265  ui(new Ui::NFMDemodGUI),
266  m_pluginAPI(pluginAPI),
267  m_deviceUISet(deviceUISet),
268  m_channelMarker(this),
269  m_basicSettingsShown(false),
270  m_doApplySettings(true),
271  m_squelchOpen(false),
272  m_tickCount(0)
273 {
274  ui->setupUi(this);
275  setAttribute(Qt::WA_DeleteOnClose, true);
276 
277  connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
278  connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
279 
280  m_nfmDemod = reinterpret_cast<NFMDemod*>(rxChannel); //new NFMDemod(m_deviceUISet->m_deviceSourceAPI);
282 
283  connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
284 
285  CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute);
286  connect(audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect()));
287 
288  blockApplySettings(true);
289 
290  ui->rfBW->clear();
291 
292  for (int i = 0; i < NFMDemodSettings::m_nbRfBW; i++) {
293  ui->rfBW->addItem(QString("%1").arg(NFMDemodSettings::getRFBW(i) / 1000.0, 0, 'f', 2));
294  }
295 
296  int ctcss_nbTones;
297  const Real *ctcss_tones = m_nfmDemod->getCtcssToneSet(ctcss_nbTones);
298 
299  ui->ctcss->addItem("--");
300 
301  for (int i=0; i<ctcss_nbTones; i++)
302  {
303  ui->ctcss->addItem(QString("%1").arg(ctcss_tones[i]));
304  }
305 
306  blockApplySettings(false);
307 
308  ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); // squelch closed
309 
310  ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
311  ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
312  ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
313  ui->channelPowerMeter->setColorTheme(LevelMeterSignalDB::ColorGreenAndBlue);
314 
315  m_channelMarker.blockSignals(true);
316  m_channelMarker.setColor(Qt::red);
319  m_channelMarker.setTitle("NFM Demodulator");
320  m_channelMarker.blockSignals(false);
321  m_channelMarker.setVisible(true); // activate signal on the last setting only
322 
324 
328 
329  connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
330  connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
331 
332  QChar delta = QChar(0x94, 0x03);
333  ui->deltaSquelch->setText(delta);
334 
335  connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
336 
337  displaySettings();
338  applySettings(true);
339 }
340 
342 {
344  delete m_nfmDemod; // TODO: check this: when the GUI closes it has to delete the demodulator
345  delete ui;
346 }
347 
349 {
350  if (m_doApplySettings)
351  {
352  qDebug() << "NFMDemodGUI::applySettings";
353 
356  m_nfmDemod->getInputMessageQueue()->push(channelConfigMsg);
357 
359  m_nfmDemod->getInputMessageQueue()->push(message);
360  }
361 }
362 
364 {
365  m_channelMarker.blockSignals(true);
369  m_channelMarker.blockSignals(false);
371 
373  setWindowTitle(m_channelMarker.getTitle());
374 
375  blockApplySettings(true);
376 
377  ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
378 
380 
381  ui->afBWText->setText(QString("%1 k").arg(m_settings.m_afBandwidth / 1000.0));
382  ui->afBW->setValue(m_settings.m_afBandwidth / 1000.0);
383 
384  ui->volumeText->setText(QString("%1").arg(m_settings.m_volume, 0, 'f', 1));
385  ui->volume->setValue(m_settings.m_volume * 10.0);
386 
387  ui->squelchGateText->setText(QString("%1").arg(m_settings.m_squelchGate * 10.0f, 0, 'f', 0));
388  ui->squelchGate->setValue(m_settings.m_squelchGate);
389 
390  ui->deltaSquelch->setChecked(m_settings.m_deltaSquelch);
391  ui->squelch->setValue(m_settings.m_squelch * 1.0);
392 
394  {
395  ui->squelchText->setText(QString("%1").arg((-m_settings.m_squelch) / 1.0, 0, 'f', 0));
396  ui->squelchText->setToolTip(tr("Squelch AF balance threshold (%)"));
397  ui->squelch->setToolTip(tr("Squelch AF balance threshold (%)"));
398  }
399  else
400  {
401  ui->squelchText->setText(QString("%1").arg(m_settings.m_squelch / 1.0, 0, 'f', 0));
402  ui->squelchText->setToolTip(tr("Squelch power threshold (dB)"));
403  ui->squelch->setToolTip(tr("Squelch power threshold (dB)"));
404  }
405 
406  ui->ctcssOn->setChecked(m_settings.m_ctcssOn);
407  ui->highPassFilter->setChecked(m_settings.m_highPass);
408  ui->audioMute->setChecked(m_settings.m_audioMute);
409 
410  ui->ctcss->setCurrentIndex(m_settings.m_ctcssIndex);
411 
412  blockApplySettings(false);
413 }
414 
416 {
418 }
419 
421 {
423 }
424 
426 {
427  if (ctcssFreq == 0)
428  {
429  ui->ctcssText->setText("--");
430  }
431  else
432  {
433  ui->ctcssText->setText(QString("%1").arg(ctcssFreq));
434  }
435 }
436 
438 {
439  m_doApplySettings = !block;
440 }
441 
443 {
444  qDebug("NFMDemodGUI::audioSelect");
446  audioSelect.exec();
447 
448  if (audioSelect.m_selected)
449  {
451  applySettings();
452  }
453 }
454 
456 {
457  double magsqAvg, magsqPeak;
458  int nbMagsqSamples;
459  m_nfmDemod->getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples);
460  double powDbAvg = CalcDb::dbPower(magsqAvg);
461  double powDbPeak = CalcDb::dbPower(magsqPeak);
462 
463  ui->channelPowerMeter->levelChanged(
464  (100.0f + powDbAvg) / 100.0f,
465  (100.0f + powDbPeak) / 100.0f,
466  nbMagsqSamples);
467 
468  if (m_tickCount % 4 == 0) {
469  ui->channelPower->setText(tr("%1 dB").arg(powDbAvg, 0, 'f', 1));
470  }
471 
472  bool squelchOpen = m_nfmDemod->getSquelchOpen();
473 
474  if (squelchOpen != m_squelchOpen)
475  {
476  if (squelchOpen) {
477  ui->audioMute->setStyleSheet("QToolButton { background-color : green; }");
478  } else {
479  ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
480  }
481 
482  m_squelchOpen = squelchOpen;
483  }
484 
485  m_tickCount++;
486 }
static MainWindow * getInstance()
Definition: mainwindow.h:73
const QString & getReverseAPIAddress() const
uint16_t m_reverseAPIPort
void setCtcssFreq(Real ctcssFreq)
bool deserialize(const QByteArray &data)
void getMagSqLevels(double &avg, double &peak, int &nbSamples)
Definition: nfmdemod.h:171
int getCenterFrequency() const
Definition: channelmarker.h:42
void on_highPassFilter_toggled(bool checked)
static int getFMDev(int index)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
const Real * getCtcssToneSet(int &nbTones) const
Definition: nfmdemod.h:159
void onMenuDialogCalled(const QPoint &p)
static double dbPower(double magsq, double floor=1e-12)
Definition: db.cpp:22
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
void blockApplySettings(bool block)
bool getSquelchOpen() const
Definition: nfmdemod.h:169
static MsgConfigureChannelizer * create(int sampleRate, int centerFrequency)
Definition: nfmdemod.h:83
static int getRFBW(int index)
void displaySettings()
QString getName() const
Definition: nfmdemodgui.cpp:35
void setChannelMarker(Serializable *channelMarker)
static MsgConfigureNFMDemod * create(const NFMDemodSettings &settings, bool force)
Definition: nfmdemod.h:60
void on_deltaFrequency_changed(qint64 value)
void resetToDefaults()
Definition: nfmdemodgui.cpp:51
void setReverseAPIChannelIndex(uint16_t channelIndex)
void resetContextMenuType()
Definition: rollupwidget.h:50
void addChannelMarker(ChannelMarker *channelMarker)
Add channel marker to spectrum.
Definition: deviceuiset.cpp:72
Real m_squelch
deci-Bels
DeviceUISet * m_deviceUISet
Definition: nfmdemodgui.h:48
void audioSelect()
static int getRFBWIndex(int rfbw)
void setName(const QString &name)
Definition: nfmdemodgui.cpp:30
virtual MessageQueue * getInputMessageQueue()
Definition: nfmdemodgui.h:37
void leaveEvent(QEvent *)
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)
NFMDemodGUI(PluginAPI *pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget *parent=0)
Ui::NFMDemodGUI * ui
Definition: nfmdemodgui.h:46
QString m_reverseAPIAddress
virtual ~NFMDemodGUI()
void on_ctcssOn_toggled(bool checked)
static const QString m_channelIdURI
Definition: nfmdemod.h:189
QByteArray serialize() const
void on_deltaSquelch_toggled(bool checked)
virtual void setMessageQueueToGUI(MessageQueue *queue)
static DSPEngine * instance()
Definition: dspengine.cpp:51
uint32_t m_tickCount
Definition: nfmdemodgui.h:56
PluginAPI * m_pluginAPI
Definition: nfmdemodgui.h:47
void on_volume_valueChanged(int value)
void setTitleColor(const QColor &c)
void on_squelch_valueChanged(int value)
void setHighlighted(bool highlighted)
void channelMarkerHighlightedByCursor()
uint16_t m_reverseAPIChannelIndex
void channelMarkerChangedByCursor()
ChannelMarker m_channelMarker
Definition: nfmdemodgui.h:49
void registerRxChannelInstance(const QString &channelName, PluginInstanceGUI *pluginGUI)
Definition: deviceuiset.cpp:82
bool m_doApplySettings
Definition: nfmdemodgui.h:52
void onWidgetRolled(QWidget *widget, bool rollDown)
int32_t i
Definition: decimators.h:244
void addRollupWidget(QWidget *widget)
Add rollup widget to channel window.
Definition: deviceuiset.cpp:77
static NFMDemodGUI * create(PluginAPI *pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
Definition: nfmdemodgui.cpp:19
void removeRxChannelInstance(PluginInstanceGUI *pluginGUI)
Definition: deviceuiset.cpp:94
const QString & getTitle() const
Definition: channelmarker.h:38
bool m_squelchOpen
Definition: nfmdemodgui.h:55
static bool match(const Message *message)
Definition: message.cpp:45
bool getHighlighted() const
Definition: channelmarker.h:61
void handleInputMessages()
Definition: nfmdemodgui.cpp:99
virtual void destroy()
Definition: nfmdemodgui.cpp:25
NFMDemodSettings m_settings
Definition: nfmdemodgui.h:50
void on_ctcss_currentIndexChanged(int index)
void on_squelchGate_valueChanged(int value)
bool deserialize(const QByteArray &data)
Definition: nfmdemodgui.cpp:63
bool m_basicSettingsShown
Definition: nfmdemodgui.h:51
uint16_t m_reverseAPIDeviceIndex
void enterEvent(QEvent *)
NFMDemod * m_nfmDemod
Definition: nfmdemodgui.h:54
void setReverseAPIAddress(const QString &address)
void setHighlighted(bool highlighted)
void applySettings(bool force=false)
void setColor(const QColor &color)
void on_audioMute_toggled(bool checked)
virtual bool handleMessage(const Message &message)
Definition: nfmdemodgui.cpp:75
void setVisible(bool visible)
virtual qint64 getCenterFrequency() const
Definition: nfmdemodgui.cpp:40
void on_afBW_valueChanged(int value)
void setBandwidth(int bandwidth)
const QColor & getColor() const
Definition: channelmarker.h:64
void setTitle(const QString &title)
static const int m_nbRfBW
int32_t m_inputFrequencyOffset
void setCenterFrequency(int centerFrequency)
const NFMDemodSettings & getSettings() const
Definition: nfmdemod.h:57
QByteArray serialize() const
Definition: nfmdemodgui.cpp:58
void widgetRolled(QWidget *widget, bool rollDown)
float Real
Definition: dsptypes.h:42
void setUseReverseAPI(bool useReverseAPI)
virtual void setCenterFrequency(qint64 centerFrequency)
Definition: nfmdemodgui.cpp:45
void on_rfBW_currentIndexChanged(int index)