From cc49d5c2662afdd3db1758d216ad0de645b2bc2c Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 9 Oct 2018 09:26:28 +0200 Subject: [PATCH] FileRecord improvement: CRC check and sample size fix --- .../filesource/filesourceinput.cpp | 21 +++++-- sdrbase/dsp/filerecord.cpp | 55 +++++++++++++------ sdrbase/dsp/filerecord.h | 36 +++++++++--- 3 files changed, 81 insertions(+), 31 deletions(-) diff --git a/plugins/samplesource/filesource/filesourceinput.cpp b/plugins/samplesource/filesource/filesourceinput.cpp index 032d39f85..24f7c2097 100644 --- a/plugins/samplesource/filesource/filesourceinput.cpp +++ b/plugins/samplesource/filesource/filesourceinput.cpp @@ -16,6 +16,7 @@ #include #include + #include #include "SWGDeviceSettings.h" @@ -87,14 +88,22 @@ void FileSourceInput::openFileStream() // TODO: add CRC m_ifstream.seekg(0,std::ios_base::beg); FileRecord::Header header; - FileRecord::readHeader(m_ifstream, header); - m_sampleRate = header.sampleRate; - m_centerFrequency = header.centerFrequency; - m_startingTimeStamp = header.startTimeStamp; - m_sampleSize = header.sampleSize; + if (FileRecord::readHeader(m_ifstream, header)) // CRC OK + { + m_sampleRate = header.sampleRate; + m_centerFrequency = header.centerFrequency; + m_startingTimeStamp = header.startTimeStamp; + m_sampleSize = header.sampleSize; + + m_recordLength = (fileSize - sizeof(FileRecord::Header)) / ((m_sampleSize == 24 ? 8 : 4) * m_sampleRate); + } + else + { + qCritical("FileSourceInput::openFileStream: bad CRC header"); + m_recordLength = 0; + } - m_recordLength = (fileSize - sizeof(FileRecord::Header)) / (4 * m_sampleRate); } else { diff --git a/sdrbase/dsp/filerecord.cpp b/sdrbase/dsp/filerecord.cpp index 56f1e07cc..55ae8cfc0 100644 --- a/sdrbase/dsp/filerecord.cpp +++ b/sdrbase/dsp/filerecord.cpp @@ -1,10 +1,30 @@ -#include +/////////////////////////////////////////////////////////////////////////////////// +// 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 // +// // +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include +#include + #include "dsp/dspcommands.h" #include "util/simpleserializer.h" #include "util/message.h" -#include -#include +#include "filerecord.h" FileRecord::FileRecord() : BasebandSampleSink(), @@ -128,21 +148,24 @@ void FileRecord::handleConfigure(const QString& fileName) void FileRecord::writeHeader() { - m_sampleFile.write((const char *) &m_sampleRate, sizeof(qint32)); // 4 bytes - m_sampleFile.write((const char *) &m_centerFrequency, sizeof(quint64)); // 8 bytes + Header header; + header.sampleRate = m_sampleRate; + header.centerFrequency = m_centerFrequency; std::time_t ts = time(0); - m_sampleFile.write((const char *) &ts, sizeof(std::time_t)); // 8 bytes - quint32 sampleSize = SDR_RX_SAMP_SZ; - m_sampleFile.write((const char *) &sampleSize, sizeof(int)); // 4 bytes + header.startTimeStamp = ts; + header.sampleSize = SDR_RX_SAMP_SZ; + header.filler = 0; + boost::crc_32_type crc32; + crc32.process_bytes(&header, 28); + header.crc32 = crc32.checksum(); + + m_sampleFile.write((const char *) &header, sizeof(Header)); } -void FileRecord::readHeader(std::ifstream& sampleFile, Header& header) +bool FileRecord::readHeader(std::ifstream& sampleFile, Header& header) { - sampleFile.read((char *) &(header.sampleRate), sizeof(qint32)); - sampleFile.read((char *) &(header.centerFrequency), sizeof(quint64)); - sampleFile.read((char *) &(header.startTimeStamp), sizeof(std::time_t)); - sampleFile.read((char *) &(header.sampleSize), sizeof(quint32)); - if ((header.sampleSize != 16) && (header.sampleSize != 24)) { // assume 16 bits if garbage (old I/Q file) - header.sampleSize = 16; - } + sampleFile.read((char *) &header, sizeof(Header)); + boost::crc_32_type crc32; + crc32.process_bytes(&header, 28); + return header.crc32 == crc32.checksum(); } diff --git a/sdrbase/dsp/filerecord.h b/sdrbase/dsp/filerecord.h index 08970e004..51edbca49 100644 --- a/sdrbase/dsp/filerecord.h +++ b/sdrbase/dsp/filerecord.h @@ -1,5 +1,21 @@ -#ifndef INCLUDE_FILESINK_H -#define INCLUDE_FILESINK_H +/////////////////////////////////////////////////////////////////////////////////// +// 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 // +// // +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_FILERECORD_H +#define INCLUDE_FILERECORD_H #include #include @@ -16,10 +32,12 @@ public: struct Header { - qint32 sampleRate; - quint64 centerFrequency; - std::time_t startTimeStamp; - quint32 sampleSize; + quint32 sampleRate; + quint64 centerFrequency; + quint64 startTimeStamp; + quint32 sampleSize; + quint32 filler; + quint32 crc32; }; FileRecord(); @@ -37,11 +55,11 @@ public: virtual bool handleMessage(const Message& message); void startRecording(); void stopRecording(); - static void readHeader(std::ifstream& samplefile, Header& header); + static bool readHeader(std::ifstream& samplefile, Header& header); //!< returns true if CRC checksum is correct else false private: QString m_fileName; - qint32 m_sampleRate; + quint32 m_sampleRate; quint64 m_centerFrequency; bool m_recordOn; bool m_recordStart; @@ -52,4 +70,4 @@ private: void writeHeader(); }; -#endif // INCLUDE_FILESINK_H +#endif // INCLUDE_FILERECORD_H