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.
bladerf1outputgui.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 <libbladeRF.h>
22 
23 #include "ui_bladerf1outputgui.h"
24 #include "gui/colormapper.h"
25 #include "gui/glspectrum.h"
26 #include "gui/crightclickenabler.h"
28 #include "dsp/dspengine.h"
29 #include "dsp/dspcommands.h"
30 #include "device/deviceapi.h"
31 #include "device/deviceuiset.h"
32 #include "bladerf1outputgui.h"
33 
34 Bladerf1OutputGui::Bladerf1OutputGui(DeviceUISet *deviceUISet, QWidget* parent) :
35  QWidget(parent),
36  ui(new Ui::Bladerf1OutputGui),
37  m_deviceUISet(deviceUISet),
38  m_doApplySettings(true),
39  m_forceSettings(true),
40  m_settings(),
41  m_sampleRateMode(true),
42  m_deviceSampleSink(nullptr),
43  m_sampleRate(0),
44  m_lastEngineState(DeviceAPI::StNotStarted)
45 {
47 
48  ui->setupUi(this);
49  ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
50  ui->centerFrequency->setValueRange(7, BLADERF_FREQUENCY_MIN_XB200/1000, BLADERF_FREQUENCY_MAX/1000);
51 
52  ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
53  ui->sampleRate->setValueRange(8, BLADERF_SAMPLERATE_MIN, BLADERF_SAMPLERATE_REC_MAX);
54 
55  ui->bandwidth->clear();
56 
57  for (unsigned int i = 0; i < BladerfBandwidths::getNbBandwidths(); i++)
58  {
59  ui->bandwidth->addItem(QString::number(BladerfBandwidths::getBandwidth(i)));
60  }
61 
62  connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
63  connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
64  m_statusTimer.start(500);
65 
66  CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStop);
67  connect(startStopRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
68 
70 
71  connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
72 }
73 
75 {
76  delete ui;
77 }
78 
80 {
81  delete this;
82 }
83 
84 void Bladerf1OutputGui::setName(const QString& name)
85 {
86  setObjectName(name);
87 }
88 
90 {
91  return objectName();
92 }
93 
95 {
98  sendSettings();
99 }
100 
102 {
104 }
105 
106 void Bladerf1OutputGui::setCenterFrequency(qint64 centerFrequency)
107 {
108  m_settings.m_centerFrequency = centerFrequency;
109  displaySettings();
110  sendSettings();
111 }
112 
114 {
115  return m_settings.serialize();
116 }
117 
118 bool Bladerf1OutputGui::deserialize(const QByteArray& data)
119 {
120  if(m_settings.deserialize(data)) {
121  displaySettings();
122  m_forceSettings = true;
123  sendSettings();
124  return true;
125  } else {
126  resetToDefaults();
127  return false;
128  }
129 }
130 
132 {
134  {
136  m_settings = cfg.getSettings();
137  blockApplySettings(true);
138  displaySettings();
139  blockApplySettings(false);
140  return true;
141  }
143  {
144  displaySettings();
145  return true;
146  }
147  else if (Bladerf1Output::MsgStartStop::match(message))
148  {
150  blockApplySettings(true);
151  ui->startStop->setChecked(notif.getStartStop());
152  blockApplySettings(false);
153  return true;
154  }
155  else
156  {
157  return false;
158  }
159 }
160 
162 {
163  Message* message;
164 
165  while ((message = m_inputMessageQueue.pop()) != 0)
166  {
167  qDebug("BladerfOutputGui::handleInputMessages: message: %s", message->getIdentifier());
168 
169  if (DSPSignalNotification::match(*message))
170  {
171  DSPSignalNotification* notif = (DSPSignalNotification*) message;
172  m_sampleRate = notif->getSampleRate();
174  qDebug("BladerfOutputGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency());
176 
177  delete message;
178  }
179  else
180  {
181  if (handleMessage(*message))
182  {
183  delete message;
184  }
185  }
186  }
187 }
188 
190 {
194 }
195 
197 {
198  ui->sampleRate->blockSignals(true);
199 
200  if (m_sampleRateMode)
201  {
202  ui->sampleRateMode->setStyleSheet("QToolButton { background:rgb(60,60,60); }");
203  ui->sampleRateMode->setText("SR");
204  ui->sampleRate->setValueRange(8, BLADERF_SAMPLERATE_MIN, BLADERF_SAMPLERATE_REC_MAX);
205  ui->sampleRate->setValue(m_settings.m_devSampleRate);
206  ui->sampleRate->setToolTip("Host to device sample rate (S/s)");
207  ui->deviceRateText->setToolTip("Baseband sample rate (S/s)");
208  uint32_t basebandSampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Interp);
209  ui->deviceRateText->setText(tr("%1k").arg(QString::number(basebandSampleRate / 1000.0f, 'g', 5)));
210  }
211  else
212  {
213  ui->sampleRateMode->setStyleSheet("QToolButton { background:rgb(50,50,50); }");
214  ui->sampleRateMode->setText("BB");
215  ui->sampleRate->setValueRange(8, BLADERF_SAMPLERATE_MIN/(1<<m_settings.m_log2Interp), BLADERF_SAMPLERATE_REC_MAX/(1<<m_settings.m_log2Interp));
216  ui->sampleRate->setValue(m_settings.m_devSampleRate/(1<<m_settings.m_log2Interp));
217  ui->sampleRate->setToolTip("Baseband sample rate (S/s)");
218  ui->deviceRateText->setToolTip("Host to device sample rate (S/s)");
219  ui->deviceRateText->setText(tr("%1k").arg(QString::number(m_settings.m_devSampleRate / 1000.0f, 'g', 5)));
220  }
221 
222  ui->sampleRate->blockSignals(false);
223 }
224 
226 {
227  ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000);
229 
230  unsigned int bandwidthIndex = BladerfBandwidths::getBandwidthIndex(m_settings.m_bandwidth);
231  ui->bandwidth->setCurrentIndex(bandwidthIndex);
232 
233  ui->interp->setCurrentIndex(m_settings.m_log2Interp);
234 
235  ui->vga1Text->setText(tr("%1dB").arg(m_settings.m_vga1));
236  ui->vga1->setValue(m_settings.m_vga1);
237 
238  ui->vga2Text->setText(tr("%1dB").arg(m_settings.m_vga2));
239  ui->vga2->setValue(m_settings.m_vga2);
240 
242 }
243 
245 {
246  if(!m_updateTimer.isActive())
247  m_updateTimer.start(100);
248 }
249 
251 {
252  m_settings.m_centerFrequency = value * 1000;
253  sendSettings();
254 }
255 
257 {
258  if (m_sampleRateMode) {
259  m_settings.m_devSampleRate = value;
260  } else {
262  }
263 
264  sendSettings();
265 }
266 
268 {
269  int newbw = BladerfBandwidths::getBandwidth(index);
270  m_settings.m_bandwidth = newbw * 1000;
271  sendSettings();
272 }
273 
275 {
276  if ((index <0) || (index > 6)) {
277  return;
278  }
279 
280  m_settings.m_log2Interp = index;
282 
283  if (m_sampleRateMode) {
284  m_settings.m_devSampleRate = ui->sampleRate->getValueNew();
285  } else {
286  m_settings.m_devSampleRate = ui->sampleRate->getValueNew() * (1 << m_settings.m_log2Interp);
287  }
288 
289  sendSettings();
290 }
291 
293 {
294  if ((value < BLADERF_TXVGA1_GAIN_MIN) || (value > BLADERF_TXVGA1_GAIN_MAX))
295  return;
296 
297  ui->vga1Text->setText(tr("%1dB").arg(value));
298  m_settings.m_vga1 = value;
299  sendSettings();
300 }
301 
303 {
304  if ((value < BLADERF_TXVGA2_GAIN_MIN) || (value > BLADERF_TXVGA2_GAIN_MAX))
305  return;
306 
307  ui->vga2Text->setText(tr("%1dB").arg(value));
308  m_settings.m_vga2 = value;
309  sendSettings();
310 }
311 
313 {
314  if (index == 1) // bypass
315  {
316  m_settings.m_xb200 = true;
317  m_settings.m_xb200Path = BLADERF_XB200_BYPASS;
318  }
319  else if (index == 2) // Auto 1dB
320  {
321  m_settings.m_xb200 = true;
322  m_settings.m_xb200Path = BLADERF_XB200_MIX;
323  m_settings.m_xb200Filter = BLADERF_XB200_AUTO_1DB;
324  }
325  else if (index == 3) // Auto 3dB
326  {
327  m_settings.m_xb200 = true;
328  m_settings.m_xb200Path = BLADERF_XB200_MIX;
329  m_settings.m_xb200Filter = BLADERF_XB200_AUTO_3DB;
330  }
331  else if (index == 4) // Custom
332  {
333  m_settings.m_xb200 = true;
334  m_settings.m_xb200Path = BLADERF_XB200_MIX;
335  m_settings.m_xb200Filter = BLADERF_XB200_CUSTOM;
336  }
337  else if (index == 5) // 50 MHz
338  {
339  m_settings.m_xb200 = true;
340  m_settings.m_xb200Path = BLADERF_XB200_MIX;
341  m_settings.m_xb200Filter = BLADERF_XB200_50M;
342  }
343  else if (index == 6) // 144 MHz
344  {
345  m_settings.m_xb200 = true;
346  m_settings.m_xb200Path = BLADERF_XB200_MIX;
347  m_settings.m_xb200Filter = BLADERF_XB200_144M;
348  }
349  else if (index == 7) // 222 MHz
350  {
351  m_settings.m_xb200 = true;
352  m_settings.m_xb200Path = BLADERF_XB200_MIX;
353  m_settings.m_xb200Filter = BLADERF_XB200_222M;
354  }
355  else // no xb200
356  {
357  m_settings.m_xb200 = false;
358  }
359 
360  if (m_settings.m_xb200)
361  {
362  ui->centerFrequency->setValueRange(7, BLADERF_FREQUENCY_MIN_XB200/1000, BLADERF_FREQUENCY_MAX/1000);
363  }
364  else
365  {
366  ui->centerFrequency->setValueRange(7, BLADERF_FREQUENCY_MIN/1000, BLADERF_FREQUENCY_MAX/1000);
367  }
368 
369  sendSettings();
370 }
371 
373 {
374  if (m_doApplySettings)
375  {
378  }
379 }
380 
382 {
383  m_sampleRateMode = checked;
385 }
386 
388 {
389  qDebug() << "BladerfGui::updateHardware";
392  m_forceSettings = false;
393  m_updateTimer.stop();
394 }
395 
397 {
398  int state = m_deviceUISet->m_deviceAPI->state();
399 
400  if(m_lastEngineState != state)
401  {
402  switch(state)
403  {
405  ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
406  break;
407  case DeviceAPI::StIdle:
408  ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
409  break;
411  ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
412  break;
413  case DeviceAPI::StError:
414  ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
415  QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage());
416  break;
417  default:
418  break;
419  }
420 
421  m_lastEngineState = state;
422  }
423 }
424 
425 unsigned int Bladerf1OutputGui::getXb200Index(bool xb_200, bladerf_xb200_path xb200Path, bladerf_xb200_filter xb200Filter)
426 {
427  if (xb_200)
428  {
429  if (xb200Path == BLADERF_XB200_BYPASS)
430  {
431  return 1;
432  }
433  else
434  {
435  if (xb200Filter == BLADERF_XB200_AUTO_1DB)
436  {
437  return 2;
438  }
439  else if (xb200Filter == BLADERF_XB200_AUTO_3DB)
440  {
441  return 3;
442  }
443  else if (xb200Filter == BLADERF_XB200_CUSTOM)
444  {
445  return 4;
446  }
447  else if (xb200Filter == BLADERF_XB200_50M)
448  {
449  return 5;
450  }
451  else if (xb200Filter == BLADERF_XB200_144M)
452  {
453  return 6;
454  }
455  else // xb200Filter == BLADERF_XB200_222M
456  {
457  return 7;
458  }
459  }
460  }
461  else
462  {
463  return 0;
464  }
465 }
466 
468 {
469  BasicDeviceSettingsDialog dialog(this);
474 
475  dialog.move(p);
476  dialog.exec();
477 
482 
483  sendSettings();
484 }
void openDeviceSettingsDialog(const QPoint &p)
virtual qint64 getCenterFrequency() const
Message * pop()
Pop message from queue.
const QString & getReverseAPIAddress() const
void push(Message *message, bool emitSignal=true)
Push message onto queue.
bool deserialize(const QByteArray &data)
void setSampleRate(qint32 sampleRate)
Definition: glspectrum.cpp:211
virtual void setCenterFrequency(qint64 centerFrequency)
void setUseReverseAPI(bool useReverseAPI)
bladerf_xb200_path m_xb200Path
void on_sampleRateMode_toggled(bool checked)
void setName(const QString &name)
void on_xb200_currentIndexChanged(int index)
QString errorMessage()
Last error message from the device engine.
Definition: deviceapi.cpp:290
DeviceSampleSink * getSampleSink()
Return pointer to the device sample sink (single Tx) or nullptr.
Definition: deviceapi.cpp:222
void on_interp_currentIndexChanged(int index)
bool m_sampleRateMode
true: device, false: base band sample rate update mode
static unsigned int getBandwidth(unsigned int bandwidth_index)
unsigned int uint32_t
Definition: rtptypes_win.h:46
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
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
const BladeRF1OutputSettings & getSettings() const
QString getName() const
DeviceAPI * m_deviceAPI
Definition: deviceuiset.h:48
engine is idle
Definition: deviceapi.h:54
MessageQueue * getInputMessageQueue()
void on_centerFrequency_changed(quint64 value)
BladeRF1OutputSettings m_settings
quint64 m_deviceCenterFrequency
Center frequency in device.
int32_t i
Definition: decimators.h:244
DeviceUISet * m_deviceUISet
static bool match(const Message *message)
Definition: message.cpp:45
bladerf_xb200_filter m_xb200Filter
void blockApplySettings(bool block)
Ui::Bladerf1OutputGui * ui
void on_startStop_toggled(bool checked)
virtual void destroy()
void on_sampleRate_changed(quint64 value)
static unsigned int getNbBandwidths()
static unsigned int getBandwidthIndex(unsigned int bandwidth)
void on_vga1_valueChanged(int value)
DeviceSampleSink * m_deviceSampleSink
int getSampleRate() const
Definition: dspcommands.h:328
void setCenterFrequency(qint64 frequency)
Definition: glspectrum.cpp:175
virtual const char * getIdentifier() const
Definition: message.cpp:35
void on_vga2_valueChanged(int value)
void setReverseAPIAddress(const QString &address)
void setReverseAPIDeviceIndex(uint16_t deviceIndex)
virtual bool handleMessage(const Message &message)
engine is running
Definition: deviceapi.h:56
QByteArray serialize() const
static MsgConfigureBladerf1 * create(const BladeRF1OutputSettings &settings, bool force)
Bladerf1OutputGui(DeviceUISet *deviceUISet, QWidget *parent=0)
bool deserialize(const QByteArray &data)
engine is in error
Definition: deviceapi.h:57
MessageQueue m_inputMessageQueue
unsigned int getXb200Index(bool xb_200, bladerf_xb200_path xb200Path, bladerf_xb200_filter xb200Filter)
void on_bandwidth_currentIndexChanged(int index)
static MsgStartStop * create(bool startStop)