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.
rtlsdrgui.cpp
Go to the documentation of this file.
1 // Copyright (C) 2015 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 <QDebug>
19 #include <QMessageBox>
20 
21 #include "rtlsdrgui.h"
22 
23 #include "device/deviceapi.h"
24 #include "device/deviceuiset.h"
25 #include "dsp/filerecord.h"
26 
27 #include "ui_rtlsdrgui.h"
28 #include "gui/colormapper.h"
29 #include "gui/glspectrum.h"
30 #include "gui/crightclickenabler.h"
32 #include "dsp/dspengine.h"
33 #include "dsp/dspcommands.h"
34 
35 
36 RTLSDRGui::RTLSDRGui(DeviceUISet *deviceUISet, QWidget* parent) :
37  QWidget(parent),
38  ui(new Ui::RTLSDRGui),
39  m_deviceUISet(deviceUISet),
40  m_doApplySettings(true),
41  m_forceSettings(true),
42  m_settings(),
43  m_sampleRateMode(true),
44  m_sampleSource(0),
45  m_lastEngineState(DeviceAPI::StNotStarted)
46 {
48 
49  ui->setupUi(this);
50  ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
52 
53  ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
54 
55  ui->rfBW->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
56  ui->rfBW->setValueRange(4, 350, 8000);
57 
58  connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
59  connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
60  m_statusTimer.start(500);
61 
63 
65  displayGains();
66 
67  connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
69 
70  CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStop);
71  connect(startStopRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
72 }
73 
75 {
76  delete ui;
77 }
78 
80 {
81  delete this;
82 }
83 
84 void RTLSDRGui::setName(const QString& name)
85 {
86  setObjectName(name);
87 }
88 
89 QString RTLSDRGui::getName() const
90 {
91  return objectName();
92 }
93 
95 {
98  sendSettings();
99 }
100 
102 {
104 }
105 
106 void RTLSDRGui::setCenterFrequency(qint64 centerFrequency)
107 {
108  m_settings.m_centerFrequency = centerFrequency;
109  displaySettings();
110  sendSettings();
111 }
112 
114 {
115  m_settings.m_dcBlock = checked;
116  sendSettings();
117 }
118 
120 {
121  m_settings.m_iqImbalance = checked;
122  sendSettings();
123 }
124 
125 QByteArray RTLSDRGui::serialize() const
126 {
127  return m_settings.serialize();
128 }
129 
130 bool RTLSDRGui::deserialize(const QByteArray& data)
131 {
132  if(m_settings.deserialize(data))
133  {
134  displayGains();
135  displaySettings();
136  m_forceSettings = true;
137  sendSettings();
138  return true;
139  }
140  else
141  {
142  resetToDefaults();
143  return false;
144  }
145 }
146 
147 bool RTLSDRGui::handleMessage(const Message& message)
148 {
150  {
152  m_settings = cfg.getSettings();
153  blockApplySettings(true);
154  displayGains();
155  displaySettings();
156  blockApplySettings(false);
157  return true;
158  }
159  else if (RTLSDRInput::MsgStartStop::match(message))
160  {
162  blockApplySettings(true);
163  ui->startStop->setChecked(notif.getStartStop());
164  blockApplySettings(false);
165 
166  return true;
167  }
168  else
169  {
170  return false;
171  }
172 }
173 
175 {
176  Message* message;
177 
178  while ((message = m_inputMessageQueue.pop()) != 0)
179  {
180  qDebug("RTLSDRGui::handleInputMessages: message: %s", message->getIdentifier());
181 
182  if (DSPSignalNotification::match(*message))
183  {
184  DSPSignalNotification* notif = (DSPSignalNotification*) message;
185  m_sampleRate = notif->getSampleRate();
187  qDebug("RTLSDRGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency());
189 
190  delete message;
191  }
192  else
193  {
194  if (handleMessage(*message))
195  {
196  delete message;
197  }
198  }
199  }
200 }
201 
203 {
207 }
208 
210 {
211  // values in kHz
212  qint64 deltaFrequency = m_settings.m_transverterMode ? m_settings.m_transverterDeltaFrequency/1000 : 0;
215 
216  minLimit = minLimit < 0 ? 0 : minLimit > 9999999 ? 9999999 : minLimit;
217  maxLimit = maxLimit < 0 ? 0 : maxLimit > 9999999 ? 9999999 : maxLimit;
218 
219  qDebug("RTLSDRGui::updateFrequencyLimits: delta: %lld min: %lld max: %lld", deltaFrequency, minLimit, maxLimit);
220 
221  ui->centerFrequency->setValueRange(7, minLimit, maxLimit);
222 }
223 
225 {
226  if (m_gains.size() > 0)
227  {
228  int dist = abs(m_settings.m_gain - m_gains[0]);
229  int pos = 0;
230 
231  for (uint i = 1; i < m_gains.size(); i++)
232  {
233  if (abs(m_settings.m_gain - m_gains[i]) < dist)
234  {
235  dist = abs(m_settings.m_gain - m_gains[i]);
236  pos = i;
237  }
238  }
239 
240  ui->gainText->setText(tr("%1.%2").arg(m_gains[pos] / 10).arg(abs(m_gains[pos] % 10)));
241  ui->gain->setMaximum(m_gains.size() - 1);
242  ui->gain->setEnabled(true);
243  ui->gain->setValue(pos);
244  }
245  else
246  {
247  ui->gain->setMaximum(0);
248  ui->gain->setEnabled(false);
249  ui->gain->setValue(0);
250  }
251 }
252 
254 {
255  ui->sampleRate->blockSignals(true);
257 
258  if (m_sampleRateMode)
259  {
260  ui->sampleRateMode->setStyleSheet("QToolButton { background:rgb(60,60,60); }");
261  ui->sampleRateMode->setText("SR");
262 
265  } else {
267  }
268 
269  ui->sampleRate->setValue(m_settings.m_devSampleRate);
270  ui->sampleRate->setToolTip("Device to host sample rate (S/s)");
271  ui->deviceRateText->setToolTip("Baseband sample rate (S/s)");
272  uint32_t basebandSampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim);
273  ui->deviceRateText->setText(tr("%1k").arg(QString::number(basebandSampleRate / 1000.0f, 'g', 5)));
274  }
275  else
276  {
277  ui->sampleRateMode->setStyleSheet("QToolButton { background:rgb(50,50,50); }");
278  ui->sampleRateMode->setText("BB");
279 
282  } else {
284  }
285 
286  ui->sampleRate->setValue(m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim));
287  ui->sampleRate->setToolTip("Baseband sample rate (S/s)");
288  ui->deviceRateText->setToolTip("Device to host sample rate (S/s)");
289  ui->deviceRateText->setText(tr("%1k").arg(QString::number(m_settings.m_devSampleRate / 1000.0f, 'g', 5)));
290  }
291 
292  ui->sampleRate->blockSignals(false);
293 }
294 
296 {
301  DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD
302  );
303  ui->fcPos->setToolTip(tr("Relative position of device center frequency: %1 kHz").arg(QString::number(fShift / 1000.0f, 'g', 5)));
304 }
305 
307 {
308  ui->transverter->setDeltaFrequency(m_settings.m_transverterDeltaFrequency);
309  ui->transverter->setDeltaFrequencyActive(m_settings.m_transverterMode);
311  ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000);
313  ui->rfBW->setValue(m_settings.m_rfBandwidth / 1000);
314  ui->dcOffset->setChecked(m_settings.m_dcBlock);
315  ui->iqImbalance->setChecked(m_settings.m_iqImbalance);
316  ui->ppm->setValue(m_settings.m_loPpmCorrection);
317  ui->ppmText->setText(tr("%1").arg(m_settings.m_loPpmCorrection));
318  ui->decim->setCurrentIndex(m_settings.m_log2Decim);
319  ui->fcPos->setCurrentIndex((int) m_settings.m_fcPos);
320  ui->checkBox->setChecked(m_settings.m_noModMode);
321  ui->agc->setChecked(m_settings.m_agc);
322  ui->lowSampleRate->setChecked(m_settings.m_lowSampleRate);
323  ui->offsetTuning->setChecked(m_settings.m_offsetTuning);
324 }
325 
327 {
328  if(!m_updateTimer.isActive())
329  {
330  m_updateTimer.start(100);
331  }
332 }
333 
335 {
336  m_settings.m_centerFrequency = value * 1000;
337  sendSettings();
338 }
339 
341 {
342  if ((index <0) || (index > 6)) {
343  return;
344  }
345 
346  m_settings.m_log2Decim = index;
348 
349  if (m_sampleRateMode) {
350  m_settings.m_devSampleRate = ui->sampleRate->getValueNew();
351  } else {
352  m_settings.m_devSampleRate = ui->sampleRate->getValueNew() * (1 << m_settings.m_log2Decim);
353  }
354 
355  sendSettings();
356 }
357 
359 {
360  m_settings.m_fcPos = (RTLSDRSettings::fcPos_t) (index < 0 ? 0 : index > 2 ? 2 : index);
362  sendSettings();
363 }
364 
366 {
367  if ((value > 99) || (value < -99))
368  {
369  return;
370  }
371 
372  ui->ppmText->setText(tr("%1").arg(value));
374 
375  sendSettings();
376 }
377 
379 {
380  if (value > (int)m_gains.size())
381  {
382  return;
383  }
384 
385  int gain = m_gains[value];
386  ui->gainText->setText(tr("%1.%2").arg(gain / 10).arg(abs(gain % 10)));
387  m_settings.m_gain = gain;
388 
389  sendSettings();
390 }
391 
393 {
394  if (m_doApplySettings)
395  {
398  }
399 }
400 
402 {
403  if (checked) {
404  ui->record->setStyleSheet("QToolButton { background-color : red; }");
405  } else {
406  ui->record->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
407  }
408 
411 }
412 
414 {
415  m_settings.m_transverterMode = ui->transverter->getDeltaFrequencyAcive();
416  m_settings.m_transverterDeltaFrequency = ui->transverter->getDeltaFrequency();
417  qDebug("RTLSDRGui::on_transverter_clicked: %lld Hz %s", m_settings.m_transverterDeltaFrequency, m_settings.m_transverterMode ? "on" : "off");
419  m_settings.m_centerFrequency = ui->centerFrequency->getValueNew()*1000;
420  sendSettings();
421 }
422 
424 {
425  m_sampleRateMode = checked;
427 }
428 
430 {
431  if (m_doApplySettings)
432  {
435  m_forceSettings = false;
436  m_updateTimer.stop();
437  }
438 }
439 
441 {
442  int state = m_deviceUISet->m_deviceAPI->state();
443 
444  if(m_lastEngineState != state)
445  {
446  switch(state)
447  {
449  ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
450  break;
451  case DeviceAPI::StIdle:
452  ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
453  break;
455  ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
456  break;
457  case DeviceAPI::StError:
458  ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
459  QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage());
460  break;
461  default:
462  break;
463  }
464 
465  m_lastEngineState = state;
466  }
467 }
468 
470 {
471  m_doApplySettings = !block;
472 }
473 
475 {
476  if (state == Qt::Checked)
477  {
478  ui->gain->setEnabled(false);
479  m_settings.m_noModMode = true;
481  ui->centerFrequency->setValue(7000);
482  m_settings.m_centerFrequency = 7000 * 1000;
483  }
484  else
485  {
486  ui->gain->setEnabled(true);
487  m_settings.m_noModMode = false;
489  ui->centerFrequency->setValue(434000);
490  ui->gain->setValue(0);
491  m_settings.m_centerFrequency = 435000 * 1000;
492  }
493 
494  sendSettings();
495 }
496 
498 {
499  m_settings.m_agc = (state == Qt::Checked);
500  sendSettings();
501 }
502 
504 {
505  if (m_sampleRateMode) {
506  m_settings.m_devSampleRate = value;
507  } else {
509  }
510 
512  sendSettings();
513 }
514 
516 {
517  m_settings.m_offsetTuning = checked;
518  sendSettings();
519 }
520 
521 void RTLSDRGui::on_rfBW_changed(quint64 value)
522 {
523  m_settings.m_rfBandwidth = value * 1000;
524  sendSettings();
525 }
526 
528 {
529  m_settings.m_lowSampleRate = checked;
530 
532 
533  if (m_sampleRateMode) {
534  m_settings.m_devSampleRate = ui->sampleRate->getValueNew();
535  } else {
536  m_settings.m_devSampleRate = ui->sampleRate->getValueNew() * (1 << m_settings.m_log2Decim);
537  }
538 
539  qDebug("RTLSDRGui::on_lowSampleRate_toggled: %d S/s", m_settings.m_devSampleRate);
540 
541  sendSettings();
542 }
543 
545 {
546  BasicDeviceSettingsDialog dialog(this);
551 
552  dialog.move(p);
553  dialog.exec();
554 
559 
560  sendSettings();
561 }
void on_sampleRate_changed(quint64 value)
Definition: rtlsdrgui.cpp:503
bool m_forceSettings
Definition: rtlsdrgui.h:60
int m_sampleRate
Definition: rtlsdrgui.h:67
Message * pop()
Pop message from queue.
const QString & getReverseAPIAddress() const
QString getName() const
Definition: rtlsdrgui.cpp:89
void displayFcTooltip()
Definition: rtlsdrgui.cpp:295
QByteArray serialize() const
Definition: rtlsdrgui.cpp:125
static qint32 calculateFrequencyShift(int log2Decim, fcPos_t fcPos, quint32 devSampleRate, FrequencyShiftScheme frequencyShiftScheme)
void on_offsetTuning_toggled(bool checked)
Definition: rtlsdrgui.cpp:515
void on_centerFrequency_changed(quint64 value)
Definition: rtlsdrgui.cpp:334
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void on_rfBW_changed(quint64 value)
Definition: rtlsdrgui.cpp:521
void setSampleRate(qint32 sampleRate)
Definition: glspectrum.cpp:211
void updateFrequencyLimits()
Definition: rtlsdrgui.cpp:209
static const quint64 frequencyLowRangeMin
Definition: rtlsdrinput.h:146
void on_dcOffset_toggled(bool checked)
Definition: rtlsdrgui.cpp:113
void sendSettings()
Definition: rtlsdrgui.cpp:326
static const int sampleRateHighRangeMax
Definition: rtlsdrinput.h:153
DeviceSampleSource * getSampleSource()
Return pointer to the device sample source (single Rx) or nullptr.
Definition: deviceapi.cpp:213
void setUseReverseAPI(bool useReverseAPI)
void on_sampleRateMode_toggled(bool checked)
Definition: rtlsdrgui.cpp:423
virtual qint64 getCenterFrequency() const
Definition: rtlsdrgui.cpp:101
MessageQueue * getInputMessageQueue()
QByteArray serialize() const
bool deserialize(const QByteArray &data)
Definition: rtlsdrgui.cpp:130
static MsgConfigureRTLSDR * create(const RTLSDRSettings &settings, bool force)
Definition: rtlsdrinput.h:46
RTLSDRGui(DeviceUISet *deviceUISet, QWidget *parent=0)
Definition: rtlsdrgui.cpp:36
QTimer m_statusTimer
Definition: rtlsdrgui.h:64
void on_checkBox_stateChanged(int state)
Definition: rtlsdrgui.cpp:474
void updateSampleRateAndFrequency()
Definition: rtlsdrgui.cpp:202
Fixed< IntType, IntBits > abs(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2313
DeviceUISet * m_deviceUISet
Definition: rtlsdrgui.h:58
QString errorMessage()
Last error message from the device engine.
Definition: deviceapi.cpp:290
bool getStartStop() const
Definition: rtlsdrinput.h:85
static const int sampleRateHighRangeMin
Definition: rtlsdrinput.h:152
void on_decim_currentIndexChanged(int index)
Definition: rtlsdrgui.cpp:340
QTimer m_updateTimer
Definition: rtlsdrgui.h:63
virtual void setMessageQueueToGUI(MessageQueue *queue)
Definition: rtlsdrinput.h:111
unsigned int uint32_t
Definition: rtptypes_win.h:46
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
int m_lastEngineState
Definition: rtlsdrgui.h:69
GLSpectrum * getSpectrum()
Direct spectrum getter.
Definition: deviceuiset.h:57
engine is before initialization
Definition: deviceapi.h:53
uint16_t m_reverseAPIDeviceIndex
qint64 getCenterFrequency() const
Definition: dspcommands.h:329
uint16_t m_reverseAPIPort
EngineState state() const
Return the state of the device engine corresponding to the stream type.
Definition: deviceapi.cpp:277
RTLSDRSettings m_settings
Definition: rtlsdrgui.h:61
void on_agc_stateChanged(int state)
Definition: rtlsdrgui.cpp:497
DeviceAPI * m_deviceAPI
Definition: deviceuiset.h:48
engine is idle
Definition: deviceapi.h:54
bool m_sampleRateMode
true: device, false: base band sample rate update mode
Definition: rtlsdrgui.h:62
void openDeviceSettingsDialog(const QPoint &p)
Definition: rtlsdrgui.cpp:544
static MsgStartStop * create(bool startStop)
Definition: rtlsdrinput.h:87
virtual void setCenterFrequency(qint64 centerFrequency)
Definition: rtlsdrgui.cpp:106
int32_t i
Definition: decimators.h:244
void on_startStop_toggled(bool checked)
Definition: rtlsdrgui.cpp:392
RTLSDRInput * m_sampleSource
Definition: rtlsdrgui.h:66
static const quint64 frequencyHighRangeMax
Definition: rtlsdrinput.h:149
static bool match(const Message *message)
Definition: message.cpp:45
void handleInputMessages()
Definition: rtlsdrgui.cpp:174
int int32_t
Definition: rtptypes_win.h:45
void updateHardware()
Definition: rtlsdrgui.cpp:429
void on_transverter_clicked()
Definition: rtlsdrgui.cpp:413
void setName(const QString &name)
Definition: rtlsdrgui.cpp:84
void blockApplySettings(bool block)
Definition: rtlsdrgui.cpp:469
quint32 m_log2Decim
virtual bool handleMessage(const Message &message)
Definition: rtlsdrgui.cpp:147
void on_record_toggled(bool checked)
Definition: rtlsdrgui.cpp:401
quint32 m_rfBandwidth
RF filter bandwidth in Hz.
quint64 m_deviceCenterFrequency
Center frequency in device.
Definition: rtlsdrgui.h:68
qint32 m_loPpmCorrection
bool m_doApplySettings
Definition: rtlsdrgui.h:59
void updateStatus()
Definition: rtlsdrgui.cpp:440
static const int sampleRateLowRangeMax
Definition: rtlsdrinput.h:151
std::vector< int > m_gains
Definition: rtlsdrgui.h:65
QString m_reverseAPIAddress
void resetToDefaults()
Definition: rtlsdrgui.cpp:94
MessageQueue m_inputMessageQueue
Definition: rtlsdrgui.h:70
int getSampleRate() const
Definition: dspcommands.h:328
void displaySampleRate()
Definition: rtlsdrgui.cpp:253
void on_fcPos_currentIndexChanged(int index)
Definition: rtlsdrgui.cpp:358
void setCenterFrequency(qint64 frequency)
Definition: glspectrum.cpp:175
virtual const char * getIdentifier() const
Definition: message.cpp:35
void on_iqImbalance_toggled(bool checked)
Definition: rtlsdrgui.cpp:119
void setReverseAPIAddress(const QString &address)
const std::vector< int > & getGains() const
Definition: rtlsdrinput.h:143
void setReverseAPIDeviceIndex(uint16_t deviceIndex)
qint64 m_transverterDeltaFrequency
const RTLSDRSettings & getSettings() const
Definition: rtlsdrinput.h:43
engine is running
Definition: deviceapi.h:56
quint64 m_centerFrequency
void on_gain_valueChanged(int value)
Definition: rtlsdrgui.cpp:378
void displaySettings()
Definition: rtlsdrgui.cpp:306
bool deserialize(const QByteArray &data)
static const int sampleRateLowRangeMin
Definition: rtlsdrinput.h:150
void displayGains()
Definition: rtlsdrgui.cpp:224
void on_ppm_valueChanged(int value)
Definition: rtlsdrgui.cpp:365
Ui::RTLSDRGui * ui
Definition: rtlsdrgui.h:56
virtual ~RTLSDRGui()
Definition: rtlsdrgui.cpp:74
virtual void destroy()
Definition: rtlsdrgui.cpp:79
void on_lowSampleRate_toggled(bool checked)
Definition: rtlsdrgui.cpp:527
engine is in error
Definition: deviceapi.h:57
static const quint64 frequencyHighRangeMin
Definition: rtlsdrinput.h:148
static const quint64 frequencyLowRangeMax
Definition: rtlsdrinput.h:147
static MsgFileRecord * create(bool startStop)
Definition: rtlsdrinput.h:68