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.
hackrfinputgui.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 "hackrfinputgui.h"
19 
20 #include <QDebug>
21 #include <QMessageBox>
22 
23 #include <libhackrf/hackrf.h>
24 
25 #include "gui/colormapper.h"
26 #include "gui/glspectrum.h"
27 #include "gui/crightclickenabler.h"
29 #include "dsp/dspengine.h"
30 #include "dsp/dspcommands.h"
31 #include "device/deviceapi.h"
32 #include "device/deviceuiset.h"
34 
35 #include "ui_hackrfinputgui.h"
36 
37 HackRFInputGui::HackRFInputGui(DeviceUISet *deviceUISet, QWidget* parent) :
38  QWidget(parent),
39  ui(new Ui::HackRFInputGui),
40  m_deviceUISet(deviceUISet),
41  m_settings(),
42  m_sampleRateMode(true),
43  m_forceSettings(true),
44  m_doApplySettings(true),
45  m_sampleSource(NULL),
46  m_lastEngineState(DeviceAPI::StNotStarted)
47 {
49 
50  ui->setupUi(this);
51  ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
52  ui->centerFrequency->setValueRange(7, 0U, 7250000U);
53 
54  ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
55  ui->sampleRate->setValueRange(8, 1000000U, 20000000U);
56 
57  connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
58  connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
59  m_statusTimer.start(500);
60 
61  CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStop);
62  connect(startStopRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
63 
66 
67  connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
69 
70  sendSettings();
71 }
72 
74 {
75  delete ui;
76 }
77 
79 {
80  delete this;
81 }
82 
83 void HackRFInputGui::setName(const QString& name)
84 {
85  setObjectName(name);
86 }
87 
88 QString HackRFInputGui::getName() const
89 {
90  return objectName();
91 }
92 
94 {
97  sendSettings();
98 }
99 
101 {
103 }
104 
105 void HackRFInputGui::setCenterFrequency(qint64 centerFrequency)
106 {
107  m_settings.m_centerFrequency = centerFrequency;
108  displaySettings();
109  sendSettings();
110 }
111 
112 QByteArray HackRFInputGui::serialize() const
113 {
114  return m_settings.serialize();
115 }
116 
117 bool HackRFInputGui::deserialize(const QByteArray& data)
118 {
119  if(m_settings.deserialize(data))
120  {
121  displaySettings();
122  m_forceSettings = true;
123  sendSettings();
124  return true;
125  }
126  else
127  {
128  resetToDefaults();
129  return false;
130  }
131 }
132 
134 {
136  {
138  m_settings = cfg.getSettings();
139  blockApplySettings(true);
140  displaySettings();
141  blockApplySettings(false);
142  return true;
143  }
144  else if (HackRFInput::MsgReportHackRF::match(message))
145  {
146  displaySettings();
147  return true;
148  }
149  else if (HackRFInput::MsgStartStop::match(message))
150  {
152  blockApplySettings(true);
153  ui->startStop->setChecked(notif.getStartStop());
154  blockApplySettings(false);
155 
156  return true;
157  }
158  else
159  {
160  return false;
161  }
162 }
163 
165 {
166  Message* message;
167 
168  while ((message = m_inputMessageQueue.pop()) != 0)
169  {
170  qDebug("HackRFGui::handleInputMessages: message: %s", message->getIdentifier());
171 
172  if (DSPSignalNotification::match(*message))
173  {
174  DSPSignalNotification* notif = (DSPSignalNotification*) message;
175  m_sampleRate = notif->getSampleRate();
177  qDebug("HackRFGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency());
179 
180  delete message;
181  }
182  else
183  {
184  if (handleMessage(*message))
185  {
186  delete message;
187  }
188  }
189  }
190 }
191 
193 {
197 }
198 
200 {
201  ui->sampleRate->blockSignals(true);
203 
204  if (m_sampleRateMode)
205  {
206  ui->sampleRateMode->setStyleSheet("QToolButton { background:rgb(60,60,60); }");
207  ui->sampleRateMode->setText("SR");
208  ui->sampleRate->setValueRange(8, 1000000U, 20000000U);
209  ui->sampleRate->setValue(m_settings.m_devSampleRate);
210  ui->sampleRate->setToolTip("Device to host sample rate (S/s)");
211  ui->deviceRateText->setToolTip("Baseband sample rate (S/s)");
212  uint32_t basebandSampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim);
213  ui->deviceRateText->setText(tr("%1k").arg(QString::number(basebandSampleRate / 1000.0f, 'g', 5)));
214  }
215  else
216  {
217  ui->sampleRateMode->setStyleSheet("QToolButton { background:rgb(50,50,50); }");
218  ui->sampleRateMode->setText("BB");
219  ui->sampleRate->setValueRange(8, 1000000U/(1<<m_settings.m_log2Decim), 20000000U/(1<<m_settings.m_log2Decim));
220  ui->sampleRate->setValue(m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim));
221  ui->sampleRate->setToolTip("Baseband sample rate (S/s)");
222  ui->deviceRateText->setToolTip("Device to host sample rate (S/s)");
223  ui->deviceRateText->setText(tr("%1k").arg(QString::number(m_settings.m_devSampleRate / 1000.0f, 'g', 5)));
224  }
225 
226  ui->sampleRate->blockSignals(false);
227 }
228 
230 {
235  DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD
236  );
237  ui->fcPos->setToolTip(tr("Relative position of device center frequency: %1 kHz").arg(QString::number(fShift / 1000.0f, 'g', 5)));
238 }
239 
241 {
242  blockApplySettings(true);
243 
244  ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000);
245 
246  ui->LOppm->setValue(m_settings.m_LOppmTenths);
247  ui->LOppmText->setText(QString("%1").arg(QString::number(m_settings.m_LOppmTenths/10.0, 'f', 1)));
248 
249  ui->dcOffset->setChecked(m_settings.m_dcBlock);
250  ui->iqImbalance->setChecked(m_settings.m_iqCorrection);
251 
253 
254  ui->biasT->setChecked(m_settings.m_biasT);
255 
256  ui->decim->setCurrentIndex(m_settings.m_log2Decim);
257 
258  ui->fcPos->setCurrentIndex((int) m_settings.m_fcPos);
259 
260  ui->lnaExt->setChecked(m_settings.m_lnaExt);
261  ui->lnaGainText->setText(tr("%1dB").arg(m_settings.m_lnaGain));
262  ui->lna->setValue(m_settings.m_lnaGain);
263 
264  unsigned int bandwidthIndex = HackRFBandwidths::getBandwidthIndex(m_settings.m_bandwidth/1000);
265  ui->bbFilter->setCurrentIndex(bandwidthIndex);
266 
267  ui->vgaText->setText(tr("%1dB").arg(m_settings.m_vgaGain));
268  ui->vga->setValue(m_settings.m_vgaGain);
269 
270  blockApplySettings(false);
271 }
272 
274 {
275  unsigned int savedIndex = HackRFBandwidths::getBandwidthIndex(m_settings.m_bandwidth/1000);
276  ui->bbFilter->blockSignals(true);
277  ui->bbFilter->clear();
278 
279  for (unsigned int i = 0; i < HackRFBandwidths::m_nb_bw; i++)
280  {
281  ui->bbFilter->addItem(QString("%1M").arg(QString::number(HackRFBandwidths::m_bw_k[i]/1000.0, 'f', 2)));
282  }
283 
284  ui->bbFilter->blockSignals(false);
285 
286  if (savedIndex < HackRFBandwidths::m_nb_bw)
287  {
288  ui->bbFilter->setCurrentIndex(savedIndex);
289  }
290  else
291  {
292  ui->bbFilter->setCurrentIndex((int) HackRFBandwidths::m_nb_bw-1);
293  }
294 }
295 
297 {
298  if(!m_updateTimer.isActive())
299  m_updateTimer.start(100);
300 }
301 
303 {
304  m_settings.m_LOppmTenths = value;
305  ui->LOppmText->setText(QString("%1").arg(QString::number(m_settings.m_LOppmTenths/10.0, 'f', 1)));
306  sendSettings();
307 }
308 
310 {
311  m_settings.m_dcBlock = checked;
312  sendSettings();
313 }
314 
316 {
317  m_settings.m_iqCorrection = checked;
318  sendSettings();
319 }
320 
322 {
323  int newBandwidth = HackRFBandwidths::getBandwidth(index);
324  m_settings.m_bandwidth = newBandwidth * 1000;
325  sendSettings();
326 }
327 
329 {
330  m_settings.m_biasT = (state == Qt::Checked);
331  sendSettings();
332 }
333 
335 {
336  m_settings.m_lnaExt = (state == Qt::Checked);
337  sendSettings();
338 }
339 
341 {
342  m_settings.m_centerFrequency = value * 1000;
343  sendSettings();
344 }
345 
347 {
348  m_settings.m_devSampleRate = value;
349 
350  if (!m_sampleRateMode) {
352  }
353 
355  sendSettings();
356 }
357 
359 {
360  if ((index <0) || (index > 6)) {
361  return;
362  }
363 
364  m_settings.m_log2Decim = index;
366  m_settings.m_devSampleRate = ui->sampleRate->getValueNew();
367 
368  if (!m_sampleRateMode) {
370  }
371 
372  sendSettings();
373 }
374 
376 {
377  m_settings.m_fcPos = (HackRFInputSettings::fcPos_t) (index < 0 ? 0 : index > 2 ? 2 : index);
379  sendSettings();
380 }
381 
383 {
384  if ((value < 0) || (value > 40))
385  return;
386 
387  ui->lnaGainText->setText(tr("%1dB").arg(value));
388  m_settings.m_lnaGain = value;
389  sendSettings();
390 }
391 
393 {
394  if ((value < 0) || (value > 62))
395  return;
396 
397  ui->vgaText->setText(tr("%1dB").arg(value));
398  m_settings.m_vgaGain = value;
399  sendSettings();
400 }
401 
403 {
404  if (m_doApplySettings)
405  {
408  }
409 }
410 
412 {
413  if (checked) {
414  ui->record->setStyleSheet("QToolButton { background-color : red; }");
415  } else {
416  ui->record->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
417  }
418 
421 }
422 
424 {
425  m_sampleRateMode = checked;
427 }
428 
430 {
431  if (m_doApplySettings)
432  {
433  qDebug() << "HackRFGui::updateHardware";
436  m_forceSettings = false;
437  m_updateTimer.stop();
438  }
439 }
440 
442 {
443  m_doApplySettings = !block;
444 }
445 
447 {
448  int state = m_deviceUISet->m_deviceAPI->state();
449 
450  if(m_lastEngineState != state)
451  {
452  switch(state)
453  {
455  ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
456  break;
457  case DeviceAPI::StIdle:
458  ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
459  ui->startStop->setChecked(false);
460  break;
462  ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
463  break;
464  case DeviceAPI::StError:
465  ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
466  QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage());
467  break;
468  default:
469  break;
470  }
471 
472  m_lastEngineState = state;
473  }
474 }
475 
477 {
478  BasicDeviceSettingsDialog dialog(this);
483 
484  dialog.move(p);
485  dialog.exec();
486 
491 
492  sendSettings();
493 }
QString getName() const
static const unsigned int m_nb_bw
Message * pop()
Pop message from queue.
const QString & getReverseAPIAddress() const
const HackRFInputSettings & getSettings() const
Definition: hackrfinput.h:45
void on_LOppm_valueChanged(int value)
void on_record_toggled(bool checked)
QByteArray serialize() const
DeviceUISet * m_deviceUISet
static qint32 calculateFrequencyShift(int log2Decim, fcPos_t fcPos, quint32 devSampleRate, FrequencyShiftScheme frequencyShiftScheme)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void setSampleRate(qint32 sampleRate)
Definition: glspectrum.cpp:211
HackRFInputGui(DeviceUISet *deviceUISet, QWidget *parent=0)
quint64 m_deviceCenterFrequency
Center frequency in device.
void on_vga_valueChanged(int value)
virtual bool handleMessage(const Message &message)
DeviceSampleSource * getSampleSource()
Return pointer to the device sample source (single Rx) or nullptr.
Definition: deviceapi.cpp:213
void setUseReverseAPI(bool useReverseAPI)
static const unsigned int m_bw_k[]
Ui::HackRFInputGui * ui
MessageQueue * getInputMessageQueue()
void on_biasT_stateChanged(int state)
void on_startStop_toggled(bool checked)
void on_iqImbalance_toggled(bool checked)
void on_bbFilter_currentIndexChanged(int index)
static MsgConfigureHackRF * create(const HackRFInputSettings &settings, bool force=false)
Definition: hackrfinput.h:48
QString errorMessage()
Last error message from the device engine.
Definition: deviceapi.cpp:290
DeviceSampleSource * m_sampleSource
QByteArray serialize() const
unsigned int uint32_t
Definition: rtptypes_win.h:46
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
MessageQueue m_inputMessageQueue
virtual void setCenterFrequency(qint64 centerFrequency)
GLSpectrum * getSpectrum()
Direct spectrum getter.
Definition: deviceuiset.h:57
engine is before initialization
Definition: deviceapi.h:53
qint64 getCenterFrequency() const
Definition: dspcommands.h:329
EngineState state() const
Return the state of the device engine corresponding to the stream type.
Definition: deviceapi.cpp:277
virtual qint64 getCenterFrequency() const
QTimer m_statusTimer
DeviceAPI * m_deviceAPI
Definition: deviceuiset.h:48
void on_sampleRateMode_toggled(bool checked)
engine is idle
Definition: deviceapi.h:54
bool m_sampleRateMode
true: device, false: base band sample rate update mode
void updateSampleRateAndFrequency()
void setName(const QString &name)
static MsgFileRecord * create(bool startStop)
Definition: hackrfinput.h:106
int32_t i
Definition: decimators.h:244
void on_dcOffset_toggled(bool checked)
static bool match(const Message *message)
Definition: message.cpp:45
static unsigned int getBandwidth(unsigned int bandwidth_index)
void blockApplySettings(bool block)
static unsigned int getBandwidthIndex(unsigned int bandwidth)
int int32_t
Definition: rtptypes_win.h:45
bool getStartStop() const
Definition: hackrfinput.h:85
void on_lnaExt_stateChanged(int state)
HackRFInputSettings m_settings
void on_centerFrequency_changed(quint64 value)
void on_fcPos_currentIndexChanged(int index)
static MsgStartStop * create(bool startStop)
Definition: hackrfinput.h:87
void openDeviceSettingsDialog(const QPoint &p)
int getSampleRate() const
Definition: dspcommands.h:328
virtual ~HackRFInputGui()
QTimer m_updateTimer
void setCenterFrequency(qint64 frequency)
Definition: glspectrum.cpp:175
virtual const char * getIdentifier() const
Definition: message.cpp:35
void on_decim_currentIndexChanged(int index)
void setReverseAPIAddress(const QString &address)
void setReverseAPIDeviceIndex(uint16_t deviceIndex)
void handleInputMessages()
virtual void setMessageQueueToGUI(MessageQueue *queue)=0
engine is running
Definition: deviceapi.h:56
bool deserialize(const QByteArray &data)
virtual void destroy()
void on_lna_valueChanged(int value)
bool deserialize(const QByteArray &data)
engine is in error
Definition: deviceapi.h:57
void on_sampleRate_changed(quint64 value)