From f0e37131edb23600b9d2b5b0da87552732dbc64e Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 18 Jan 2021 09:55:15 +0000 Subject: [PATCH 1/4] FileSink: Generate qWarning and error dialog in GUI when failing to open a file or write to a file. --- plugins/channelrx/filesink/filesinkgui.cpp | 7 +++++ .../channelrx/filesink/filesinkmessages.cpp | 1 + plugins/channelrx/filesink/filesinkmessages.h | 19 +++++++++++++ plugins/channelrx/filesink/filesinksink.cpp | 23 ++++++++++++++-- sdrbase/dsp/filerecord.cpp | 16 +++++++++-- sdrbase/dsp/filerecord.h | 4 +-- sdrbase/dsp/filerecordinterface.h | 4 +-- sdrbase/dsp/sigmffilerecord.cpp | 27 +++++++++++++++++-- sdrbase/dsp/sigmffilerecord.h | 4 +-- 9 files changed, 93 insertions(+), 12 deletions(-) diff --git a/plugins/channelrx/filesink/filesinkgui.cpp b/plugins/channelrx/filesink/filesinkgui.cpp index 13d197859..fadc1ee82 100644 --- a/plugins/channelrx/filesink/filesinkgui.cpp +++ b/plugins/channelrx/filesink/filesinkgui.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "device/deviceuiset.h" #include "device/deviceapi.h" @@ -141,6 +142,12 @@ bool FileSinkGUI::handleMessage(const Message& message) ui->fileNameText->setText(report.getFileName()); return true; } + else if (FileSinkMessages::MsgReportRecordFileError::match(message)) + { + const FileSinkMessages::MsgReportRecordFileError& report = (FileSinkMessages::MsgReportRecordFileError&) message; + QMessageBox::critical(this, tr("File Error"), report.getMessage()); + return true; + } else { return false; diff --git a/plugins/channelrx/filesink/filesinkmessages.cpp b/plugins/channelrx/filesink/filesinkmessages.cpp index 020291d05..a05776be0 100644 --- a/plugins/channelrx/filesink/filesinkmessages.cpp +++ b/plugins/channelrx/filesink/filesinkmessages.cpp @@ -21,3 +21,4 @@ MESSAGE_CLASS_DEFINITION(FileSinkMessages::MsgConfigureSpectrum, Message) MESSAGE_CLASS_DEFINITION(FileSinkMessages::MsgReportSquelch, Message) MESSAGE_CLASS_DEFINITION(FileSinkMessages::MsgReportRecording, Message) MESSAGE_CLASS_DEFINITION(FileSinkMessages::MsgReportRecordFileName, Message) +MESSAGE_CLASS_DEFINITION(FileSinkMessages::MsgReportRecordFileError, Message) diff --git a/plugins/channelrx/filesink/filesinkmessages.h b/plugins/channelrx/filesink/filesinkmessages.h index b6914a72a..3e69a810e 100644 --- a/plugins/channelrx/filesink/filesinkmessages.h +++ b/plugins/channelrx/filesink/filesinkmessages.h @@ -103,6 +103,25 @@ public: m_fileName(fileName) { } }; + + class MsgReportRecordFileError : public Message { + MESSAGE_CLASS_DECLARATION + + public: + const QString& getMessage() const { return m_message; } + + static MsgReportRecordFileError* create(const QString& message) { + return new MsgReportRecordFileError(message); + } + + private: + QString m_message; + + MsgReportRecordFileError(const QString& message) : + Message(), + m_message(message) + { } + }; }; #endif // INCLUDE_FILESINKMESSAGES_H_ diff --git a/plugins/channelrx/filesink/filesinksink.cpp b/plugins/channelrx/filesink/filesinksink.cpp index 656a74497..b1d2daf0a 100644 --- a/plugins/channelrx/filesink/filesinksink.cpp +++ b/plugins/channelrx/filesink/filesinksink.cpp @@ -49,7 +49,17 @@ void FileSinkSink::startRecording() m_fileSink.setMsShift(-mSShift); // notify capture start - m_fileSink.startRecording(); + if (!m_fileSink.startRecording()) + { + // qWarning already output in startRecording, just need to send to GUI + if (m_msgQueueToGUI) + { + FileSinkMessages::MsgReportRecordFileError *msg + = FileSinkMessages::MsgReportRecordFileError::create(QString("Failed to open %1").arg(m_fileSink.getCurrentFileName())); + m_msgQueueToGUI->push(msg); + } + return; + } m_record = true; m_nbCaptures++; @@ -84,7 +94,16 @@ void FileSinkSink::stopRecording() if (m_record) { m_preRecordBuffer.reset(); - m_fileSink.stopRecording(); + if (!m_fileSink.stopRecording()) + { + // qWarning already output stopRecording, just need to send to GUI + if (m_msgQueueToGUI) + { + FileSinkMessages::MsgReportRecordFileError *msg + = FileSinkMessages::MsgReportRecordFileError::create(QString("Error while writing to %1").arg(m_fileSink.getCurrentFileName())); + m_msgQueueToGUI->push(msg); + } + } m_record = false; } } diff --git a/sdrbase/dsp/filerecord.cpp b/sdrbase/dsp/filerecord.cpp index 5fafd940a..8ecd1291b 100644 --- a/sdrbase/dsp/filerecord.cpp +++ b/sdrbase/dsp/filerecord.cpp @@ -103,7 +103,7 @@ void FileRecord::stop() stopRecording(); } -void FileRecord::startRecording() +bool FileRecord::startRecording() { if (m_recordOn) { stopRecording(); @@ -114,13 +114,19 @@ void FileRecord::startRecording() qDebug() << "FileRecord::startRecording"; m_curentFileName = QString("%1.%2.sdriq").arg(m_fileBase).arg(QDateTime::currentDateTimeUtc().toString("yyyy-MM-ddTHH_mm_ss_zzz")); m_sampleFile.open(m_curentFileName.toStdString().c_str(), std::ios::binary); + if (!m_sampleFile.is_open()) + { + qWarning() << "FileRecord::startRecording: failed to open file: " << m_curentFileName; + return false; + } m_recordOn = true; m_recordStart = true; m_byteCount = 0; } + return true; } -void FileRecord::stopRecording() +bool FileRecord::stopRecording() { if (m_sampleFile.is_open()) { @@ -128,7 +134,13 @@ void FileRecord::stopRecording() m_sampleFile.close(); m_recordOn = false; m_recordStart = false; + if (m_sampleFile.bad()) + { + qWarning() << "FileRecord::stopRecording: an error occured while writing to " << m_curentFileName; + return false; + } } + return true; } bool FileRecord::handleMessage(const Message& message) diff --git a/sdrbase/dsp/filerecord.h b/sdrbase/dsp/filerecord.h index f444e4d26..732376d74 100644 --- a/sdrbase/dsp/filerecord.h +++ b/sdrbase/dsp/filerecord.h @@ -60,8 +60,8 @@ public: virtual bool handleMessage(const Message& message); virtual void setFileName(const QString& fileBase); - virtual void startRecording(); - virtual void stopRecording(); + virtual bool startRecording(); + virtual bool stopRecording(); virtual bool isRecording() const { return m_recordOn; } static bool readHeader(std::ifstream& samplefile, Header& header); //!< returns true if CRC checksum is correct else false diff --git a/sdrbase/dsp/filerecordinterface.h b/sdrbase/dsp/filerecordinterface.h index 67cbd3bf3..b66e8694f 100644 --- a/sdrbase/dsp/filerecordinterface.h +++ b/sdrbase/dsp/filerecordinterface.h @@ -51,8 +51,8 @@ public: MessageQueue *getMessageQueueToGUI() { return m_guiMessageQueue; } virtual void setFileName(const QString &filename) = 0; - virtual void startRecording() = 0; - virtual void stopRecording() = 0; + virtual bool startRecording() = 0; + virtual bool stopRecording() = 0; virtual bool isRecording() const = 0; static QString genUniqueFileName(unsigned int deviceUID, int istream = -1); diff --git a/sdrbase/dsp/sigmffilerecord.cpp b/sdrbase/dsp/sigmffilerecord.cpp index a20812d28..c298b3fd5 100644 --- a/sdrbase/dsp/sigmffilerecord.cpp +++ b/sdrbase/dsp/sigmffilerecord.cpp @@ -107,8 +107,9 @@ unsigned int SigMFFileRecord::getNbCaptures() const return m_metaRecord->captures.size(); } -void SigMFFileRecord::startRecording() +bool SigMFFileRecord::startRecording() { + bool success = true; if (m_recordStart) { @@ -118,7 +119,17 @@ void SigMFFileRecord::startRecording() m_sampleFileName = m_fileName + ".sigmf-data"; m_metaFileName = m_fileName + ".sigmf-meta"; m_sampleFile.open(m_sampleFileName.toStdString().c_str(), std::ios::binary); + if (!m_sampleFile.is_open()) + { + qWarning() << "SigMFFileRecord::startRecording: failed to open file: " << m_sampleFileName; + success = false; + } m_metaFile.open(m_metaFileName.toStdString().c_str(), std::ofstream::out); + if (!m_metaFile.is_open()) + { + qWarning() << "SigMFFileRecord::startRecording: failed to open file: " << m_metaFile; + success = false; + } makeHeader(); m_recordStart = false; } @@ -130,16 +141,28 @@ void SigMFFileRecord::startRecording() m_captureStartDT = QDateTime::currentDateTimeUtc().addMSecs(m_msShift); m_recordOn = true; m_sampleCount = 0; + return success; } -void SigMFFileRecord::stopRecording() +bool SigMFFileRecord::stopRecording() { if (m_recordOn) { qDebug("SigMFFileRecord::stopRecording: file previous capture"); makeCapture(); m_recordOn = false; + if (m_sampleFile.bad()) + { + qWarning() << "SigMFFileRecord::stopRecording: an error occured while writing to " << m_sampleFileName; + return false; + } + if (m_metaFile.bad()) + { + qWarning() << "SigMFFileRecord::stopRecording: an error occured while writing to " << m_metaFileName; + return false; + } } + return true; } void SigMFFileRecord::makeHeader() diff --git a/sdrbase/dsp/sigmffilerecord.h b/sdrbase/dsp/sigmffilerecord.h index 9d31a1709..5ab1d714e 100644 --- a/sdrbase/dsp/sigmffilerecord.h +++ b/sdrbase/dsp/sigmffilerecord.h @@ -45,8 +45,8 @@ public: virtual bool handleMessage(const Message& message); virtual void setFileName(const QString& filename); - virtual void startRecording(); - virtual void stopRecording(); + virtual bool startRecording(); + virtual bool stopRecording(); virtual bool isRecording() const { return m_recordOn; } void setHardwareId(const QString& hardwareId) { m_hardwareId = hardwareId; } From d6bf5223db0145542075a7d17b62d62ef079a0b6 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 18 Jan 2021 09:55:39 +0000 Subject: [PATCH 2/4] Fix formatting --- plugins/channelrx/filesink/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/channelrx/filesink/readme.md b/plugins/channelrx/filesink/readme.md index 9b450c9c0..76ae28fd0 100644 --- a/plugins/channelrx/filesink/readme.md +++ b/plugins/channelrx/filesink/readme.md @@ -68,7 +68,7 @@ Note that spectrum polling is done every 200 ms. If the signal of interest is sh This is the squelch level as discussed above. To try to find the correct value you can use the spectrum display (15). -

10: Pre recording period

+

10: Pre recording period

This is the number of seconds of data that will be prepended before the start of recording point. Thus you can make sure that the signal of interest will be fully recorded. Works in both spectrum squelch triggered and manual mode. From 890f6fc0490f81b80e96298195fcc51c69789bf7 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 18 Jan 2021 09:55:51 +0000 Subject: [PATCH 3/4] Add tooltip to record button --- plugins/channelrx/filesink/filesinkgui.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/channelrx/filesink/filesinkgui.ui b/plugins/channelrx/filesink/filesinkgui.ui index 814bf79a0..144bfc5fb 100644 --- a/plugins/channelrx/filesink/filesinkgui.ui +++ b/plugins/channelrx/filesink/filesinkgui.ui @@ -453,6 +453,9 @@ 16777215 + + Start/stop recording + From 3fed08f3207bff50b84e6de7f569f4a74e41ef0f Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 18 Jan 2021 16:33:50 +0000 Subject: [PATCH 4/4] Output filename rather than file --- sdrbase/dsp/sigmffilerecord.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sdrbase/dsp/sigmffilerecord.cpp b/sdrbase/dsp/sigmffilerecord.cpp index c298b3fd5..3630cacb6 100644 --- a/sdrbase/dsp/sigmffilerecord.cpp +++ b/sdrbase/dsp/sigmffilerecord.cpp @@ -127,7 +127,7 @@ bool SigMFFileRecord::startRecording() m_metaFile.open(m_metaFileName.toStdString().c_str(), std::ofstream::out); if (!m_metaFile.is_open()) { - qWarning() << "SigMFFileRecord::startRecording: failed to open file: " << m_metaFile; + qWarning() << "SigMFFileRecord::startRecording: failed to open file: " << m_metaFileName; success = false; } makeHeader(); @@ -265,4 +265,5 @@ bool SigMFFileRecord::handleMessage(const Message& message) { return false; } -} \ No newline at end of file +} +