diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt
index ff18b6ba2..84a458be4 100644
--- a/sdrbase/CMakeLists.txt
+++ b/sdrbase/CMakeLists.txt
@@ -85,6 +85,7 @@ set(sdrbase_SOURCES
dsp/filerecord.cpp
dsp/freqlockcomplex.cpp
dsp/interpolator.cpp
+ dsp/glscopesettings.cpp
dsp/glspectrumsettings.cpp
dsp/hbfilterchainconverter.cpp
dsp/hbfiltertraits.cpp
@@ -201,6 +202,7 @@ set(sdrbase_HEADERS
dsp/filerecord.h
dsp/freqlockcomplex.h
dsp/gfft.h
+ dsp/glscopesettings.h
dsp/glspectrumsettings.h
dsp/hbfilterchainconverter.h
dsp/iirfilter.h
diff --git a/sdrbase/dsp/glscopesettings.cpp b/sdrbase/dsp/glscopesettings.cpp
new file mode 100644
index 000000000..ecbb60181
--- /dev/null
+++ b/sdrbase/dsp/glscopesettings.cpp
@@ -0,0 +1,202 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2019 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 //
+// (at your option) any later version. //
+// //
+// 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 "util/simpleserializer.h"
+#include "glscopesettings.h"
+
+GLScopeSettings::GLScopeSettings()
+{
+ resetToDefaults();
+}
+
+GLScopeSettings::~GLScopeSettings()
+{}
+
+void GLScopeSettings::resetToDefaults()
+{
+ m_displayMode = DisplayX;
+ m_traceIntensity = 50;
+ m_gridIntensity = 10;
+ m_time = 1;
+ m_timeOfs = 0;
+ m_traceLen = 1;
+ m_trigPre = 0;
+}
+
+QByteArray GLScopeSettings::serialize() const
+{
+ SimpleSerializer s(1);
+
+ // first row
+ s.writeS32(1, (int) m_displayMode);
+ s.writeS32(2, m_traceIntensity);
+ s.writeS32(3, m_gridIntensity);
+ s.writeS32(4, m_time);
+ s.writeS32(5, m_timeOfs);
+ s.writeS32(6, m_traceLen);
+
+ std::vector::const_iterator traceDataIt = m_tracesData.begin();
+ unsigned int i = 0;
+
+ for (; traceDataIt != m_tracesData.end(); ++traceDataIt, i++)
+ {
+ if (20 + 16*i > 200) {
+ break;
+ }
+
+ s.writeS32(20 + 16*i, (int) traceDataIt->m_projectionType);
+ s.writeU32(21 + 16*i, traceDataIt->m_ampIndex);
+ s.writeS32(22 + 16*i, traceDataIt->m_ofsCoarse);
+ s.writeS32(23 + 16*i, traceDataIt->m_ofsFine);
+ s.writeS32(24 + 16*i, traceDataIt->m_traceDelayCoarse);
+ s.writeS32(25 + 16*i, traceDataIt->m_traceDelayFine);
+ s.writeFloat(26 + 16*i, traceDataIt->m_traceColorR);
+ s.writeFloat(27 + 16*i, traceDataIt->m_traceColorG);
+ s.writeFloat(28 + 16*i, traceDataIt->m_traceColorB);
+ }
+
+ s.writeU32(10, i);
+ s.writeU32(200, m_triggersData.size());
+ s.writeS32(201, m_trigPre);
+ std::vector::const_iterator triggerDataIt = m_triggersData.begin();
+ i = 0;
+
+ for (; triggerDataIt != m_triggersData.end(); i++)
+ {
+ s.writeS32(210 + 16*i, (int) triggerDataIt->m_projectionType);
+ s.writeS32(211 + 16*i, triggerDataIt->m_triggerRepeat);
+ s.writeBool(212 + 16*i, triggerDataIt->m_triggerPositiveEdge);
+ s.writeBool(213 + 16*i, triggerDataIt->m_triggerBothEdges);
+ s.writeS32(214 + 16*i, triggerDataIt->m_triggerLevelCoarse);
+ s.writeS32(215 + 16*i, triggerDataIt->m_triggerLevelFine);
+ s.writeS32(216 + 16*i, triggerDataIt->m_triggerDelayCoarse);
+ s.writeS32(217 + 16*i, triggerDataIt->m_triggerDelayFine);
+ s.writeFloat(218 + 16*i, triggerDataIt->m_triggerColorR);
+ s.writeFloat(219 + 16*i, triggerDataIt->m_triggerColorG);
+ s.writeFloat(220 + 16*i, triggerDataIt->m_triggerColorB);
+ s.writeU32(221 + 16*i, triggerDataIt->m_triggerHoldoff);
+ }
+
+ return s.final();
+}
+
+bool GLScopeSettings::deserialize(const QByteArray& data)
+{
+ qDebug("GLScopeGUI::deserialize");
+ SimpleDeserializer d(data);
+
+ if(!d.isValid()) {
+ resetToDefaults();
+ return false;
+ }
+
+ if (d.getVersion() == 1)
+ {
+ int intValue;
+ uint32_t uintValue;
+ bool boolValue;
+
+ d.readS32(1, &intValue, (int) DisplayX);
+ m_displayMode = (DisplayMode) intValue;
+ d.readS32(2, &m_traceIntensity, 50);
+ d.readS32(3, &m_gridIntensity, 10);
+ d.readS32(4, &m_time, 1);
+ d.readS32(5, &m_timeOfs, 0);
+ d.readS32(6, &m_traceLen, 1);
+ d.readS32(201, &m_trigPre, 0);
+
+ uint32_t nbTracesSaved;
+ d.readU32(10, &nbTracesSaved, 1);
+ m_tracesData.clear();
+ float r, g, b;
+
+ for (int iTrace = 0; iTrace < nbTracesSaved; iTrace++)
+ {
+ if (20 + 16*iTrace > 200) {
+ break;
+ }
+
+ m_tracesData.push_back(TraceData());
+
+ d.readS32(20 + 16*iTrace, &intValue, 0);
+ m_tracesData.back().m_projectionType = (Projector::ProjectionType) intValue;
+ d.readU32(21 + 16*iTrace, &uintValue, 0);
+ m_tracesData.back().m_amp = uintValue;
+ d.readS32(22 + 16*iTrace, &intValue, 0);
+ m_tracesData.back().m_ofsCoarse = intValue;
+ d.readS32(23 + 16*iTrace, &intValue, 0);
+ m_tracesData.back().m_ofsFine = intValue;
+ d.readS32(24 + 16*iTrace, &intValue, 0);
+ m_tracesData.back().m_traceDelayCoarse = intValue;
+ d.readS32(25 + 16*iTrace, &intValue, 0);
+ m_tracesData.back().m_traceDelayFine = intValue;
+ d.readFloat(26 + 16*iTrace, &r, 1.0f);
+ d.readFloat(27 + 16*iTrace, &g, 1.0f);
+ d.readFloat(28 + 16*iTrace, &b, 1.0f);
+ m_tracesData.back().m_traceColorR = r;
+ m_tracesData.back().m_traceColorG = g;
+ m_tracesData.back().m_traceColorB = b;
+ m_tracesData.back().m_traceColor.setRedF(r);
+ m_tracesData.back().m_traceColor.setGreenF(g);
+ m_tracesData.back().m_traceColor.setBlueF(b);
+ }
+
+ uint32_t nbTriggersSaved;
+ d.readU32(200, &nbTriggersSaved, 1);
+ m_triggersData.clear();
+
+ for (int iTrigger = 0; iTrigger < nbTriggersSaved; iTrigger++)
+ {
+ m_triggersData.push_back(TriggerData());
+
+ d.readS32(210 + 16*iTrigger, &intValue, 0);
+ m_triggersData.back().m_projectionType = (Projector::ProjectionType) intValue;
+ d.readS32(211 + 16*iTrigger, &intValue, 1);
+ m_triggersData.back().m_triggerRepeat = intValue;
+ d.readBool(212 + 16*iTrigger, &boolValue, true);
+ m_triggersData.back().m_triggerPositiveEdge = boolValue;
+ d.readBool(213 + 16*iTrigger, &boolValue, false);
+ m_triggersData.back().m_triggerBothEdges = boolValue;
+ d.readS32(214 + 16*iTrigger, &intValue, 1);
+ m_triggersData.back().m_triggerLevelCoarse = intValue;
+ d.readS32(215 + 16*iTrigger, &intValue, 1);
+ m_triggersData.back().m_triggerLevelFine = intValue;
+ d.readS32(216 + 16*iTrigger, &intValue, 1);
+ m_triggersData.back().m_triggerDelayCoarse = intValue;
+ d.readS32(217 + 16*iTrigger, &intValue, 1);
+ m_triggersData.back().m_triggerDelayFine = intValue;
+ d.readFloat(218 + 16*iTrigger, &r, 1.0f);
+ d.readFloat(219 + 16*iTrigger, &g, 1.0f);
+ d.readFloat(220 + 16*iTrigger, &b, 1.0f);
+ m_triggersData.back().m_triggerColorR = r;
+ m_triggersData.back().m_triggerColorG = g;
+ m_triggersData.back().m_triggerColorB = b;
+ m_triggersData.back().m_triggerColor.setRedF(r);
+ m_triggersData.back().m_triggerColor.setGreenF(g);
+ m_triggersData.back().m_triggerColor.setBlueF(b);
+ d.readU32(221 + 16*iTrigger, &uintValue, 1);
+ m_triggersData.back().m_triggerHoldoff = uintValue;
+ }
+
+ return true;
+ }
+ else
+ {
+ resetToDefaults();
+ return false;
+ }
+}
diff --git a/sdrbase/dsp/glscopesettings.h b/sdrbase/dsp/glscopesettings.h
new file mode 100644
index 000000000..e6b793165
--- /dev/null
+++ b/sdrbase/dsp/glscopesettings.h
@@ -0,0 +1,169 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2019 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 //
+// (at your option) any later version. //
+// //
+// 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 "export.h"
+#include "dsp/dsptypes.h"
+#include "dsp/projector.h"
+#include "settings/serializable.h"
+
+class SDRBASE_API GLScopeSettings : public Serializable
+{
+public:
+ enum DisplayMode // TODO: copy of GLScope::DisplayMode => unify
+ {
+ DisplayXYH,
+ DisplayXYV,
+ DisplayX,
+ DisplayY,
+ DisplayPol
+ };
+
+ struct TraceData // TODO: copy of ScopeVis::TraceData => unify
+ {
+ Projector::ProjectionType m_projectionType; //!< Complex to real projection type
+ uint32_t m_inputIndex; //!< Input or feed index this trace is associated with
+ float m_amp; //!< Amplification factor
+ uint32_t m_ampIndex; //!< Index in list of amplification factors
+ float m_ofs; //!< Offset factor
+ int m_ofsCoarse; //!< Coarse offset slider value
+ int m_ofsFine; //!< Fine offset slider value
+ int m_traceDelay; //!< Trace delay in number of samples
+ int m_traceDelayCoarse; //!< Coarse delay slider value
+ int m_traceDelayFine; //!< Fine delay slider value
+ float m_triggerDisplayLevel; //!< Displayable trigger display level in -1:+1 scale. Off scale if not displayable.
+ QColor m_traceColor; //!< Trace display color
+ float m_traceColorR; //!< Trace display color - red shortcut
+ float m_traceColorG; //!< Trace display color - green shortcut
+ float m_traceColorB; //!< Trace display color - blue shortcut
+ bool m_hasTextOverlay; //!< True if a text overlay has to be displayed
+ QString m_textOverlay; //!< Text overlay to display
+ bool m_viewTrace; //!< Trace visibility
+
+ TraceData()
+ {
+ resetToDefaults();
+ }
+
+ void setColor(QColor color)
+ {
+ m_traceColor = color;
+ qreal r,g,b,a;
+ m_traceColor.getRgbF(&r, &g, &b, &a);
+ m_traceColorR = r;
+ m_traceColorG = g;
+ m_traceColorB = b;
+ }
+
+ void resetToDefaults()
+ {
+ m_projectionType = Projector::ProjectionReal;
+ m_inputIndex = 0;
+ m_amp = 1.0f;
+ m_ampIndex = 0;
+ m_ofs = 0.0f;
+ m_ofsCoarse = 0;
+ m_ofsFine = 0;
+ m_traceDelay = 0;
+ m_traceDelayCoarse = 0;
+ m_traceDelayFine = 0;
+ m_triggerDisplayLevel = 2.0; // Over scale by default (2.0)
+ m_traceColor = QColor(255,255,64);
+ m_hasTextOverlay = false;
+ m_viewTrace = true;
+ setColor(m_traceColor);
+ }
+ };
+
+ struct TriggerData // TODO: copy of ScopeVis::TriggerData => unify
+ {
+ Projector::ProjectionType m_projectionType; //!< Complex to real projection type
+ uint32_t m_inputIndex; //!< Input or feed index this trigger is associated with
+ Real m_triggerLevel; //!< Level in real units
+ int m_triggerLevelCoarse;
+ int m_triggerLevelFine;
+ bool m_triggerPositiveEdge; //!< Trigger on the positive edge (else negative)
+ bool m_triggerBothEdges; //!< Trigger on both edges (else only one)
+ uint32_t m_triggerHoldoff; //!< Trigger holdoff in number of samples
+ uint32_t m_triggerDelay; //!< Delay before the trigger is kicked off in number of samples (trigger delay)
+ double m_triggerDelayMult; //!< Trigger delay as a multiplier of trace length
+ int m_triggerDelayCoarse;
+ int m_triggerDelayFine;
+ uint32_t m_triggerRepeat; //!< Number of trigger conditions before the final decisive trigger
+ QColor m_triggerColor; //!< Trigger line display color
+ float m_triggerColorR; //!< Trigger line display color - red shortcut
+ float m_triggerColorG; //!< Trigger line display color - green shortcut
+ float m_triggerColorB; //!< Trigger line display color - blue shortcut
+
+ TriggerData()
+ {
+ resetToDefaults();
+ }
+
+ void setColor(QColor color)
+ {
+ m_triggerColor = color;
+ qreal r,g,b,a;
+ m_triggerColor.getRgbF(&r, &g, &b, &a);
+ m_triggerColorR = r;
+ m_triggerColorG = g;
+ m_triggerColorB = b;
+ }
+
+ void resetToDefaults()
+ {
+ m_projectionType = Projector::ProjectionReal;
+ m_inputIndex = 0;
+ m_triggerLevel = 0.0f;
+ m_triggerLevelCoarse = 0;
+ m_triggerLevelFine = 0;
+ m_triggerPositiveEdge = true;
+ m_triggerBothEdges = false;
+ m_triggerHoldoff = 1;
+ m_triggerDelay = 0;
+ m_triggerDelayMult = 0.0;
+ m_triggerDelayCoarse = 0;
+ m_triggerDelayFine = 0;
+ m_triggerRepeat = 0;
+ m_triggerColor = QColor(0,255,0);
+ setColor(m_triggerColor);
+ }
+ };
+
+ DisplayMode m_displayMode;
+ int m_traceIntensity;
+ int m_gridIntensity;
+ int m_time;
+ int m_timeOfs;
+ int m_traceLen;
+ int m_trigPre;
+ std::vector m_tracesData;
+ std::vector m_triggersData;
+
+ GLScopeSettings();
+ virtual ~GLScopeSettings();
+
+ void resetToDefaults();
+
+ virtual QByteArray serialize() const;
+ virtual bool deserialize(const QByteArray& data);
+
+};
\ No newline at end of file
diff --git a/sdrbase/dsp/glspectrumsettings.cpp b/sdrbase/dsp/glspectrumsettings.cpp
index 3dd8c7dd3..679d1327e 100644
--- a/sdrbase/dsp/glspectrumsettings.cpp
+++ b/sdrbase/dsp/glspectrumsettings.cpp
@@ -24,6 +24,10 @@ GLSpectrumSettings::GLSpectrumSettings()
resetToDefaults();
}
+GLSpectrumSettings::~GLSpectrumSettings()
+{}
+
+
void GLSpectrumSettings::resetToDefaults()
{
m_fftSize = 1024;
diff --git a/sdrbase/dsp/glspectrumsettings.h b/sdrbase/dsp/glspectrumsettings.h
index a49094caa..4e74f023d 100644
--- a/sdrbase/dsp/glspectrumsettings.h
+++ b/sdrbase/dsp/glspectrumsettings.h
@@ -19,8 +19,9 @@
#include "export.h"
#include "dsp/dsptypes.h"
+#include "settings/serializable.h"
-class SDRBASE_API GLSpectrumSettings
+class SDRBASE_API GLSpectrumSettings : public Serializable
{
public:
enum AveragingMode
@@ -56,10 +57,11 @@ public:
bool m_linear; //!< linear else logarithmic scale
GLSpectrumSettings();
+ virtual ~GLSpectrumSettings();
void resetToDefaults();
- QByteArray serialize() const;
- bool deserialize(const QByteArray& data);
+ virtual QByteArray serialize() const;
+ virtual bool deserialize(const QByteArray& data);
static int getAveragingMaxScale(AveragingMode averagingMode);
static int getAveragingValue(int averagingIndex, AveragingMode averagingMode);