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.
filerecord.cpp
Go to the documentation of this file.
1 // Copyright (C) 2015-2018 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 <boost/crc.hpp>
19 #include <boost/cstdint.hpp>
20 
21 #include <QDebug>
22 #include <QDateTime>
23 
24 #include "dsp/dspcommands.h"
25 #include "util/simpleserializer.h"
26 #include "util/message.h"
27 
28 #include "filerecord.h"
29 
32  m_fileName("test.sdriq"),
33  m_sampleRate(0),
34  m_centerFrequency(0),
35  m_recordOn(false),
36  m_recordStart(false),
37  m_byteCount(0)
38 {
39  setObjectName("FileSink");
40 }
41 
42 FileRecord::FileRecord(const QString& filename) :
44  m_fileName(filename),
45  m_sampleRate(0),
47  m_recordOn(false),
48  m_recordStart(false),
49  m_byteCount(0)
50 {
51  setObjectName("FileRecord");
52 }
53 
55 {
56  stopRecording();
57 }
58 
59 void FileRecord::setFileName(const QString& filename)
60 {
61  if (!m_recordOn)
62  {
63  m_fileName = filename;
64  }
65 }
66 
67 void FileRecord::genUniqueFileName(uint deviceUID, int istream)
68 {
69  if (istream < 0) {
70  setFileName(QString("rec%1_%2.sdriq").arg(deviceUID).arg(QDateTime::currentDateTimeUtc().toString("yyyy-MM-ddTHH_mm_ss_zzz")));
71  } else {
72  setFileName(QString("rec%1_%2_%3.sdriq").arg(deviceUID).arg(istream).arg(QDateTime::currentDateTimeUtc().toString("yyyy-MM-ddTHH_mm_ss_zzz")));
73  }
74 }
75 
76 void FileRecord::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly)
77 {
78  (void) positiveOnly;
79  // if no recording is active, send the samples to /dev/null
80  if(!m_recordOn)
81  return;
82 
83  if (begin < end) // if there is something to put out
84  {
85  if (m_recordStart)
86  {
87  writeHeader();
88  m_recordStart = false;
89  }
90 
91  m_sampleFile.write(reinterpret_cast<const char*>(&*(begin)), (end - begin)*sizeof(Sample));
92  m_byteCount += end - begin;
93  }
94 }
95 
97 {
98 }
99 
101 {
102  stopRecording();
103 }
104 
106 {
107  if (!m_sampleFile.is_open())
108  {
109  qDebug() << "FileRecord::startRecording";
110  m_sampleFile.open(m_fileName.toStdString().c_str(), std::ios::binary);
111  m_recordOn = true;
112  m_recordStart = true;
113  m_byteCount = 0;
114  }
115 }
116 
118 {
119  if (m_sampleFile.is_open())
120  {
121  qDebug() << "FileRecord::stopRecording";
122  m_sampleFile.close();
123  m_recordOn = false;
124  m_recordStart = false;
125  }
126 }
127 
128 bool FileRecord::handleMessage(const Message& message)
129 {
130  if (DSPSignalNotification::match(message))
131  {
132  DSPSignalNotification& notif = (DSPSignalNotification&) message;
133  m_sampleRate = notif.getSampleRate();
135  qDebug() << "FileRecord::handleMessage: DSPSignalNotification: m_inputSampleRate: " << m_sampleRate
136  << " m_centerFrequency: " << m_centerFrequency;
137  return true;
138  }
139  else
140  {
141  return false;
142  }
143 }
144 
145 void FileRecord::handleConfigure(const QString& fileName)
146 {
147  if (fileName != m_fileName)
148  {
149  stopRecording();
150  }
151 
152  m_fileName = fileName;
153 }
154 
156 {
157  Header header;
158  header.sampleRate = m_sampleRate;
160  std::time_t ts = time(0);
161  header.startTimeStamp = ts;
162  header.sampleSize = SDR_RX_SAMP_SZ;
163  header.filler = 0;
164 
165  writeHeader(m_sampleFile, header);
166 }
167 
168 bool FileRecord::readHeader(std::ifstream& sampleFile, Header& header)
169 {
170  sampleFile.read((char *) &header, sizeof(Header));
171  boost::crc_32_type crc32;
172  crc32.process_bytes(&header, 28);
173  return header.crc32 == crc32.checksum();
174 }
175 
176 void FileRecord::writeHeader(std::ofstream& sampleFile, Header& header)
177 {
178  boost::crc_32_type crc32;
179  crc32.process_bytes(&header, 28);
180  header.crc32 = crc32.checksum();
181  sampleFile.write((const char *) &header, sizeof(Header));
182 }
void setFileName(const QString &filename)
Definition: filerecord.cpp:59
quint64 m_byteCount
Definition: filerecord.h:72
bool m_recordStart
Definition: filerecord.h:70
quint32 m_sampleRate
Definition: filerecord.h:67
void startRecording()
Definition: filerecord.cpp:105
void writeHeader()
Definition: filerecord.cpp:155
quint64 centerFrequency
Definition: filerecord.h:38
virtual void feed(const SampleVector::const_iterator &begin, const SampleVector::const_iterator &end, bool positiveOnly)
Definition: filerecord.cpp:76
void handleConfigure(const QString &fileName)
Definition: filerecord.cpp:145
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
virtual bool handleMessage(const Message &message)
Processing of a message. Returns true if message has actually been processed.
Definition: filerecord.cpp:128
qint64 getCenterFrequency() const
Definition: dspcommands.h:329
#define SDR_RX_SAMP_SZ
Definition: dsptypes.h:32
void genUniqueFileName(uint deviceUID, int istream=-1)
Definition: filerecord.cpp:67
quint64 m_centerFrequency
Definition: filerecord.h:68
void stopRecording()
Definition: filerecord.cpp:117
static bool match(const Message *message)
Definition: message.cpp:45
std::ofstream m_sampleFile
Definition: filerecord.h:71
virtual void start()
Definition: filerecord.cpp:96
virtual void stop()
Definition: filerecord.cpp:100
quint32 sampleRate
Definition: filerecord.h:37
int getSampleRate() const
Definition: dspcommands.h:328
quint32 sampleSize
Definition: filerecord.h:40
uint32_t crc32(const uint8_t *buf, int len)
Definition: crc.h:58
bool m_recordOn
Definition: filerecord.h:69
static bool readHeader(std::ifstream &samplefile, Header &header)
returns true if CRC checksum is correct else false
Definition: filerecord.cpp:168
virtual ~FileRecord()
Definition: filerecord.cpp:54
QString m_fileName
Definition: filerecord.h:66
quint64 startTimeStamp
Definition: filerecord.h:39