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.
fileinputgui.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 
20 #include <QTime>
21 #include <QDateTime>
22 #include <QString>
23 #include <QFileDialog>
24 #include <QMessageBox>
25 
26 #include "ui_fileinputgui.h"
27 #include "plugin/pluginapi.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 #include "mainwindow.h"
36 
37 #include "fileinputgui.h"
38 #include "device/deviceapi.h"
39 #include "device/deviceuiset.h"
40 
41 FileInputGUI::FileInputGUI(DeviceUISet *deviceUISet, QWidget* parent) :
42  QWidget(parent),
43  ui(new Ui::FileInputGUI),
44  m_deviceUISet(deviceUISet),
45  m_settings(),
46  m_doApplySettings(true),
47  m_sampleSource(0),
48  m_acquisition(false),
49  m_fileName("..."),
50  m_sampleRate(0),
51  m_centerFrequency(0),
52  m_recordLength(0),
53  m_startingTimeStamp(0),
54  m_samplesCount(0),
55  m_tickCount(0),
56  m_enableNavTime(false),
57  m_lastEngineState(DeviceAPI::StNotStarted)
58 {
59  ui->setupUi(this);
60  ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
61  ui->centerFrequency->setValueRange(7, 0, pow(10,7));
62  ui->fileNameText->setText(m_fileName);
63  ui->crcLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }");
64 
65  connect(&(m_deviceUISet->m_deviceAPI->getMasterTimer()), SIGNAL(timeout()), this, SLOT(tick()));
66  connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
67  m_statusTimer.start(500);
68 
69  CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStop);
70  connect(startStopRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
71 
74 
75  ui->navTimeSlider->setEnabled(false);
76  ui->acceleration->setEnabled(false);
77 
79 
80  connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
82 }
83 
85 {
86  delete ui;
87 }
88 
90 {
91  delete this;
92 }
93 
94 void FileInputGUI::setName(const QString& name)
95 {
96  setObjectName(name);
97 }
98 
99 QString FileInputGUI::getName() const
100 {
101  return objectName();
102 }
103 
105 {
107  displaySettings();
108  sendSettings();
109 }
110 
112 {
113  return m_centerFrequency;
114 }
115 
116 void FileInputGUI::setCenterFrequency(qint64 centerFrequency)
117 {
118  m_centerFrequency = centerFrequency;
119  displaySettings();
120  sendSettings();
121 }
122 
123 QByteArray FileInputGUI::serialize() const
124 {
125  return m_settings.serialize();
126 }
127 
128 bool FileInputGUI::deserialize(const QByteArray& data)
129 {
130  if(m_settings.deserialize(data)) {
131  displaySettings();
132  sendSettings();
133  return true;
134  } else {
135  resetToDefaults();
136  return false;
137  }
138 }
139 
141 {
142  Message* message;
143 
144  while ((message = m_inputMessageQueue.pop()) != 0)
145  {
146  if (DSPSignalNotification::match(*message))
147  {
148  DSPSignalNotification* notif = (DSPSignalNotification*) message;
151  qDebug("FileInputGUI::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency());
153 
154  delete message;
155  }
156  else
157  {
158  if (handleMessage(*message))
159  {
160  delete message;
161  }
162  }
163  }
164 }
165 
167 {
169  {
171  m_settings = cfg.getSettings();
172  displaySettings();
173  return true;
174  }
176  {
177  m_acquisition = ((FileInput::MsgReportFileSourceAcquisition&)message).getAcquisition();
179  return true;
180  }
182  {
183  m_sampleRate = ((FileInput::MsgReportFileInputStreamData&)message).getSampleRate();
184  m_sampleSize = ((FileInput::MsgReportFileInputStreamData&)message).getSampleSize();
185  m_centerFrequency = ((FileInput::MsgReportFileInputStreamData&)message).getCenterFrequency();
186  m_startingTimeStamp = ((FileInput::MsgReportFileInputStreamData&)message).getStartingTimeStamp();
187  m_recordLength = ((FileInput::MsgReportFileInputStreamData&)message).getRecordLength();
189  return true;
190  }
192  {
193  m_samplesCount = ((FileInput::MsgReportFileInputStreamTiming&)message).getSamplesCount();
195  return true;
196  }
197  else if (FileInput::MsgStartStop::match(message))
198  {
200  blockApplySettings(true);
201  ui->startStop->setChecked(notif.getStartStop());
202  blockApplySettings(false);
203 
204  return true;
205  }
206  else if (FileInput::MsgPlayPause::match(message))
207  {
209  bool checked = notif.getPlayPause();
210  ui->play->setChecked(checked);
211  ui->navTimeSlider->setEnabled(!checked);
212  ui->acceleration->setEnabled(!checked);
213  m_enableNavTime = !checked;
214 
215  return true;
216  }
217  else if (FileInput::MsgReportHeaderCRC::match(message))
218  {
220  if (notif.isOK()) {
221  ui->crcLabel->setStyleSheet("QLabel { background-color : green; }");
222  } else {
223  ui->crcLabel->setStyleSheet("QLabel { background-color : red; }");
224  }
225 
226  return true;
227  }
228  else
229  {
230  return false;
231  }
232 }
233 
235 {
238  ui->deviceRateText->setText(tr("%1k").arg((float)m_deviceSampleRate / 1000));
239 }
240 
242 {
243  blockApplySettings(true);
244  ui->playLoop->setChecked(m_settings.m_loop);
246  blockApplySettings(false);
247 }
248 
250 {
251 }
252 
254 {
255  if (m_doApplySettings)
256  {
257  m_settings.m_loop = checked;
260  }
261 }
262 
264 {
265  if (m_doApplySettings)
266  {
269  }
270 }
271 
273 {
274  int state = m_deviceUISet->m_deviceAPI->state();
275 
276  if(m_lastEngineState != state)
277  {
278  switch(state)
279  {
281  ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
282  break;
283  case DeviceAPI::StIdle:
284  ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
285  break;
287  ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
288  break;
289  case DeviceAPI::StError:
290  ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
291  QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage());
292  break;
293  default:
294  break;
295  }
296 
297  m_lastEngineState = state;
298  }
299 }
300 
302 {
305  ui->navTimeSlider->setEnabled(!checked);
306  ui->acceleration->setEnabled(!checked);
307  m_enableNavTime = !checked;
308 }
309 
311 {
312  if (m_enableNavTime && ((value >= 0) && (value <= 1000)))
313  {
316  }
317 }
318 
320 {
321  (void) checked;
322  QString fileName = QFileDialog::getOpenFileName(this,
323  tr("Open I/Q record file"), ".", tr("SDR I/Q Files (*.sdriq)"), 0, QFileDialog::DontUseNativeDialog);
324 
325  if (fileName != "")
326  {
327  m_fileName = fileName;
328  ui->fileNameText->setText(m_fileName);
329  ui->crcLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }");
331  }
332 }
333 
335 {
336  if (m_doApplySettings)
337  {
341  }
342 }
343 
345 {
346  qDebug() << "FileInputGUI::configureFileName: " << m_fileName.toStdString().c_str();
349 }
350 
352 {
353  ui->play->setEnabled(m_acquisition);
354  ui->play->setChecked(m_acquisition);
355  ui->showFileDialog->setEnabled(!m_acquisition);
356 }
357 
359 {
360  ui->centerFrequency->setValue(m_centerFrequency/1000);
361  ui->sampleRateText->setText(tr("%1k").arg((float)m_sampleRate / 1000));
362  ui->sampleSizeText->setText(tr("%1b").arg(m_sampleSize));
363  ui->play->setEnabled(m_acquisition);
364  QTime recordLength(0, 0, 0, 0);
365  recordLength = recordLength.addSecs(m_recordLength);
366  QString s_time = recordLength.toString("HH:mm:ss");
367  ui->recordLengthText->setText(s_time);
369 }
370 
372 {
373  qint64 t_sec = 0;
374  qint64 t_msec = 0;
375 
376  if (m_sampleRate > 0){
377  t_sec = m_samplesCount / m_sampleRate;
378  t_msec = (m_samplesCount - (t_sec * m_sampleRate)) * 1000LL / m_sampleRate;
379  }
380 
381  QTime t(0, 0, 0, 0);
382  t = t.addSecs(t_sec);
383  t = t.addMSecs(t_msec);
384  QString s_timems = t.toString("HH:mm:ss.zzz");
385  ui->relTimeText->setText(s_timems);
386 
387  qint64 startingTimeStampMsec = m_startingTimeStamp * 1000LL;
388  QDateTime dt = QDateTime::fromMSecsSinceEpoch(startingTimeStampMsec);
389  dt = dt.addSecs(t_sec);
390  dt = dt.addMSecs(t_msec);
391  QString s_date = dt.toString("yyyy-MM-dd HH:mm:ss.zzz");
392  ui->absTimeText->setText(s_date);
393 
394  if (!m_enableNavTime)
395  {
396  float posRatio = (float) t_sec / (float) m_recordLength;
397  ui->navTimeSlider->setValue((int) (posRatio * 1000.0));
398  }
399 }
400 
402 {
403  if ((++m_tickCount & 0xf) == 0) {
406  }
407 }
408 
410 {
411  ui->acceleration->blockSignals(true);
412  ui->acceleration->clear();
413  ui->acceleration->addItem(QString("1"));
414 
415  for (unsigned int i = 0; i <= FileInputSettings::m_accelerationMaxScale; i++)
416  {
417  QString s;
418  int m = pow(10.0, i);
419  int x = 2*m;
420  setNumberStr(x, s);
421  ui->acceleration->addItem(s);
422  x = 5*m;
423  setNumberStr(x, s);
424  ui->acceleration->addItem(s);
425  x = 10*m;
426  setNumberStr(x, s);
427  ui->acceleration->addItem(s);
428  }
429 
430  ui->acceleration->blockSignals(false);
431 }
432 
433 void FileInputGUI::setNumberStr(int n, QString& s)
434 {
435  if (n < 1000) {
436  s = tr("%1").arg(n);
437  } else if (n < 100000) {
438  s = tr("%1k").arg(n/1000);
439  } else if (n < 1000000) {
440  s = tr("%1e5").arg(n/100000);
441  } else if (n < 1000000000) {
442  s = tr("%1M").arg(n/1000000);
443  } else {
444  s = tr("%1G").arg(n/1000000000);
445  }
446 }
447 
449 {
450  BasicDeviceSettingsDialog dialog(this);
455 
456  dialog.move(p);
457  dialog.exec();
458 
463 
464  sendSettings();
465 }
quint64 m_centerFrequency
Definition: fileinputgui.h:68
void on_acceleration_currentIndexChanged(int index)
Message * pop()
Pop message from queue.
const QString & getReverseAPIAddress() const
void on_playLoop_toggled(bool checked)
void blockApplySettings(bool block)
Definition: fileinputgui.h:79
static MsgConfigureFileInputStreamTiming * create()
Definition: fileinput.h:109
bool m_doApplySettings
Definition: fileinputgui.h:60
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void setSampleRate(qint32 sampleRate)
Definition: glspectrum.cpp:211
void configureFileName()
FileInputSettings m_settings
Definition: fileinputgui.h:59
DeviceSampleSource * getSampleSource()
Return pointer to the device sample source (single Rx) or nullptr.
Definition: deviceapi.cpp:213
void setUseReverseAPI(bool useReverseAPI)
MessageQueue * getInputMessageQueue()
int m_lastEngineState
Definition: fileinputgui.h:76
quint64 m_startingTimeStamp
Definition: fileinputgui.h:70
virtual ~FileInputGUI()
const QTimer & getMasterTimer() const
This is the DSPEngine master timer.
Definition: deviceapi.h:173
quint32 m_sampleSize
Definition: fileinputgui.h:67
DeviceUISet * m_deviceUISet
Definition: fileinputgui.h:58
uint16_t m_reverseAPIDeviceIndex
std::size_t m_tickCount
Definition: fileinputgui.h:72
bool deserialize(const QByteArray &data)
static MsgConfigureFileInputWork * create(bool working)
Definition: fileinput.h:90
QString errorMessage()
Last error message from the device engine.
Definition: deviceapi.cpp:290
QByteArray serialize() const
int m_deviceSampleRate
Definition: fileinputgui.h:74
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
Ui::FileInputGUI * ui
Definition: fileinputgui.h:56
GLSpectrum * getSpectrum()
Direct spectrum getter.
Definition: deviceuiset.h:57
engine is before initialization
Definition: deviceapi.h:53
void updateWithStreamTime()
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
DeviceAPI * m_deviceAPI
Definition: deviceuiset.h:48
void updateSampleRateAndFrequency()
engine is idle
Definition: deviceapi.h:54
quint64 m_samplesCount
Definition: fileinputgui.h:71
static MsgConfigureFileInput * create(const FileInputSettings &settings, bool force)
Definition: fileinput.h:48
QString m_fileName
Definition: fileinputgui.h:65
MessageQueue m_inputMessageQueue
Definition: fileinputgui.h:77
void setAccelerationCombo()
QByteArray serialize() const
void on_startStop_toggled(bool checked)
void on_play_toggled(bool checked)
int32_t i
Definition: decimators.h:244
virtual void destroy()
void updateWithStreamData()
static int getAccelerationIndex(int averaging)
static bool match(const Message *message)
Definition: message.cpp:45
void setNumberStr(int n, QString &s)
void handleInputMessages()
static int getAccelerationValue(int averagingIndex)
QString getName() const
static MsgConfigureFileSourceName * create(const QString &fileName)
Definition: fileinput.h:70
virtual qint64 getCenterFrequency() const
QTimer m_statusTimer
Definition: fileinputgui.h:61
const FileInputSettings & getSettings() const
Definition: fileinput.h:45
bool getStartStop() const
Definition: fileinput.h:165
void openDeviceSettingsDialog(const QPoint &p)
void displaySettings()
void updateWithAcquisition()
quint64 m_deviceCenterFrequency
Center frequency in device.
Definition: fileinputgui.h:75
void on_showFileDialog_clicked(bool checked)
void resetToDefaults()
void updateStatus()
int getSampleRate() const
Definition: dspcommands.h:328
FileInputGUI(DeviceUISet *deviceUISet, QWidget *parent=0)
bool m_acquisition
Definition: fileinputgui.h:64
void setName(const QString &name)
void setCenterFrequency(qint64 frequency)
Definition: glspectrum.cpp:175
void setReverseAPIAddress(const QString &address)
static const unsigned int m_accelerationMaxScale
Max power of 10 multiplier to 2,5,10 base ex: 2 -> 2,5,10,20,50,100,200,500,1000. ...
void setReverseAPIDeviceIndex(uint16_t deviceIndex)
quint64 m_recordLength
Definition: fileinputgui.h:69
virtual void setMessageQueueToGUI(MessageQueue *queue)=0
engine is running
Definition: deviceapi.h:56
static MsgConfigureFileSourceSeek * create(int seekMillis)
Definition: fileinput.h:127
virtual void setCenterFrequency(qint64 centerFrequency)
DeviceSampleSource * m_sampleSource
Definition: fileinputgui.h:63
bool deserialize(const QByteArray &data)
bool m_enableNavTime
Definition: fileinputgui.h:73
bool getPlayPause() const
Definition: fileinput.h:184
void on_navTimeSlider_valueChanged(int value)
void sendSettings()
engine is in error
Definition: deviceapi.h:57
static MsgStartStop * create(bool startStop)
Definition: fileinput.h:167
virtual bool handleMessage(const Message &message)