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.
fileinput.cpp
Go to the documentation of this file.
1 // Copyright (C) 2015-2019 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 <string.h>
19 #include <errno.h>
20 
21 #include <QDebug>
22 #include <QNetworkReply>
23 #include <QBuffer>
24 
25 #include "SWGDeviceSettings.h"
26 #include "SWGFileInputSettings.h"
27 #include "SWGDeviceState.h"
28 #include "SWGDeviceReport.h"
29 
30 #include "util/simpleserializer.h"
31 #include "dsp/dspcommands.h"
33 #include "dsp/dspengine.h"
34 #include "dsp/filerecord.h"
35 #include "device/deviceapi.h"
36 
37 #include "fileinput.h"
38 #include "fileinputthread.h"
39 
51 
53  m_deviceAPI(deviceAPI),
54  m_settings(),
55  m_fileInputThread(nullptr),
56  m_deviceDescription(),
57  m_fileName("..."),
58  m_sampleRate(0),
59  m_sampleSize(0),
60  m_centerFrequency(0),
61  m_recordLength(0),
62  m_startingTimeStamp(0)
63 {
64  m_deviceAPI->setNbSourceStreams(1);
65  qDebug("FileInput::FileInput: device source engine: %p", m_deviceAPI->getDeviceSourceEngine());
66  qDebug("FileInput::FileInput: device source engine message queue: %p", m_deviceAPI->getDeviceEngineInputMessageQueue());
67  qDebug("FileInput::FileInput: device source: %p", m_deviceAPI->getDeviceSourceEngine()->getSource());
68  m_networkManager = new QNetworkAccessManager();
69  connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
70  m_masterTimer.setTimerType(Qt::PreciseTimer);
71  m_masterTimer.start(50);
72 }
73 
75 {
76  m_masterTimer.stop();
77  disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
78  delete m_networkManager;
79 
80  stop();
81 }
82 
84 {
85  delete this;
86 }
87 
89 {
90  //stopInput();
91 
92  if (m_ifstream.is_open()) {
93  m_ifstream.close();
94  }
95 
96 #ifdef Q_OS_WIN
97  m_ifstream.open(m_fileName.toStdWString().c_str(), std::ios::binary | std::ios::ate);
98 #else
99  m_ifstream.open(m_fileName.toStdString().c_str(), std::ios::binary | std::ios::ate);
100 #endif
101  quint64 fileSize = m_ifstream.tellg();
102 
103  if (fileSize > sizeof(FileRecord::Header))
104  {
105  FileRecord::Header header;
106  m_ifstream.seekg(0,std::ios_base::beg);
107  bool crcOK = FileRecord::readHeader(m_ifstream, header);
108  m_sampleRate = header.sampleRate;
111  m_sampleSize = header.sampleSize;
112  QString crcHex = QString("%1").arg(header.crc32 , 0, 16);
113 
114  if (crcOK)
115  {
116  qDebug("FileInput::openFileStream: CRC32 OK for header: %s", qPrintable(crcHex));
117  m_recordLength = (fileSize - sizeof(FileRecord::Header)) / ((m_sampleSize == 24 ? 8 : 4) * m_sampleRate);
118  }
119  else
120  {
121  qCritical("FileInput::openFileStream: bad CRC32 for header: %s", qPrintable(crcHex));
122  m_recordLength = 0;
123  }
124 
125  if (getMessageQueueToGUI()) {
127  getMessageQueueToGUI()->push(report);
128  }
129  }
130  else
131  {
132  m_recordLength = 0;
133  }
134 
135  qDebug() << "FileInput::openFileStream: " << m_fileName.toStdString().c_str()
136  << " fileSize: " << fileSize << " bytes"
137  << " length: " << m_recordLength << " seconds"
138  << " sample rate: " << m_sampleRate << " S/s"
139  << " center frequency: " << m_centerFrequency << " Hz"
140  << " sample size: " << m_sampleSize << " bits";
141 
142  if (getMessageQueueToGUI()) {
144  m_sampleSize,
147  m_recordLength); // file stream data
148  getMessageQueueToGUI()->push(report);
149  }
150 
151  if (m_recordLength == 0) {
152  m_ifstream.close();
153  }
154 }
155 
156 void FileInput::seekFileStream(int seekMillis)
157 {
158  QMutexLocker mutexLocker(&m_mutex);
159 
160  if ((m_ifstream.is_open()) && m_fileInputThread && !m_fileInputThread->isRunning())
161  {
162  quint64 seekPoint = ((m_recordLength * seekMillis) / 1000) * m_sampleRate;
164  seekPoint *= (m_sampleSize == 24 ? 8 : 4); // + sizeof(FileSink::Header)
165  m_ifstream.clear();
166  m_ifstream.seekg(seekPoint + sizeof(FileRecord::Header), std::ios::beg);
167  }
168 }
169 
171 {
174 }
175 
177 {
178  if (!m_ifstream.is_open())
179  {
180  qWarning("FileInput::start: file not open. not starting");
181  return false;
182  }
183 
184  QMutexLocker mutexLocker(&m_mutex);
185  qDebug() << "FileInput::start";
186 
187  if (m_ifstream.tellg() != (std::streampos)0) {
188  m_ifstream.clear();
189  m_ifstream.seekg(sizeof(FileRecord::Header), std::ios::beg);
190  }
191 
193  qCritical("Could not allocate SampleFifo");
194  return false;
195  }
196 
198  m_fileInputThread->setSampleRateAndSize(m_settings.m_accelerationFactor * m_sampleRate, m_sampleSize); // Fast Forward: 1 corresponds to live. 1/2 is half speed, 2 is double speed
200  m_deviceDescription = "FileInput";
201 
202  mutexLocker.unlock();
203  qDebug("FileInput::startInput: started");
204 
205  if (getMessageQueueToGUI()) {
207  getMessageQueueToGUI()->push(report);
208  }
209 
210  return true;
211 }
212 
214 {
215  qDebug() << "FileInput::stop";
216  QMutexLocker mutexLocker(&m_mutex);
217 
218  if (m_fileInputThread)
219  {
221  delete m_fileInputThread;
222  m_fileInputThread = nullptr;
223  }
224 
225  m_deviceDescription.clear();
226 
227  if (getMessageQueueToGUI()) {
229  getMessageQueueToGUI()->push(report);
230  }
231 }
232 
233 QByteArray FileInput::serialize() const
234 {
235  return m_settings.serialize();
236 }
237 
238 bool FileInput::deserialize(const QByteArray& data)
239 {
240  bool success = true;
241 
242  if (!m_settings.deserialize(data))
243  {
245  success = false;
246  }
247 
249  m_inputMessageQueue.push(message);
250 
251  if (getMessageQueueToGUI())
252  {
254  getMessageQueueToGUI()->push(messageToGUI);
255  }
256 
257  return success;
258 }
259 
260 const QString& FileInput::getDeviceDescription() const
261 {
262  return m_deviceDescription;
263 }
264 
266 {
267  return m_sampleRate;
268 }
269 
271 {
272  return m_centerFrequency;
273 }
274 
275 void FileInput::setCenterFrequency(qint64 centerFrequency)
276 {
277  FileInputSettings settings = m_settings;
278  settings.m_centerFrequency = centerFrequency;
279 
281  m_inputMessageQueue.push(message);
282 
283  if (getMessageQueueToGUI())
284  {
286  getMessageQueueToGUI()->push(messageToGUI);
287  }
288 }
289 
291 {
292  return m_startingTimeStamp;
293 }
294 
295 bool FileInput::handleMessage(const Message& message)
296 {
297  if (MsgConfigureFileInput::match(message))
298  {
299  MsgConfigureFileInput& conf = (MsgConfigureFileInput&) message;
300  FileInputSettings settings = conf.getSettings();
301  applySettings(settings);
302  return true;
303  }
304  else if (MsgConfigureFileSourceName::match(message))
305  {
307  m_fileName = conf.getFileName();
308  openFileStream();
309  return true;
310  }
311  else if (MsgConfigureFileInputWork::match(message))
312  {
314  bool working = conf.isWorking();
315 
316  if (m_fileInputThread != 0)
317  {
318  if (working) {
320  } else {
322  }
323  }
324 
325  return true;
326  }
327  else if (MsgConfigureFileSourceSeek::match(message))
328  {
330  int seekMillis = conf.getMillis();
331  seekFileStream(seekMillis);
332 
333  return true;
334  }
336  {
338 
339  if (m_fileInputThread != 0)
340  {
341  if (getMessageQueueToGUI())
342  {
344  getMessageQueueToGUI()->push(report);
345  }
346  }
347 
348  return true;
349  }
350  else if (MsgStartStop::match(message))
351  {
352  MsgStartStop& cmd = (MsgStartStop&) message;
353  qDebug() << "FileInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
354 
355  if (cmd.getStartStop())
356  {
358  {
360  }
361  }
362  else
363  {
365  }
366 
369  }
370 
371  return true;
372  }
373  else if (FileInputThread::MsgReportEOF::match(message))
374  {
375  qDebug() << "FileInput::handleMessage: MsgReportEOF";
377 
378  if (getMessageQueueToGUI())
379  {
381  getMessageQueueToGUI()->push(report);
382  }
383 
384  if (m_settings.m_loop)
385  {
386  seekFileStream(0);
388  }
389  else
390  {
391  if (getMessageQueueToGUI())
392  {
393  MsgPlayPause *report = MsgPlayPause::create(false);
394  getMessageQueueToGUI()->push(report);
395  }
396  }
397 
398  return true;
399  }
400  else
401  {
402  return false;
403  }
404 }
405 
406 bool FileInput::applySettings(const FileInputSettings& settings, bool force)
407 {
408  QList<QString> reverseAPIKeys;
409 
410  if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
412  }
413 
414  if ((m_settings.m_accelerationFactor != settings.m_accelerationFactor) || force)
415  {
416  reverseAPIKeys.append("accelerationFactor");
417 
418  if (m_fileInputThread)
419  {
420  QMutexLocker mutexLocker(&m_mutex);
422  qCritical("FileInput::applySettings: could not reallocate sample FIFO size to %lu",
424  }
425  m_fileInputThread->setSampleRateAndSize(settings.m_accelerationFactor * m_sampleRate, m_sampleSize); // Fast Forward: 1 corresponds to live. 1/2 is half speed, 2 is double speed
426  }
427  }
428 
429  if ((m_settings.m_loop != settings.m_loop)) {
430  reverseAPIKeys.append("loop");
431  }
432  if ((m_settings.m_fileName != settings.m_fileName)) {
433  reverseAPIKeys.append("fileName");
434  }
435 
436  if (settings.m_useReverseAPI)
437  {
438  bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
442  webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
443  }
444 
445  m_settings = settings;
446  return true;
447 }
448 
451  QString& errorMessage)
452 {
453  (void) errorMessage;
455  response.getFileInputSettings()->init();
457  return 200;
458 }
459 
461  bool force,
462  const QStringList& deviceSettingsKeys,
463  SWGSDRangel::SWGDeviceSettings& response, // query + response
464  QString& errorMessage)
465 {
466  (void) errorMessage;
467  FileInputSettings settings = m_settings;
468 
469  if (deviceSettingsKeys.contains("fileName")) {
470  settings.m_fileName = *response.getFileInputSettings()->getFileName();
471  }
472  if (deviceSettingsKeys.contains("accelerationFactor")) {
474  }
475  if (deviceSettingsKeys.contains("loop")) {
476  settings.m_loop = response.getFileInputSettings()->getLoop() != 0;
477  }
478  if (deviceSettingsKeys.contains("useReverseAPI")) {
479  settings.m_useReverseAPI = response.getFileInputSettings()->getUseReverseApi() != 0;
480  }
481  if (deviceSettingsKeys.contains("reverseAPIAddress")) {
483  }
484  if (deviceSettingsKeys.contains("reverseAPIPort")) {
486  }
487  if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
489  }
490 
493 
494  if (m_guiMessageQueue) // forward to GUI if any
495  {
496  MsgConfigureFileInput *msgToGUI = MsgConfigureFileInput::create(settings, force);
497  m_guiMessageQueue->push(msgToGUI);
498  }
499 
500  webapiFormatDeviceSettings(response, settings);
501  return 200;
502 }
503 
505  SWGSDRangel::SWGDeviceState& response,
506  QString& errorMessage)
507 {
508  (void) errorMessage;
510  return 200;
511 }
512 
514  bool run,
515  SWGSDRangel::SWGDeviceState& response,
516  QString& errorMessage)
517 {
518  (void) errorMessage;
520  MsgStartStop *message = MsgStartStop::create(run);
521  m_inputMessageQueue.push(message);
522 
523  if (getMessageQueueToGUI()) // forward to GUI if any
524  {
525  MsgStartStop *msgToGUI = MsgStartStop::create(run);
526  getMessageQueueToGUI()->push(msgToGUI);
527  }
528 
529  return 200;
530 }
531 
534  QString& errorMessage)
535 {
536  (void) errorMessage;
538  response.getFileInputReport()->init();
539  webapiFormatDeviceReport(response);
540  return 200;
541 }
542 
544 {
545  response.getFileInputSettings()->setFileName(new QString(settings.m_fileName));
547  response.getFileInputSettings()->setLoop(settings.m_loop ? 1 : 0);
548 
549  response.getFileInputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
550 
551  if (response.getFileInputSettings()->getReverseApiAddress()) {
553  } else {
554  response.getFileInputSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
555  }
556 
559 }
560 
562 {
563  qint64 t_sec = 0;
564  qint64 t_msec = 0;
565  quint64 samplesCount = 0;
566 
567  if (m_fileInputThread) {
568  samplesCount = m_fileInputThread->getSamplesCount();
569  }
570 
571  if (m_sampleRate > 0)
572  {
573  t_sec = samplesCount / m_sampleRate;
574  t_msec = (samplesCount - (t_sec * m_sampleRate)) * 1000 / m_sampleRate;
575  }
576 
577  QTime t(0, 0, 0, 0);
578  t = t.addSecs(t_sec);
579  t = t.addMSecs(t_msec);
580  response.getFileInputReport()->setElapsedTime(new QString(t.toString("HH:mm:ss.zzz")));
581 
582  qint64 startingTimeStampMsec = m_startingTimeStamp * 1000LL;
583  QDateTime dt = QDateTime::fromMSecsSinceEpoch(startingTimeStampMsec);
584  dt = dt.addSecs(t_sec);
585  dt = dt.addMSecs(t_msec);
586  response.getFileInputReport()->setAbsoluteTime(new QString(dt.toString("yyyy-MM-dd HH:mm:ss.zzz")));
587 
588  QTime recordLength(0, 0, 0, 0);
589  recordLength = recordLength.addSecs(m_recordLength);
590  response.getFileInputReport()->setDurationTime(new QString(recordLength.toString("HH:mm:ss")));
591 
592  response.getFileInputReport()->setFileName(new QString(m_fileName));
595 }
596 
597 void FileInput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const FileInputSettings& settings, bool force)
598 {
600  swgDeviceSettings->setDirection(0); // single Rx
601  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
602  swgDeviceSettings->setDeviceHwType(new QString("FileInput"));
604  SWGSDRangel::SWGFileInputSettings *swgFileInputSettings = swgDeviceSettings->getFileInputSettings();
605 
606  // transfer data that has been modified. When force is on transfer all data except reverse API data
607 
608  if (deviceSettingsKeys.contains("accelerationFactor") || force) {
609  swgFileInputSettings->setAccelerationFactor(settings.m_accelerationFactor);
610  }
611  if (deviceSettingsKeys.contains("loop") || force) {
612  swgFileInputSettings->setLoop(settings.m_loop);
613  }
614  if (deviceSettingsKeys.contains("fileName") || force) {
615  swgFileInputSettings->setFileName(new QString(settings.m_fileName));
616  }
617 
618  QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings")
619  .arg(settings.m_reverseAPIAddress)
620  .arg(settings.m_reverseAPIPort)
621  .arg(settings.m_reverseAPIDeviceIndex);
622  m_networkRequest.setUrl(QUrl(deviceSettingsURL));
623  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
624 
625  QBuffer *buffer=new QBuffer();
626  buffer->open((QBuffer::ReadWrite));
627  buffer->write(swgDeviceSettings->asJson().toUtf8());
628  buffer->seek(0);
629 
630  // Always use PATCH to avoid passing reverse API settings
631  m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
632 
633  delete swgDeviceSettings;
634 }
635 
637 {
639  swgDeviceSettings->setDirection(0); // single Rx
640  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
641  swgDeviceSettings->setDeviceHwType(new QString("FileInput"));
642 
643  QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/run")
647  m_networkRequest.setUrl(QUrl(deviceSettingsURL));
648  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
649 
650  QBuffer *buffer=new QBuffer();
651  buffer->open((QBuffer::ReadWrite));
652  buffer->write(swgDeviceSettings->asJson().toUtf8());
653  buffer->seek(0);
654 
655  if (start) {
656  m_networkManager->sendCustomRequest(m_networkRequest, "POST", buffer);
657  } else {
658  m_networkManager->sendCustomRequest(m_networkRequest, "DELETE", buffer);
659  }
660 
661  delete swgDeviceSettings;
662 }
663 
664 void FileInput::networkManagerFinished(QNetworkReply *reply)
665 {
666  QNetworkReply::NetworkError replyError = reply->error();
667 
668  if (replyError)
669  {
670  qWarning() << "FileInput::networkManagerFinished:"
671  << " error(" << (int) replyError
672  << "): " << replyError
673  << ": " << reply->errorString();
674  return;
675  }
676 
677  QString answer = reply->readAll();
678  answer.chop(1); // remove last \n
679  qDebug("FileInput::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
680 }
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const FileInputSettings &settings)
Definition: fileinput.cpp:543
void setFileName(QString *file_name)
virtual bool handleMessage(const Message &message)
Definition: fileinput.cpp:295
bool startDeviceEngine()
Start the device engine corresponding to the stream type.
Definition: deviceapi.cpp:253
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
virtual void setCenterFrequency(qint64 centerFrequency)
Definition: fileinput.cpp:275
SWGFileInputReport * getFileInputReport()
virtual bool deserialize(const QByteArray &data)
Definition: fileinput.cpp:238
void setAbsoluteTime(QString *absolute_time)
QString m_deviceDescription
Definition: fileinput.h:328
std::ifstream m_ifstream
Definition: fileinput.h:326
DeviceAPI * m_deviceAPI
Definition: fileinput.h:323
void setSampleRate(qint32 sample_rate)
virtual quint64 getCenterFrequency() const
Center frequency exposed by the source.
Definition: fileinput.cpp:270
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void stopDeviceEngine()
Stop the device engine corresponding to the stream type.
Definition: deviceapi.cpp:266
virtual int webapiRun(bool run, SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
Definition: fileinput.cpp:513
MessageQueue m_inputMessageQueue
Input queue to the source.
virtual QString asJson() override
MessageQueue * getDeviceEngineInputMessageQueue()
Device engine message queue.
Definition: deviceapi.cpp:316
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport &response)
Definition: fileinput.cpp:561
quint64 centerFrequency
Definition: filerecord.h:38
bool initDeviceEngine()
Init the device engine corresponding to the stream type.
Definition: deviceapi.cpp:240
uint16_t m_reverseAPIDeviceIndex
QTimer m_masterTimer
Definition: fileinput.h:335
void openFileStream()
Definition: fileinput.cpp:88
virtual bool start()
Definition: fileinput.cpp:176
bool deserialize(const QByteArray &data)
const QString & getFileName() const
Definition: fileinput.h:68
void setOriginatorIndex(qint32 originator_index)
static MsgReportFileInputStreamTiming * create(quint64 samplesCount)
Definition: fileinput.h:245
void webapiReverseSendStartStop(bool start)
Definition: fileinput.cpp:636
SampleSinkFifo m_sampleFifo
bool setSize(int size)
quint64 getSamplesCount() const
MessageQueue * getMessageQueueToGUI()
quint64 m_startingTimeStamp
Definition: fileinput.h:334
int getDeviceSetIndex() const
Definition: deviceapi.h:131
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
Definition: message.h:52
virtual void destroy()
Definition: fileinput.cpp:83
static MsgConfigureFileInput * create(const FileInputSettings &settings, bool force)
Definition: fileinput.h:48
void setFileInputSettings(SWGFileInputSettings *file_input_settings)
QByteArray serialize() const
virtual ~FileInput()
Definition: fileinput.cpp:74
static bool match(const Message *message)
Definition: message.cpp:45
virtual int webapiRunGet(SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
Definition: fileinput.cpp:504
static MsgPlayPause * create(bool playPause)
Definition: fileinput.h:186
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
virtual void stop()
Definition: fileinput.cpp:213
virtual const QString & getDeviceDescription() const
Definition: fileinput.cpp:260
void setDurationTime(QString *duration_time)
virtual int getSampleRate() const
Sample rate exposed by the source.
Definition: fileinput.cpp:265
void setFileInputReport(SWGFileInputReport *file_input_report)
virtual int webapiSettingsGet(SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
Definition: fileinput.cpp:449
void setElapsedTime(QString *elapsed_time)
const FileInputSettings & getSettings() const
Definition: fileinput.h:45
static MsgReportHeaderCRC * create(bool ok)
Definition: fileinput.h:265
bool getStartStop() const
Definition: fileinput.h:165
int m_sampleRate
Definition: fileinput.h:330
virtual int webapiSettingsPutPatch(bool force, const QStringList &deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
Definition: fileinput.cpp:460
void getDeviceEngineStateStr(QString &state)
Definition: deviceapi.cpp:389
virtual void init()
initializations to be done when all collaborating objects are created and possibly connected ...
Definition: fileinput.cpp:170
FileInputSettings m_settings
Definition: fileinput.h:325
virtual QByteArray serialize() const
Definition: fileinput.cpp:233
bool isRunning() const
quint32 sampleRate
Definition: filerecord.h:37
QMutex m_mutex
Definition: fileinput.h:324
void setSampleRateAndSize(int samplerate, quint32 samplesize)
void setAccelerationFactor(qint32 acceleration_factor)
SWGFileInputSettings * getFileInputSettings()
virtual int webapiReportGet(SWGSDRangel::SWGDeviceReport &response, QString &errorMessage)
Definition: fileinput.cpp:532
quint32 sampleSize
Definition: filerecord.h:40
FileInputThread * m_fileInputThread
Definition: fileinput.h:327
QNetworkRequest m_networkRequest
Definition: fileinput.h:337
void seekFileStream(int seekMillis)
Definition: fileinput.cpp:156
quint64 m_centerFrequency
Definition: fileinput.h:332
void setSampleSize(qint32 sample_size)
quint64 getStartingTimeStamp() const
Definition: fileinput.cpp:290
quint64 m_recordLength
record length in seconds computed from file size
Definition: fileinput.h:333
void setReverseApiPort(qint32 reverse_api_port)
quint32 m_sampleSize
Definition: fileinput.h:331
void networkManagerFinished(QNetworkReply *reply)
Definition: fileinput.cpp:664
static bool readHeader(std::ifstream &samplefile, Header &header)
returns true if CRC checksum is correct else false
Definition: filerecord.cpp:168
void setReverseApiAddress(QString *reverse_api_address)
static MsgReportFileSourceAcquisition * create(bool acquisition)
Definition: fileinput.h:147
quint64 startTimeStamp
Definition: filerecord.h:39
void setDirection(qint32 direction)
static MsgReportFileInputStreamData * create(int sampleRate, quint32 sampleSize, quint64 centerFrequency, quint64 startingTimeStamp, quint64 recordLength)
Definition: fileinput.h:209
QString m_fileName
Definition: fileinput.h:329
bool applySettings(const FileInputSettings &settings, bool force=false)
Definition: fileinput.cpp:406
void setUseReverseApi(qint32 use_reverse_api)
static MsgStartStop * create(bool startStop)
Definition: fileinput.h:167
void setDeviceHwType(QString *device_hw_type)
void setSamplesCount(quint64 samplesCount)
QNetworkAccessManager * m_networkManager
Definition: fileinput.h:336
void webapiReverseSendSettings(QList< QString > &deviceSettingsKeys, const FileInputSettings &settings, bool force)
Definition: fileinput.cpp:597