| 
									
										
										
										
											2018-10-09 09:26:28 +02:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2015-2018 Edouard Griffiths, F4EXB                              //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is free software; you can redistribute it and/or modify          //
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by          //
 | 
					
						
							|  |  |  | // the Free Software Foundation as version 3 of the License, or                  //
 | 
					
						
							| 
									
										
										
										
											2019-04-11 14:32:15 +02:00
										 |  |  | // (at your option) any later version.                                           //
 | 
					
						
							| 
									
										
										
										
											2018-10-09 09:26:28 +02:00
										 |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful,               //
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
					
						
							|  |  |  | // GNU General Public License V3 for more details.                               //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License             //
 | 
					
						
							|  |  |  | // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/crc.hpp>
 | 
					
						
							|  |  |  | #include <boost/cstdint.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | #include <QDateTime>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-14 05:00:28 +02:00
										 |  |  | #include "dsp/dspcommands.h"
 | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | #include "util/simpleserializer.h"
 | 
					
						
							| 
									
										
										
										
											2016-05-12 10:31:57 +02:00
										 |  |  | #include "util/message.h"
 | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-09 09:26:28 +02:00
										 |  |  | #include "filerecord.h"
 | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 10:30:58 +02:00
										 |  |  | FileRecord::FileRecord() : | 
					
						
							| 
									
										
										
										
											2016-10-02 22:29:04 +02:00
										 |  |  | 	BasebandSampleSink(), | 
					
						
							| 
									
										
										
										
											2018-05-08 11:03:09 +02:00
										 |  |  |     m_fileName("test.sdriq"), | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  |     m_sampleRate(0), | 
					
						
							|  |  |  |     m_centerFrequency(0), | 
					
						
							|  |  |  | 	m_recordOn(false), | 
					
						
							|  |  |  |     m_recordStart(false), | 
					
						
							|  |  |  |     m_byteCount(0) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-08-12 09:03:02 +02:00
										 |  |  | 	setObjectName("FileSink"); | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 11:03:09 +02:00
										 |  |  | FileRecord::FileRecord(const QString& filename) : | 
					
						
							| 
									
										
										
										
											2016-10-02 22:29:04 +02:00
										 |  |  |     BasebandSampleSink(), | 
					
						
							| 
									
										
										
										
											2018-05-08 11:03:09 +02:00
										 |  |  |     m_fileName(filename), | 
					
						
							| 
									
										
										
										
											2016-05-12 10:31:57 +02:00
										 |  |  |     m_sampleRate(0), | 
					
						
							|  |  |  |     m_centerFrequency(0), | 
					
						
							|  |  |  |     m_recordOn(false), | 
					
						
							|  |  |  |     m_recordStart(false), | 
					
						
							|  |  |  |     m_byteCount(0) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  |     setObjectName("FileRecord"); | 
					
						
							| 
									
										
										
										
											2016-05-12 10:31:57 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 10:30:58 +02:00
										 |  |  | FileRecord::~FileRecord() | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     stopRecording(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 11:03:09 +02:00
										 |  |  | void FileRecord::setFileName(const QString& filename) | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-12 10:31:57 +02:00
										 |  |  |     if (!m_recordOn) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_fileName = filename; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 09:08:20 +02:00
										 |  |  | void FileRecord::genUniqueFileName(uint deviceUID) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     setFileName(QString("rec%1_%2.sdriq").arg(deviceUID).arg(QDateTime::currentDateTimeUtc().toString("yyyy-MM-ddTHH_mm_ss_zzz"))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 16:58:20 +01:00
										 |  |  | void FileRecord::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-12 16:58:20 +01:00
										 |  |  |     (void) positiveOnly; | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  |     // if no recording is active, send the samples to /dev/null
 | 
					
						
							|  |  |  |     if(!m_recordOn) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (begin < end) // if there is something to put out
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (m_recordStart) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             writeHeader(); | 
					
						
							|  |  |  |             m_recordStart = false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_sampleFile.write(reinterpret_cast<const char*>(&*(begin)), (end - begin)*sizeof(Sample)); | 
					
						
							|  |  |  |         m_byteCount += end - begin; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 10:30:58 +02:00
										 |  |  | void FileRecord::start() | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 10:30:58 +02:00
										 |  |  | void FileRecord::stop() | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     stopRecording(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 10:30:58 +02:00
										 |  |  | void FileRecord::startRecording() | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!m_sampleFile.is_open()) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  |     	qDebug() << "FileRecord::startRecording"; | 
					
						
							| 
									
										
										
										
											2018-05-08 11:03:09 +02:00
										 |  |  |         m_sampleFile.open(m_fileName.toStdString().c_str(), std::ios::binary); | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  |         m_recordOn = true; | 
					
						
							|  |  |  |         m_recordStart = true; | 
					
						
							|  |  |  |         m_byteCount = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 10:30:58 +02:00
										 |  |  | void FileRecord::stopRecording() | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (m_sampleFile.is_open()) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  |     	qDebug() << "FileRecord::stopRecording"; | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  |         m_sampleFile.close(); | 
					
						
							|  |  |  |         m_recordOn = false; | 
					
						
							|  |  |  |         m_recordStart = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 10:30:58 +02:00
										 |  |  | bool FileRecord::handleMessage(const Message& message) | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 	if (DSPSignalNotification::match(message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		DSPSignalNotification& notif = (DSPSignalNotification&) message; | 
					
						
							|  |  |  | 		m_sampleRate = notif.getSampleRate(); | 
					
						
							| 
									
										
										
										
											2015-08-19 22:12:52 +02:00
										 |  |  | 		m_centerFrequency = notif.getCenterFrequency(); | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 		qDebug() << "FileRecord::handleMessage: DSPSignalNotification: m_inputSampleRate: " << m_sampleRate | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 				<< " m_centerFrequency: " << m_centerFrequency; | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 11:03:09 +02:00
										 |  |  | void FileRecord::handleConfigure(const QString& fileName) | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-08-14 05:00:28 +02:00
										 |  |  |     if (fileName != m_fileName) | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         stopRecording(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-05-12 10:31:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | 	m_fileName = fileName; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 10:30:58 +02:00
										 |  |  | void FileRecord::writeHeader() | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-09 09:26:28 +02:00
										 |  |  |     Header header; | 
					
						
							|  |  |  |     header.sampleRate = m_sampleRate; | 
					
						
							|  |  |  |     header.centerFrequency = m_centerFrequency; | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  |     std::time_t ts = time(0); | 
					
						
							| 
									
										
										
										
											2018-10-09 09:26:28 +02:00
										 |  |  |     header.startTimeStamp = ts; | 
					
						
							|  |  |  |     header.sampleSize = SDR_RX_SAMP_SZ; | 
					
						
							|  |  |  |     header.filler = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 14:05:21 +02:00
										 |  |  |     writeHeader(m_sampleFile, header); | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-09 09:26:28 +02:00
										 |  |  | bool FileRecord::readHeader(std::ifstream& sampleFile, Header& header) | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-09 09:26:28 +02:00
										 |  |  |     sampleFile.read((char *) &header, sizeof(Header)); | 
					
						
							|  |  |  |     boost::crc_32_type crc32; | 
					
						
							|  |  |  |     crc32.process_bytes(&header, 28); | 
					
						
							|  |  |  |     return header.crc32 == crc32.checksum(); | 
					
						
							| 
									
										
										
										
											2015-07-28 23:54:17 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-10-10 14:05:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void FileRecord::writeHeader(std::ofstream& sampleFile, Header& header) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     boost::crc_32_type crc32; | 
					
						
							|  |  |  |     crc32.process_bytes(&header, 28); | 
					
						
							|  |  |  |     header.crc32 = crc32.checksum(); | 
					
						
							|  |  |  |     sampleFile.write((const char *) &header, sizeof(Header)); | 
					
						
							| 
									
										
										
										
											2018-11-12 16:58:20 +01:00
										 |  |  | } |