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/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 + 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/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. 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..3630cacb6 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_metaFileName; + 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() @@ -242,4 +265,5 @@ bool SigMFFileRecord::handleMessage(const Message& message) { return false; } -} \ No newline at end of file +} + 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; }