diff --git a/sdrbase/util/doublebuffer.h b/sdrbase/util/doublebuffer.h index 1dafc3334..cb29255cd 100644 --- a/sdrbase/util/doublebuffer.h +++ b/sdrbase/util/doublebuffer.h @@ -125,7 +125,9 @@ public: d.readU32(2, &tmpUInt, 0); m_current = m_data.begin() + tmpUInt; d.readBlob(3, &buf); - std::copy(reinterpret_cast(m_data.data()), buf.data(), buf.data() + buf.size()); + //qDebug("DoubleBufferSimple::deserialize: m_data.size(): %u buf.size(): %d", m_data.size(), buf.size()); + //std::copy(reinterpret_cast(m_data.data()), buf.data(), buf.data() + buf.size()); // bug + memcpy(reinterpret_cast(m_data.data()), buf.data(), buf.size()); return true; } diff --git a/sdrgui/dsp/scopevis.h b/sdrgui/dsp/scopevis.h index a45c95d20..174b0ae6a 100644 --- a/sdrgui/dsp/scopevis.h +++ b/sdrgui/dsp/scopevis.h @@ -167,6 +167,52 @@ public: void setOneShot(bool oneShot); void setMemoryIndex(uint32_t memoryIndex); + QByteArray serializeMemory() const + { + SimpleSerializer s(1); + + s.writeU32(1, m_traceSize); + s.writeS32(2, m_sampleRate); + QByteArray buffer = m_traceDiscreteMemory.serialize(); + s.writeBlob(3, buffer); + + return s.final(); + } + + bool deserializeMemory(const QByteArray& data) + { + SimpleDeserializer d(data); + + if(!d.isValid()) { + return false; + } + + if (d.getVersion() == 1) + { + uint32_t traceSize; + int sampleRate; + QByteArray buf; + bool traceDiscreteMemorySuccess; + + d.readU32(1, &traceSize, m_traceChunkSize); + d.readS32(2, &sampleRate, 0); + setSampleRate(sampleRate); + setTraceSize(traceSize); + d.readBlob(3, &buf); + traceDiscreteMemorySuccess = m_traceDiscreteMemory.deserialize(buf); + + if (traceDiscreteMemorySuccess && (m_glScope) && (m_currentTraceMemoryIndex > 0)) { + processMemoryTrace(); + } + + return traceDiscreteMemorySuccess; + } + else + { + return false; + } + } + void getTriggerData(TriggerData& triggerData, uint32_t triggerIndex) { if (triggerIndex < m_triggerConditions.size()) @@ -665,7 +711,7 @@ private: for (std::vector::iterator it = m_traceBackBuffers.begin(); it != m_traceBackBuffers.end(); ++it) { - it->resize(4*m_traceSize); + it->resize(4*m_traceSize); // TODO: why 4? } } diff --git a/sdrgui/gui/glscopegui.cpp b/sdrgui/gui/glscopegui.cpp index 82ce036b7..e218c9d48 100644 --- a/sdrgui/gui/glscopegui.cpp +++ b/sdrgui/gui/glscopegui.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "glscopegui.h" #include "glscope.h" @@ -771,7 +772,6 @@ void GLScopeGUI::on_traceColor_clicked() void GLScopeGUI::on_memorySave_clicked(bool checked __attribute__((unused))) { - qDebug("GLScopeGUI::on_memorySave_clicked"); QString fileName = QFileDialog::getSaveFileName(this, tr("Open trace memory file"), ".", tr("Trace memory files (*.trcm)"), 0, QFileDialog::DontUseNativeDialog); @@ -783,7 +783,20 @@ void GLScopeGUI::on_memorySave_clicked(bool checked __attribute__((unused))) fileName += ".trcm"; } - qDebug("GLScopeGUI::on_memorySave_clicked: %s", qPrintable(fileName)); + QFile exportFile(fileName); + + if (exportFile.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QString base64Str = m_scopeVis->serializeMemory().toBase64(); + QTextStream outstream(&exportFile); + outstream << base64Str; + exportFile.close(); + qDebug("GLScopeGUI::on_memorySave_clicked: saved to %s", qPrintable(fileName)); + } + else + { + QMessageBox::information(this, tr("Message"), tr("Cannot open %1 file for writing").arg(fileName)); + } } } @@ -796,7 +809,21 @@ void GLScopeGUI::on_memoryLoad_clicked(bool checked __attribute__((unused))) if (fileName != "") { - qDebug("GLScopeGUI::on_memoryLoad_clicked: %s", qPrintable(fileName)); + QFile exportFile(fileName); + + if (exportFile.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QByteArray base64Str; + QTextStream instream(&exportFile); + instream >> base64Str; + exportFile.close(); + m_scopeVis->deserializeMemory(QByteArray::fromBase64(base64Str)); + qDebug("GLScopeGUI::on_memoryLoad_clicked: loaded from %s", qPrintable(fileName)); + } + else + { + QMessageBox::information(this, tr("Message"), tr("Cannot open file %1 for reading").arg(fileName)); + } } }