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.
udpsourcegui.cpp
Go to the documentation of this file.
1 // Copyright (C) 2017 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 "udpsourcegui.h"
19 
20 #include "device/deviceuiset.h"
21 #include "dsp/spectrumvis.h"
22 #include "dsp/dspengine.h"
23 #include "util/simpleserializer.h"
24 #include "util/db.h"
26 #include "plugin/pluginapi.h"
27 #include "mainwindow.h"
28 
29 #include "ui_udpsourcegui.h"
30 
32 {
33  UDPSourceGUI* gui = new UDPSourceGUI(pluginAPI, deviceUISet, channelTx);
34  return gui;
35 }
36 
38 {
39  delete this;
40 }
41 
42 void UDPSourceGUI::setName(const QString& name)
43 {
44  setObjectName(name);
45 }
46 
47 QString UDPSourceGUI::getName() const
48 {
49  return objectName();
50 }
51 
54 }
55 
56 void UDPSourceGUI::setCenterFrequency(qint64 centerFrequency)
57 {
58  m_channelMarker.setCenterFrequency(centerFrequency);
59  applySettings();
60 }
61 
63 {
66  applySettings(true);
67 }
68 
69 QByteArray UDPSourceGUI::serialize() const
70 {
71  return m_settings.serialize();
72 }
73 
74 bool UDPSourceGUI::deserialize(const QByteArray& data)
75 {
76  if(m_settings.deserialize(data))
77  {
79  applySettings(true);
80  return true;
81  } else {
83  return false;
84  }
85 }
86 
88 {
90  {
92  m_settings = cfg.getSettings();
93  blockApplySettings(true);
95  blockApplySettings(false);
96  return true;
97  }
98  else
99  {
100  return false;
101  }
102 }
103 
105 {
106  Message* message;
107 
108  while ((message = getInputMessageQueue()->pop()) != 0)
109  {
110  if (handleMessage(*message))
111  {
112  delete message;
113  }
114  }
115 }
116 
117 UDPSourceGUI::UDPSourceGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent) :
118  RollupWidget(parent),
119  ui(new Ui::UDPSourceGUI),
120  m_pluginAPI(pluginAPI),
121  m_deviceUISet(deviceUISet),
122  m_tickCount(0),
123  m_channelMarker(this),
124  m_rfBandwidthChanged(false),
125  m_doApplySettings(true)
126 {
127  ui->setupUi(this);
128  connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
129  connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
130  setAttribute(Qt::WA_DeleteOnClose, true);
131 
132  m_spectrumVis = new SpectrumVis(SDR_TX_SCALEF, ui->glSpectrum);
133  m_udpSource = (UDPSource*) channelTx;
136 
137  ui->fmDeviation->setEnabled(false);
138  ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
139  ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
140  ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
141 
142  ui->glSpectrum->setCenterFrequency(0);
143  ui->glSpectrum->setSampleRate(ui->sampleRate->text().toInt());
144  ui->glSpectrum->setDisplayWaterfall(true);
145  ui->glSpectrum->setDisplayMaxHold(true);
147  64, // FFT size
148  10, // overlapping %
149  0, // number of averaging samples
150  0, // no averaging
152  false); // logarithmic scale
153 
154  ui->glSpectrum->connectTimer(MainWindow::getInstance()->getMasterTimer());
155  connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
156 
157  m_channelMarker.blockSignals(true);
161  m_channelMarker.setTitle("UDP Sample Sink");
163  m_channelMarker.blockSignals(false);
164  m_channelMarker.setVisible(true); // activate signal on the last setting only
165 
169 
170  connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
171 
172  ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
173 
174  connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
175  connect(m_udpSource, SIGNAL(levelChanged(qreal, qreal, int)), ui->volumeMeter, SLOT(levelChanged(qreal, qreal, int)));
176 
177  displaySettings();
178  applySettings(true);
179 }
180 
182 {
184  delete m_udpSource; // TODO: check this: when the GUI closes it has to delete the modulator
185  delete m_spectrumVis;
186  delete ui;
187 }
188 
190 {
191  m_doApplySettings = !block;
192 }
193 
195 {
196  if (m_doApplySettings)
197  {
202 
205 
206  ui->applyBtn->setEnabled(false);
207  ui->applyBtn->setStyleSheet("QPushButton { background:rgb(79,79,79); }");
208  }
209 }
210 
212 {
213  m_channelMarker.blockSignals(true);
216  m_channelMarker.blockSignals(false);
218 
220  this->setWindowTitle(m_channelMarker.getTitle());
221 
222  blockApplySettings(true);
223 
224  ui->deltaFrequency->setValue(m_settings.m_inputFrequencyOffset);
225  ui->sampleRate->setText(QString("%1").arg(roundf(m_settings.m_inputSampleRate), 0));
226  ui->glSpectrum->setSampleRate(m_settings.m_inputSampleRate);
227  ui->rfBandwidth->setText(QString("%1").arg(roundf(m_settings.m_rfBandwidth), 0));
228  ui->fmDeviation->setText(QString("%1").arg(m_settings.m_fmDeviation, 0));
229  ui->amModPercent->setText(QString("%1").arg(roundf(m_settings.m_amModFactor * 100.0), 0));
230 
232 
233  ui->channelMute->setChecked(m_settings.m_channelMute);
234  ui->autoRWBalance->setChecked(m_settings.m_autoRWBalance);
235  ui->stereoInput->setChecked(m_settings.m_stereoInput);
236 
237  ui->gainInText->setText(tr("%1").arg(m_settings.m_gainIn, 0, 'f', 1));
238  ui->gainIn->setValue(roundf(m_settings.m_gainIn * 10.0));
239 
240  ui->gainOutText->setText(tr("%1").arg(m_settings.m_gainOut, 0, 'f', 1));
241  ui->gainOut->setValue(roundf(m_settings.m_gainOut * 10.0));
242 
244  ui->squelchText->setText(tr("%1").arg(m_settings.m_squelch, 0, 'f', 0));
245  } else {
246  ui->squelchText->setText("---");
247  }
248 
249  ui->squelch->setValue(roundf(m_settings.m_squelch));
250 
251  ui->squelchGateText->setText(tr("%1").arg(roundf(m_settings.m_squelchGate * 1000.0), 0, 'f', 0));
252  ui->squelchGate->setValue(roundf(m_settings.m_squelchGate * 100.0));
253 
254  ui->localUDPAddress->setText(m_settings.m_udpAddress);
255  ui->localUDPPort->setText(tr("%1").arg(m_settings.m_udpPort));
256 
257  ui->applyBtn->setEnabled(false);
258  ui->applyBtn->setStyleSheet("QPushButton { background:rgb(79,79,79); }");
259 
260  blockApplySettings(false);
261 }
262 
264 {
265  ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
267  applySettings();
268 }
269 
271 {
274  applySettings();
275 }
276 
278 {
279  if (index == (int) UDPSourceSettings::FormatNFM) {
280  ui->fmDeviation->setEnabled(true);
281  } else {
282  ui->fmDeviation->setEnabled(false);
283  }
284 
285  if (index == (int) UDPSourceSettings::FormatAM) {
286  ui->amModPercent->setEnabled(true);
287  } else {
288  ui->amModPercent->setEnabled(false);
289  }
290 
291  setSampleFormat(index);
292 
293  ui->applyBtn->setEnabled(true);
294  ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
295 }
296 
298 {
299  m_settings.m_udpAddress = ui->localUDPAddress->text();
300  ui->applyBtn->setEnabled(true);
301  ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
302 }
303 
305 {
306  bool ok;
307  quint16 udpPort = ui->localUDPPort->text().toInt(&ok);
308 
309  if((!ok) || (udpPort < 1024)) {
310  udpPort = 9998;
311  }
312 
313  m_settings.m_udpPort = udpPort;
314  ui->localUDPPort->setText(tr("%1").arg(m_settings.m_udpPort));
315 
316  ui->applyBtn->setEnabled(true);
317  ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
318 }
319 
320 void UDPSourceGUI::on_sampleRate_textEdited(const QString& arg1)
321 {
322  (void) arg1;
323  bool ok;
324  Real inputSampleRate = ui->sampleRate->text().toDouble(&ok);
325 
326  if ((!ok) || (inputSampleRate < 1000)) {
328  ui->sampleRate->setText(QString("%1").arg(m_settings.m_inputSampleRate, 0));
329  } else {
330  m_settings.m_inputSampleRate = inputSampleRate;
331  }
332 
333  ui->applyBtn->setEnabled(true);
334  ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
335 }
336 
338 {
339  (void) arg1;
340  bool ok;
341  Real rfBandwidth = ui->rfBandwidth->text().toDouble(&ok);
342 
343  if ((!ok) || (rfBandwidth > m_settings.m_inputSampleRate))
344  {
346  ui->rfBandwidth->setText(QString("%1").arg(m_settings.m_rfBandwidth, 0));
347  }
348  else
349  {
350  m_settings.m_rfBandwidth = rfBandwidth;
351  }
352 
353  m_rfBandwidthChanged = true;
354 
355  ui->applyBtn->setEnabled(true);
356  ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
357 }
358 
360 {
361  (void) arg1;
362  bool ok;
363  int fmDeviation = ui->fmDeviation->text().toInt(&ok);
364 
365  if ((!ok) || (fmDeviation < 1)) {
366  m_settings.m_fmDeviation = 2500;
367  ui->fmDeviation->setText(QString("%1").arg(m_settings.m_fmDeviation));
368  } else {
369  m_settings.m_fmDeviation = fmDeviation;
370  }
371 
372  ui->applyBtn->setEnabled(true);
373  ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
374 }
375 
377 {
378  (void) arg1;
379  bool ok;
380  int amModPercent = ui->amModPercent->text().toInt(&ok);
381 
382  if ((!ok) || (amModPercent < 1) || (amModPercent > 100))
383  {
384  m_settings.m_amModFactor = 0.95;
385  ui->amModPercent->setText(QString("%1").arg(95));
386  } else {
387  m_settings.m_amModFactor = amModPercent / 100.0;
388  }
389 
390  ui->applyBtn->setEnabled(true);
391  ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
392 }
393 
395 {
396  m_settings.m_gainIn = value / 10.0;
397  ui->gainInText->setText(tr("%1").arg(m_settings.m_gainIn, 0, 'f', 1));
398  applySettings();
399 }
400 
402 {
403  m_settings.m_gainOut = value / 10.0;
404  ui->gainOutText->setText(tr("%1").arg(m_settings.m_gainOut, 0, 'f', 1));
405  applySettings();
406 }
407 
409 {
410  m_settings.m_squelchEnabled = (value != -100);
411  m_settings.m_squelch = value * 1.0;
412 
414  ui->squelchText->setText(tr("%1").arg(m_settings.m_squelch, 0, 'f', 0));
415  } else {
416  ui->squelchText->setText("---");
417  }
418 
419  applySettings();
420 }
421 
423 {
424  m_settings.m_squelchGate = value / 100.0;
425  ui->squelchGateText->setText(tr("%1").arg(roundf(value * 10.0), 0, 'f', 0));
426  applySettings();
427 }
428 
430 {
431  m_settings.m_channelMute = checked;
432  applySettings();
433 }
434 
436 {
438  {
440  m_rfBandwidthChanged = false;
441  }
442 
443  ui->glSpectrum->setSampleRate(m_settings.m_inputSampleRate);
444 
445  applySettings();
446 }
447 
449 {
451 }
452 
454 {
455  m_settings.m_autoRWBalance = checked;
456  applySettings();
457 }
458 
460 {
461  m_settings.m_stereoInput = checked;
462  applySettings();
463 }
464 
465 void UDPSourceGUI::onWidgetRolled(QWidget* widget, bool rollDown)
466 {
467  if ((widget == ui->spectrumBox) && (m_udpSource != 0))
468  {
469  m_udpSource->setSpectrum(rollDown);
470  }
471 }
472 
473 void UDPSourceGUI::onMenuDialogCalled(const QPoint &p)
474 {
476  {
483 
484  dialog.move(p);
485  dialog.exec();
486 
494 
495  setWindowTitle(m_channelMarker.getTitle());
497 
498  applySettings();
499  }
500 
502 }
503 
505 {
507 }
508 
510 {
512 }
513 
515 {
518 
519  if (m_tickCount % 4 == 0)
520  {
521  double powDb = CalcDb::dbPower(m_channelPowerAvg.asDouble());
522  ui->channelPower->setText(tr("%1 dB").arg(powDb, 0, 'f', 1));
523  double inPowDb = CalcDb::dbPower(m_inPowerAvg.asDouble());
524  ui->inputPower->setText(tr("%1").arg(inPowDb, 0, 'f', 1));
525  }
526 
527  int32_t bufferGauge = m_udpSource->getBufferGauge();
528  ui->bufferGaugeNegative->setValue((bufferGauge < 0 ? -bufferGauge : 0));
529  ui->bufferGaugePositive->setValue((bufferGauge < 0 ? 0 : bufferGauge));
530  QString s = QString::number(bufferGauge, 'f', 0);
531  ui->bufferRWBalanceText->setText(tr("%1").arg(s));
532 
533  if (m_udpSource->getSquelchOpen()) {
534  ui->channelMute->setStyleSheet("QToolButton { background-color : green; }");
535  } else {
536  ui->channelMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
537  }
538 
539  m_tickCount++;
540 }
541 
543 {
544  switch(sampleFormat)
545  {
547  ui->sampleFormat->setCurrentIndex(0);
548  ui->fmDeviation->setEnabled(false);
549  ui->stereoInput->setChecked(true);
550  ui->stereoInput->setEnabled(false);
551  break;
553  ui->sampleFormat->setCurrentIndex(1);
554  ui->fmDeviation->setEnabled(true);
555  ui->stereoInput->setEnabled(true);
556  break;
558  ui->sampleFormat->setCurrentIndex(2);
559  ui->fmDeviation->setEnabled(false);
560  ui->stereoInput->setEnabled(true);
561  break;
563  ui->sampleFormat->setCurrentIndex(3);
564  ui->fmDeviation->setEnabled(false);
565  ui->stereoInput->setEnabled(true);
566  break;
568  ui->sampleFormat->setCurrentIndex(4);
569  ui->fmDeviation->setEnabled(false);
570  ui->stereoInput->setEnabled(true);
571  break;
572  default:
573  ui->sampleFormat->setCurrentIndex(0);
574  ui->fmDeviation->setEnabled(false);
575  ui->stereoInput->setChecked(true);
576  ui->stereoInput->setEnabled(false);
577  break;
578  }
579 }
580 
582 {
583  switch(index)
584  {
585  case 0:
587  ui->fmDeviation->setEnabled(false);
588  ui->stereoInput->setChecked(true);
589  ui->stereoInput->setEnabled(false);
590  break;
591  case 1:
593  ui->fmDeviation->setEnabled(true);
594  ui->stereoInput->setEnabled(true);
595  break;
596  case 2:
598  ui->fmDeviation->setEnabled(false);
599  ui->stereoInput->setEnabled(true);
600  break;
601  case 3:
603  ui->fmDeviation->setEnabled(false);
604  ui->stereoInput->setEnabled(true);
605  break;
606  case 4:
608  ui->fmDeviation->setEnabled(false);
609  ui->stereoInput->setEnabled(true);
610  break;
611  default:
613  ui->fmDeviation->setEnabled(false);
614  ui->stereoInput->setChecked(true);
615  ui->stereoInput->setEnabled(false);
616  break;
617  }
618 }
619 
void removeTxChannelInstance(PluginInstanceGUI *pluginGUI)
double getInMagSq() const
Definition: udpsource.h:136
static MainWindow * getInstance()
Definition: mainwindow.h:73
void enterEvent(QEvent *)
const QString & getReverseAPIAddress() const
void on_amModPercent_textEdited(const QString &arg1)
void on_rfBandwidth_textEdited(const QString &arg1)
int getCenterFrequency() const
Definition: channelmarker.h:42
virtual bool deserialize(const QByteArray &data)
void registerTxChannelInstance(const QString &channelName, PluginInstanceGUI *pluginGUI)
Definition: deviceuiset.cpp:88
virtual void setCenterFrequency(qint64 centerFrequency)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
PluginAPI * m_pluginAPI
Definition: udpsourcegui.h:63
void on_applyBtn_clicked()
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)
virtual void resetToDefaults()
DeviceUISet * m_deviceUISet
Definition: udpsourcegui.h:64
static const QString m_channelIdURI
Definition: udpsource.h:143
const UDPSourceSettings & getSettings() const
Definition: udpsource.h:50
void on_deltaFrequency_changed(qint64 value)
void on_squelchGate_valueChanged(int value)
void leaveEvent(QEvent *)
static UDPSourceGUI * create(PluginAPI *pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx)
void displaySettings()
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
void setReverseAPIChannelIndex(uint16_t channelIndex)
void resetContextMenuType()
Definition: rollupwidget.h:50
void addChannelMarker(ChannelMarker *channelMarker)
Add channel marker to spectrum.
Definition: deviceuiset.cpp:72
MovingAverageUtil< double, double, 4 > m_inPowerAvg
Definition: udpsourcegui.h:68
bool getSquelchOpen() const
Definition: udpsource.h:138
virtual QByteArray serialize() const
void setSpectrum(bool enabled)
Definition: udpsource.cpp:450
virtual MessageQueue * getInputMessageQueue()
Definition: udpsourcegui.h:55
void on_localUDPPort_editingFinished()
ContextMenuType m_contextMenuType
Definition: rollupwidget.h:33
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
Real m_squelch
squared magnitude
void setReverseAPIDeviceIndex(uint16_t deviceIndex)
bool m_rfBandwidthChanged
Definition: udpsourcegui.h:74
Ui::UDPSourceGUI * ui
Definition: udpsourcegui.h:62
#define SDR_TX_SCALEF
Definition: dsptypes.h:39
int32_t getBufferGauge() const
Definition: udpsource.h:137
void on_sampleRate_textEdited(const QString &arg1)
void setSourceOrSinkStream(bool sourceOrSinkStream)
Definition: channelmarker.h:75
void setTitleColor(const QColor &c)
void setName(const QString &name)
void setHighlighted(bool highlighted)
void addRollupWidget(QWidget *widget)
Add rollup widget to channel window.
Definition: deviceuiset.cpp:77
virtual void setMessageQueueToGUI(MessageQueue *queue)
void handleSourceMessages()
const QString & getTitle() const
Definition: channelmarker.h:38
static bool match(const Message *message)
Definition: message.cpp:45
QString getName() const
QByteArray serialize() const
bool deserialize(const QByteArray &data)
int int32_t
Definition: rtptypes_win.h:45
void setSpectrumSink(BasebandSampleSink *spectrum)
Definition: udpsource.h:97
void setSampleFormat(int index)
uint16_t m_reverseAPIDeviceIndex
void on_gainIn_valueChanged(int value)
void on_squelch_valueChanged(int value)
void resetReadIndex()
Definition: udpsource.cpp:456
void onWidgetRolled(QWidget *widget, bool rollDown)
void on_sampleFormat_currentIndexChanged(int index)
virtual bool handleMessage(const Message &message)
virtual ~UDPSourceGUI()
void setSampleFormatIndex(const UDPSourceSettings::SampleFormat &sampleFormat)
void on_localUDPAddress_editingFinished()
void setReverseAPIAddress(const QString &address)
MovingAverageUtil< double, double, 4 > m_channelPowerAvg
Definition: udpsourcegui.h:67
uint16_t m_reverseAPIChannelIndex
void setColor(const QColor &color)
SpectrumVis * m_spectrumVis
Definition: udpsourcegui.h:65
uint32_t m_tickCount
Definition: udpsourcegui.h:69
UDPSourceSettings m_settings
Definition: udpsourcegui.h:73
double getMagSq() const
Definition: udpsource.h:135
virtual qint64 getCenterFrequency() const
void setVisible(bool visible)
Real m_squelchGate
seconds
void onMenuDialogCalled(const QPoint &p)
ChannelMarker m_channelMarker
Definition: udpsourcegui.h:70
virtual void destroy()
void configure(MessageQueue *msgQueue, int fftSize, int overlapPercent, unsigned int averagingNb, int averagingMode, FFTWindow::Function window, bool m_linear)
Definition: spectrumvis.cpp:44
void channelMarkerChangedByCursor()
SampleFormat m_sampleFormat
void setBandwidth(int bandwidth)
const QColor & getColor() const
Definition: channelmarker.h:64
void setTitle(const QString &title)
void on_stereoInput_toggled(bool checked)
UDPSourceGUI(PluginAPI *pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget *parent=NULL)
void on_autoRWBalance_toggled(bool checked)
void setCenterFrequency(int centerFrequency)
UDPSource * m_udpSource
Definition: udpsourcegui.h:66
void on_channelMute_toggled(bool checked)
double asDouble() const
Definition: movingaverage.h:57
void widgetRolled(QWidget *widget, bool rollDown)
float Real
Definition: dsptypes.h:42
void on_gainOut_valueChanged(int value)
void setUseReverseAPI(bool useReverseAPI)
bool m_doApplySettings
Definition: udpsourcegui.h:75
static MsgConfigureUDPSource * create(const UDPSourceSettings &settings, bool force)
Definition: udpsource.h:53
static MsgConfigureChannelizer * create(int sampleRate, int centerFrequency)
Definition: udpsource.h:77
void on_resetUDPReadIndex_clicked()
void applySettings(bool force=false)
void on_fmDeviation_textEdited(const QString &arg1)