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.
freedvdemodgui.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 <QPixmap>
19 
20 #include "freedvdemodgui.h"
21 
22 #include "device/deviceuiset.h"
23 
24 #include "dsp/spectrumvis.h"
25 #include "dsp/dspengine.h"
26 #include "dsp/dspcommands.h"
27 #include "gui/glspectrum.h"
29 #include "plugin/pluginapi.h"
30 #include "util/simpleserializer.h"
31 #include "util/db.h"
32 #include "gui/crightclickenabler.h"
33 #include "gui/audioselectdialog.h"
34 #include "mainwindow.h"
35 
36 #include "ui_freedvdemodgui.h"
37 #include "freedvdemod.h"
38 
40 {
41  FreeDVDemodGUI* gui = new FreeDVDemodGUI(pluginAPI, deviceUISet, rxChannel);
42  return gui;
43 }
44 
46 {
47  delete this;
48 }
49 
50 void FreeDVDemodGUI::setName(const QString& name)
51 {
52  setObjectName(name);
53 }
54 
55 QString FreeDVDemodGUI::getName() const
56 {
57  return objectName();
58 }
59 
61 {
63 }
64 
65 void FreeDVDemodGUI::setCenterFrequency(qint64 centerFrequency)
66 {
67  m_channelMarker.setCenterFrequency(centerFrequency);
69  applySettings();
70 }
71 
73 {
75 }
76 
77 QByteArray FreeDVDemodGUI::serialize() const
78 {
79  return m_settings.serialize();
80 }
81 
82 bool FreeDVDemodGUI::deserialize(const QByteArray& data)
83 {
84  if(m_settings.deserialize(data))
85  {
87  applyBandwidths(5 - ui->spanLog2->value(), true); // does applySettings(true)
88  return true;
89  }
90  else
91  {
94  applyBandwidths(5 - ui->spanLog2->value(), true); // does applySettings(true)
95  return false;
96  }
97 }
98 
100 {
102  {
103  qDebug("FreeDVDemodGUI::handleMessage: FreeDVDemodGUI::MsgConfigureFreeDVDemod");
105  m_settings = cfg.getSettings();
106  blockApplySettings(true);
107  displaySettings();
108  blockApplySettings(false);
109  return true;
110  }
111  else if (DSPConfigureAudio::match(message))
112  {
113  qDebug("FreeDVDemodGUI::handleMessage: DSPConfigureAudio: %d", m_freeDVDemod->getAudioSampleRate());
114  applyBandwidths(5 - ui->spanLog2->value()); // will update spectrum details with new sample rate
115  return true;
116  }
117  else
118  {
119  return false;
120  }
121 }
122 
124 {
125  Message* message;
126 
127  while ((message = getInputMessageQueue()->pop()) != 0)
128  {
129  if (handleMessage(*message))
130  {
131  delete message;
132  }
133  }
134 }
135 
137 {
138  ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
140  applySettings();
141 }
142 
144 {
146 }
147 
149 {
152  applySettings();
153 }
154 
156 {
157  (void) checked;
160 }
161 
163 {
168  applySettings();
169 }
170 
172 {
173  ui->volumeText->setText(QString("%1").arg(value / 10.0, 0, 'f', 1));
174  m_settings.m_volume = value / 10.0;
175  applySettings();
176 }
177 
179 {
180  ui->volumeInText->setText(QString("%1").arg(value / 10.0, 0, 'f', 1));
181  m_settings.m_volumeIn = value / 10.0;
182  applySettings();
183 }
184 
186 {
187  m_settings.m_agc = checked;
188  applySettings();
189 }
190 
192 {
193  m_audioMute = checked;
194  m_settings.m_audioMute = checked;
195  applySettings();
196 }
197 
199 {
200  if ((value < 0) || (value > 4)) {
201  return;
202  }
203 
204  applyBandwidths(5 - ui->spanLog2->value());
205 }
206 
208 {
210  {
217 
218  dialog.move(p);
219  dialog.exec();
220 
229 
230  setWindowTitle(m_settings.m_title);
232 
233  applySettings();
234  }
235 
237 }
238 
239 void FreeDVDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown)
240 {
241  (void) widget;
242  (void) rollDown;
243 }
244 
245 FreeDVDemodGUI::FreeDVDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) :
246  RollupWidget(parent),
247  ui(new Ui::FreeDVDemodGUI),
248  m_pluginAPI(pluginAPI),
249  m_deviceUISet(deviceUISet),
250  m_channelMarker(this),
251  m_doApplySettings(true),
252  m_spectrumRate(6000),
253  m_audioBinaural(false),
254  m_audioFlipChannels(false),
255  m_audioMute(false),
256  m_squelchOpen(false)
257 {
258  ui->setupUi(this);
259  setAttribute(Qt::WA_DeleteOnClose, true);
260  connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
261  connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
262 
263  m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
264  m_freeDVDemod = (FreeDVDemod*) rxChannel;
267 
268  resetToDefaults();
269 
270  ui->glSpectrum->setCenterFrequency(m_spectrumRate/2);
271  ui->glSpectrum->setSampleRate(m_spectrumRate);
272  ui->glSpectrum->setDisplayWaterfall(true);
273  ui->glSpectrum->setDisplayMaxHold(true);
274  ui->glSpectrum->setSsbSpectrum(true);
275  ui->glSpectrum->connectTimer(MainWindow::getInstance()->getMasterTimer());
276 
277  connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
278 
279  CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute);
280  connect(audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect()));
281 
282  ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
283  ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
284  ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
285  ui->channelPowerMeter->setColorTheme(LevelMeterSignalDB::ColorGreenAndBlue);
286  ui->snrMeter->setColorTheme(LevelMeterSignalDB::ColorCyanAndBlue);
287  ui->snrMeter->setRange(-10, 30);
288  ui->snrMeter->setAverageSmoothing(2);
289 
290  m_channelMarker.setVisible(true); // activate signal on the last setting only
291 
293  m_settings.setSpectrumGUI(ui->spectrumGUI);
294 
298 
299  connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
300  connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
301  connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
302  connect(m_freeDVDemod, SIGNAL(levelInChanged(qreal, qreal, int)), ui->volumeInMeter, SLOT(levelChanged(qreal, qreal, int)));
303 
304  ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
305 
306  m_iconDSBUSB.addPixmap(QPixmap("://dsb.png"), QIcon::Normal, QIcon::On);
307  m_iconDSBUSB.addPixmap(QPixmap("://usb.png"), QIcon::Normal, QIcon::Off);
308  m_iconDSBLSB.addPixmap(QPixmap("://dsb.png"), QIcon::Normal, QIcon::On);
309  m_iconDSBLSB.addPixmap(QPixmap("://lsb.png"), QIcon::Normal, QIcon::Off);
310 
311  displaySettings();
312  applyBandwidths(5 - ui->spanLog2->value(), true); // does applySettings(true)
313 }
314 
316 {
318  delete m_freeDVDemod; // TODO: check this: when the GUI closes it has to delete the demodulator
319  delete m_spectrumVis;
320  delete ui;
321 }
322 
324 {
325  bool ret = !m_doApplySettings;
326  m_doApplySettings = !block;
327  return ret;
328 }
329 
331 {
332  if (m_doApplySettings)
333  {
336  m_freeDVDemod->getInputMessageQueue()->push(channelConfigMsg);
337 
340  }
341 }
342 
343 void FreeDVDemodGUI::applyBandwidths(int spanLog2, bool force)
344 {
346  m_settings.m_spanLog2 = spanLog2;
347  applySettings(force);
348 }
349 
351 {
352  m_spectrumRate = m_freeDVDemod->getModemSampleRate() / (1<<spanLog2);
353  int bwMax = m_freeDVDemod->getModemSampleRate() / (100*(1<<spanLog2));
354 
355  qDebug() << "FreeDVDemodGUI::displayBandwidths:"
356  << " spanLog2: " << spanLog2
357  << " m_spectrumRate: " << m_spectrumRate
358  << " bwMax: " << bwMax;
359 
360  QString spanStr = QString::number(bwMax/10.0, 'f', 1);
361 
362  ui->spanText->setText(tr("%1k").arg(spanStr));
363  ui->glSpectrum->setCenterFrequency(m_spectrumRate/2);
364  ui->glSpectrum->setSampleRate(m_spectrumRate);
365  ui->glSpectrum->setSsbSpectrum(true);
366  ui->glSpectrum->setLsbDisplay(false);
367 }
368 
370 {
371  m_channelMarker.blockSignals(true);
377  m_channelMarker.blockSignals(false);
378  m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
379 
381  setWindowTitle(m_channelMarker.getTitle());
382 
383  blockApplySettings(true);
384 
385  ui->freeDVMode->setCurrentIndex((int) m_settings.m_freeDVMode);
386  ui->agc->setChecked(m_settings.m_agc);
387  ui->audioMute->setChecked(m_settings.m_audioMute);
388  ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
389 
390  // Prevent uncontrolled triggering of applyBandwidths
391  ui->spanLog2->blockSignals(true);
392  ui->spanLog2->setValue(5 - m_settings.m_spanLog2);
394  ui->spanLog2->blockSignals(false);
395 
396  ui->volume->setValue(m_settings.m_volume * 10.0);
397  ui->volumeText->setText(QString("%1").arg(m_settings.m_volume, 0, 'f', 1));
398 
399  ui->volumeIn->setValue(m_settings.m_volumeIn * 10.0);
400  ui->volumeInText->setText(QString("%1").arg(m_settings.m_volumeIn, 0, 'f', 1));
401 
402  blockApplySettings(false);
403 }
404 
406 {
408 }
409 
411 {
413 }
414 
416 {
417  qDebug("FreeDVDemodGUI::audioSelect");
419  audioSelect.exec();
420 
421  if (audioSelect.m_selected)
422  {
424  applySettings();
425  }
426 }
427 
429 {
430  double magsqAvg, magsqPeak;
431  int nbMagsqSamples;
432  m_freeDVDemod->getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples);
433  double powDbAvg = CalcDb::dbPower(magsqAvg);
434  double powDbPeak = CalcDb::dbPower(magsqPeak);
435 
436  ui->channelPowerMeter->levelChanged(
439  nbMagsqSamples);
440 
441  double snrAvg, snrPeak;
442  int nbSNRSamples;
443  m_freeDVDemod->getSNRLevels(snrAvg, snrPeak, nbSNRSamples);
444 
445  ui->snrMeter->levelChanged(
446  (10.0f + snrAvg) / 40.0f,
447  (10.0f + snrPeak) / 40.0f,
448  nbSNRSamples
449  );
450 
451  ui->berText->setText(tr("%1").arg(m_freeDVDemod->getBER()));
452  float freqOffset = m_freeDVDemod->getFrequencyOffset();
453  int freqOffsetInt = freqOffset < -999 ? -999 : freqOffset > 999 ? 999 : freqOffset;
454  ui->freqOffset->setText(tr("%1Hz").arg(freqOffsetInt));
455 
456  if (m_freeDVDemod->isSync()) {
457  ui->syncLabel->setStyleSheet("QLabel { background-color : green; }");
458  } else {
459  ui->syncLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }");
460  }
461 
462  if (m_tickCount % 4 == 0) {
463  ui->channelPower->setText(tr("%1 dB").arg(powDbAvg, 0, 'f', 1));
464  ui->snrText->setText(tr("%1 dB").arg(snrAvg < -90 ? -90 : snrAvg > 90 ? 90 : snrAvg, 0, 'f', 1));
465  }
466 
467  bool squelchOpen = m_freeDVDemod->getAudioActive();
468 
469  if (squelchOpen != m_squelchOpen)
470  {
471  if (squelchOpen) {
472  ui->audioMute->setStyleSheet("QToolButton { background-color : green; }");
473  } else {
474  ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
475  }
476 
477  m_squelchOpen = squelchOpen;
478  }
479 
480  m_tickCount++;
481 }
virtual void destroy()
void on_freeDVMode_currentIndexChanged(int index)
void setChannelMarker(Serializable *channelMarker)
static MainWindow * getInstance()
Definition: mainwindow.h:73
const QString & getReverseAPIAddress() const
static MsgResyncFreeDVDemod * create()
Definition: freedvdemod.h:80
bool m_audioFlipChannels
void on_volume_valueChanged(int value)
void getSNRLevels(double &avg, double &peak, int &nbSamples)
int getCenterFrequency() const
Definition: channelmarker.h:42
float getFrequencyOffset() const
Definition: freedvdemod.h:179
void setLowCutoff(int lowCutoff)
Ui::FreeDVDemodGUI * ui
void push(Message *message, bool emitSignal=true)
Push message onto queue.
static MsgConfigureFreeDVDemod * create(const FreeDVDemodSettings &settings, bool force)
Definition: freedvdemod.h:60
static double dbPower(double magsq, double floor=1e-12)
Definition: db.cpp:22
bool getAudioActive() const
Definition: freedvdemod.h:157
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
SpectrumVis * m_spectrumVis
DeviceUISet * m_deviceUISet
virtual MessageQueue * getInputMessageQueue()
int getBER() const
Definition: freedvdemod.h:178
static const QString m_channelIdURI
Definition: freedvdemod.h:196
void applyBandwidths(int spanLog2, bool force=false)
QString getName() const
void on_agc_toggled(bool checked)
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_spanLog2_valueChanged(int value)
void getMagSqLevels(double &avg, double &peak, int &nbSamples)
Definition: freedvdemod.h:159
ContextMenuType m_contextMenuType
Definition: rollupwidget.h:33
bool deserialize(const QByteArray &data)
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
void onMenuDialogCalled(const QPoint &p)
void setReverseAPIDeviceIndex(uint16_t deviceIndex)
bool blockApplySettings(bool block)
#define SDR_RX_SCALEF
Definition: dsptypes.h:33
void displayBandwidths(int spanLog2)
uint32_t m_tickCount
virtual bool handleMessage(const Message &message)
virtual ~FreeDVDemodGUI()
void enterEvent(QEvent *)
void setSpectrumGUI(Serializable *spectrumGUI)
virtual void setMessageQueueToGUI(MessageQueue *queue)
uint32_t getModemSampleRate() const
Definition: freedvdemod.h:155
static DSPEngine * instance()
Definition: dspengine.cpp:51
static MsgConfigureChannelizer * create(int sampleRate, int centerFrequency)
Definition: freedvdemod.h:96
void setTitleColor(const QColor &c)
void setHighlighted(bool highlighted)
const FreeDVDemodSettings & getSettings() const
Definition: freedvdemod.h:57
void registerRxChannelInstance(const QString &channelName, PluginInstanceGUI *pluginGUI)
Definition: deviceuiset.cpp:82
void channelMarkerHighlightedByCursor()
QByteArray serialize() const
void addRollupWidget(QWidget *widget)
Add rollup widget to channel window.
Definition: deviceuiset.cpp:77
PluginAPI * m_pluginAPI
bool deserialize(const QByteArray &data)
void removeRxChannelInstance(PluginInstanceGUI *pluginGUI)
Definition: deviceuiset.cpp:94
const QString & getTitle() const
Definition: channelmarker.h:38
static const float m_mminPowerThresholdDBf
virtual qint64 getCenterFrequency() const
static bool match(const Message *message)
Definition: message.cpp:45
bool getHighlighted() const
Definition: channelmarker.h:61
void on_audioMute_toggled(bool checked)
void setSampleSink(BasebandSampleSink *sampleSink)
Definition: freedvdemod.h:115
void handleInputMessages()
void onWidgetRolled(QWidget *widget, bool rollDown)
void setName(const QString &name)
uint32_t getAudioSampleRate() const
Definition: freedvdemod.h:154
void setReverseAPIAddress(const QString &address)
void applySettings(bool force=false)
FreeDVDemodSettings m_settings
void setHighlighted(bool highlighted)
bool isSync() const
Definition: freedvdemod.h:180
FreeDVDemodGUI(PluginAPI *pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget *parent=0)
void setColor(const QColor &color)
void setVisible(bool visible)
virtual void setCenterFrequency(qint64 centerFrequency)
QByteArray serialize() const
void setBandwidth(int bandwidth)
const QColor & getColor() const
Definition: channelmarker.h:64
void setTitle(const QString &title)
void on_reSync_clicked(bool checked)
ChannelMarker m_channelMarker
void channelMarkerChangedByCursor()
static FreeDVDemodGUI * create(PluginAPI *pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
void setCenterFrequency(int centerFrequency)
void setSidebands(sidebands_t sidebands)
static int getHiCutoff(FreeDVMode freeDVMode)
FreeDVDemod * m_freeDVDemod
void widgetRolled(QWidget *widget, bool rollDown)
void on_deltaFrequency_changed(qint64 value)
void setUseReverseAPI(bool useReverseAPI)
static int getLowCutoff(FreeDVMode freeDVMode)
void leaveEvent(QEvent *)
void on_volumeIn_valueChanged(int value)