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.
filesinkoutput.cpp
Go to the documentation of this file.
1 // Copyright (C) 2016 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 #include <QDebug>
21 
22 #include "SWGDeviceSettings.h"
23 #include "SWGDeviceState.h"
24 
25 #include "util/simpleserializer.h"
26 #include "dsp/dspcommands.h"
27 #include "dsp/dspengine.h"
28 #include "dsp/filerecord.h"
29 
30 #include "device/deviceapi.h"
31 
32 #include "filesinkoutput.h"
33 #include "filesinkthread.h"
34 
42 
44  m_deviceAPI(deviceAPI),
45  m_settings(),
46  m_fileSinkThread(0),
47  m_deviceDescription("FileSink"),
48  m_fileName("./test.sdriq"),
49  m_startingTimeStamp(0),
50  m_masterTimer(deviceAPI->getMasterTimer())
51 {
52  m_deviceAPI->setNbSinkStreams(1);
53 }
54 
56 {
57  stop();
58 }
59 
61 {
62  delete this;
63 }
64 
66 {
67  if (m_ofstream.is_open()) {
68  m_ofstream.close();
69  }
70 
71  m_ofstream.open(m_fileName.toStdString().c_str(), std::ios::binary);
72 
73  FileRecord::Header header;
74  int actualSampleRate = m_settings.m_sampleRate * (1<<m_settings.m_log2Interp);
75  header.sampleRate = actualSampleRate;
77  m_startingTimeStamp = time(0);
79  header.sampleSize = SDR_RX_SAMP_SZ;
80 
82 
83  qDebug() << "FileSinkOutput::openFileStream: " << m_fileName.toStdString().c_str();
84 }
85 
87 {
89 }
90 
92 {
93  QMutexLocker mutexLocker(&m_mutex);
94  qDebug() << "FileSinkOutput::start";
95 
97 
103 
104  mutexLocker.unlock();
105  //applySettings(m_generalSettings, m_settings, true);
106  qDebug("FileSinkOutput::start: started");
107 
108  if (getMessageQueueToGUI())
109  {
110  MsgReportFileSinkGeneration *report = MsgReportFileSinkGeneration::create(true); // acquisition on
111  getMessageQueueToGUI()->push(report);
112  }
113 
114  return true;
115 }
116 
118 {
119  qDebug() << "FileSourceInput::stop";
120  QMutexLocker mutexLocker(&m_mutex);
121 
122  if(m_fileSinkThread != 0)
123  {
125  delete m_fileSinkThread;
126  m_fileSinkThread = 0;
127  }
128 
129  if (m_ofstream.is_open()) {
130  m_ofstream.close();
131  }
132 
133  if (getMessageQueueToGUI())
134  {
135  MsgReportFileSinkGeneration *report = MsgReportFileSinkGeneration::create(false); // acquisition off
136  getMessageQueueToGUI()->push(report);
137  }
138 }
139 
140 QByteArray FileSinkOutput::serialize() const
141 {
142  return m_settings.serialize();
143 }
144 
145 bool FileSinkOutput::deserialize(const QByteArray& data)
146 {
147  bool success = true;
148 
149  if (!m_settings.deserialize(data))
150  {
152  success = false;
153  }
154 
156  m_inputMessageQueue.push(message);
157 
158  if (m_guiMessageQueue)
159  {
161  m_guiMessageQueue->push(messageToGUI);
162  }
163 
164  return success;
165 }
166 
168 {
169  return m_deviceDescription;
170 }
171 
173 {
174  return m_settings.m_sampleRate;
175 }
176 
178 {
180 }
181 
182 void FileSinkOutput::setCenterFrequency(qint64 centerFrequency)
183 {
184  FileSinkSettings settings = m_settings;
185  settings.m_centerFrequency = centerFrequency;
186 
187  MsgConfigureFileSink* message = MsgConfigureFileSink::create(settings, false);
188  m_inputMessageQueue.push(message);
189 
190  if (m_guiMessageQueue)
191  {
192  MsgConfigureFileSink* messageToGUI = MsgConfigureFileSink::create(settings, false);
193  m_guiMessageQueue->push(messageToGUI);
194  }
195 }
196 
198 {
199  return m_startingTimeStamp;
200 }
201 
203 {
204  if (MsgConfigureFileSinkName::match(message))
205  {
207  m_fileName = conf.getFileName();
208  openFileStream();
209  return true;
210  }
211  else if (MsgStartStop::match(message))
212  {
213  MsgStartStop& cmd = (MsgStartStop&) message;
214  qDebug() << "FileSinkOutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
215 
216  if (cmd.getStartStop())
217  {
219  {
221  }
222  }
223  else
224  {
226  }
227 
228  return true;
229  }
230  else if (MsgConfigureFileSink::match(message))
231  {
232  qDebug() << "FileSinkOutput::handleMessage: MsgConfigureFileSink";
233  MsgConfigureFileSink& conf = (MsgConfigureFileSink&) message;
234  applySettings(conf.getSettings(), conf.getForce());
235  return true;
236  }
237  else if (MsgConfigureFileSinkWork::match(message))
238  {
240  bool working = conf.isWorking();
241 
242  if (m_fileSinkThread != 0)
243  {
244  if (working)
245  {
247  }
248  else
249  {
251  }
252  }
253 
254  return true;
255  }
256  else if (MsgConfigureFileSinkStreamTiming::match(message))
257  {
259 
261  {
263  getMessageQueueToGUI()->push(report);
264  }
265 
266  return true;
267  }
268  else
269  {
270  return false;
271  }
272 }
273 
274 void FileSinkOutput::applySettings(const FileSinkSettings& settings, bool force)
275 {
276  QMutexLocker mutexLocker(&m_mutex);
277  bool forwardChange = false;
278 
279  if (force || (m_settings.m_centerFrequency != settings.m_centerFrequency))
280  {
282  forwardChange = true;
283  }
284 
285  if (force || (m_settings.m_sampleRate != settings.m_sampleRate))
286  {
288 
289  if (m_fileSinkThread != 0)
290  {
292  }
293 
294  forwardChange = true;
295  }
296 
297  if (force || (m_settings.m_log2Interp != settings.m_log2Interp))
298  {
300 
301  if (m_fileSinkThread != 0)
302  {
304  }
305 
306  forwardChange = true;
307  }
308 
309  if (forwardChange)
310  {
311  qDebug("FileSinkOutput::applySettings: forward: m_centerFrequency: %llu m_sampleRate: %llu m_log2Interp: %d",
317  }
318 
319 }
320 
322  SWGSDRangel::SWGDeviceState& response,
323  QString& errorMessage)
324 {
325  (void) errorMessage;
327  return 200;
328 }
329 
331  bool run,
332  SWGSDRangel::SWGDeviceState& response,
333  QString& errorMessage)
334 {
335  (void) errorMessage;
337  MsgStartStop *message = MsgStartStop::create(run);
338  m_inputMessageQueue.push(message);
339 
340  if (m_guiMessageQueue)
341  {
342  MsgStartStop *messagetoGui = MsgStartStop::create(run);
343  m_guiMessageQueue->push(messagetoGui);
344  }
345 
346  return 200;
347 }
348 
349 
virtual ~FileSinkOutput()
virtual int webapiRun(bool run, SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
bool startDeviceEngine()
Start the device engine corresponding to the stream type.
Definition: deviceapi.cpp:253
static MsgReportFileSinkStreamTiming * create(std::size_t samplesCount)
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
std::ofstream m_ofstream
bool deserialize(const QByteArray &data)
void writeHeader()
Definition: filerecord.cpp:155
virtual void destroy()
MessageQueue * getDeviceEngineInputMessageQueue()
Device engine message queue.
Definition: deviceapi.cpp:316
quint64 centerFrequency
Definition: filerecord.h:38
DeviceAPI * m_deviceAPI
void setLog2Interpolation(int log2Interpolation)
virtual const QString & getDeviceDescription() const
void applySettings(const FileSinkSettings &settings, bool force=false)
bool initDeviceEngine()
Init the device engine corresponding to the stream type.
Definition: deviceapi.cpp:240
virtual int getSampleRate() const
Sample rate exposed by the sink.
virtual void init()
initializations to be done when all collaborating objects are created and possibly connected ...
virtual bool handleMessage(const Message &message)
MessageQueue m_inputMessageQueue
Input queue to the sink.
#define SDR_RX_SAMP_SZ
Definition: dsptypes.h:32
static MsgStartStop * create(bool startStop)
virtual quint64 getCenterFrequency() const
Center frequency exposed by the sink.
const QTimer & m_masterTimer
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
Definition: message.h:52
virtual int webapiRunGet(SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
static bool match(const Message *message)
Definition: message.cpp:45
const FileSinkSettings & getSettings() const
virtual QByteArray serialize() const
void getDeviceEngineStateStr(QString &state)
Definition: deviceapi.cpp:389
virtual void setCenterFrequency(qint64 centerFrequency)
FileSinkSettings m_settings
std::size_t getSamplesCount() const
quint32 sampleRate
Definition: filerecord.h:37
quint32 sampleSize
Definition: filerecord.h:40
QByteArray serialize() const
SampleSourceFifo m_sampleSourceFifo
void connectTimer(const QTimer &timer)
static MsgReportFileSinkGeneration * create(bool acquisition)
virtual bool deserialize(const QByteArray &data)
virtual void stop()
std::time_t getStartingTimeStamp() const
quint64 startTimeStamp
Definition: filerecord.h:39
MessageQueue * getMessageQueueToGUI()
QString m_deviceDescription
FileSinkThread * m_fileSinkThread
std::time_t m_startingTimeStamp
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
void setSamplerate(int samplerate)
static MsgConfigureFileSink * create(const FileSinkSettings &settings, bool force)
virtual bool start()