SigMF file sink: append data if file exists and has been recorded with SDRangel. Implements #781

This commit is contained in:
f4exb 2021-02-20 12:16:34 +01:00
parent 1eaaa8407d
commit 754798cafb
4 changed files with 75 additions and 5 deletions

View File

@ -13,6 +13,8 @@ As per SigMF specifications two files are created in fact.
If a filename is given without `.sigmf-meta` extension then the `.sigmf-meta` extension is appended automatically.
If a filename is given with an extension different of `.sigmf-meta` then the extension is replaced by `.sigmf-meta` automatically.
If the couple `.sigmf-meta`, `.sigmf-data` exists for a file set and it was recorded by SDRangel then new data will be appended as new captures.
It adds a dependency to the [libsigmf library](https://github.com/f4exb/libsigmf) more specifically the `f4exb` fork that supports `multirecordings` and `sdrangel` extensions.
<h2>Interface</h2>

View File

@ -264,8 +264,8 @@ void SigMFFileSinkSink::applySettings(const SigMFFileSinkSettings& settings, boo
{
m_fileSink.setFileName(fileBase);
m_fileSink.setHardwareId(m_deviceHwId);
m_msCount = 0;
m_byteCount = 0;
m_msCount = m_fileSink.getInitialMsCount();
m_byteCount = m_fileSink.getInitialBytesCount();
m_recordEnabled = true;
}
else

View File

@ -19,6 +19,7 @@
#include <QCoreApplication>
#include <QSysInfo>
#include <QFile>
#include <QDebug>
#include "libsigmf/sigmf_core_generated.h"
@ -39,7 +40,9 @@ SigMFFileRecord::SigMFFileRecord() :
m_recordOn(false),
m_recordStart(true),
m_sampleStart(0),
m_sampleCount(0)
m_sampleCount(0),
m_initialMsCount(0),
m_initialBytesCount(0)
{
qDebug("SigMFFileRecord::SigMFFileRecord: test");
setObjectName("SigMFFileSink");
@ -57,7 +60,9 @@ SigMFFileRecord::SigMFFileRecord(const QString& fileName, const QString& hardwar
m_recordOn(false),
m_recordStart(true),
m_sampleStart(0),
m_sampleCount(0)
m_sampleCount(0),
m_initialMsCount(0),
m_initialBytesCount(0)
{
qDebug("SigMFFileRecord::SigMFFileRecord: %s", qPrintable(fileName));
setObjectName("SigMFFileSink");
@ -98,7 +103,66 @@ void SigMFFileRecord::setFileName(const QString& fileName)
}
m_fileName = fileName;
m_recordStart = true;
if (QFile::exists(fileName + ".sigmf-data") && QFile::exists(fileName + ".sigmf-meta"))
{
m_metaFileName = m_fileName + ".sigmf-meta";
std::ifstream metaStream;
#ifdef Q_OS_WIN
metaStream.open(m_metaFileName.toStdWString().c_str());
#else
metaStream.open(m_metaFileName.toStdString().c_str());
#endif
std::ostringstream meta_buffer;
meta_buffer << metaStream.rdbuf();
try
{
from_json(json::parse(meta_buffer.str()), *m_metaRecord);
metaStream.close();
std::string sdrAngelVersion = m_metaRecord->global.access<sdrangel::GlobalT>().version;
if (sdrAngelVersion.size() != 0)
{
qDebug("SigMFFileRecord::setFileName: appending mode");
m_metaFile.open(m_metaFileName.toStdString().c_str(), std::ofstream::out);
m_initialMsCount = 0;
for (auto capture : m_metaRecord->captures)
{
uint64_t length = capture.get<core::DescrT>().length;
int32_t sampleRate = capture.get<sdrangel::DescrT>().sample_rate;
m_initialMsCount += (length * 1000) / sampleRate;
}
m_sampleFileName = m_fileName + ".sigmf-data";
m_sampleFile.open(m_sampleFileName.toStdString().c_str(), std::ios::binary & std::ios::app);
m_initialBytesCount = (uint64_t) m_sampleFile.tellp();
m_sampleStart = m_initialBytesCount / sizeof(Sample);
m_recordStart = false;
}
else
{
qDebug("SigMFFileRecord::setFileName: SigMF not recorded with SDRangel. Recreating files...");
m_initialBytesCount = 0;
m_initialMsCount = 0;
m_recordStart = true;
}
}
catch(const std::exception& e)
{
qInfo("SigMFFileRecord::setFileName: exception: %s. Recreating files...", qPrintable(e.what()));
m_initialBytesCount = 0;
m_initialMsCount = 0;
m_recordStart = true;
}
}
else
{
m_initialBytesCount = 0;
m_initialMsCount = 0;
m_recordStart = true;
}
}
}

View File

@ -52,6 +52,8 @@ public:
void setHardwareId(const QString& hardwareId) { m_hardwareId = hardwareId; }
void setMsShift(qint64 msShift) { m_msShift = msShift; }
unsigned int getNbCaptures() const;
uint64_t getInitialMsCount() const { return m_initialMsCount; }
uint64_t getInitialBytesCount() const { return m_initialBytesCount; }
private:
QString m_hardwareId;
@ -68,6 +70,8 @@ private:
std::ofstream m_sampleFile;
quint64 m_sampleStart;
quint64 m_sampleCount;
quint64 m_initialMsCount;
quint64 m_initialBytesCount;
sigmf::SigMF<sigmf::Global<core::DescrT, sdrangel::DescrT>,
sigmf::Capture<core::DescrT, sdrangel::DescrT>,
sigmf::Annotation<core::DescrT> > *m_metaRecord;