diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt
index 57967a1d1..e90989e35 100644
--- a/sdrbase/CMakeLists.txt
+++ b/sdrbase/CMakeLists.txt
@@ -38,6 +38,7 @@ set(sdrbase_SOURCES
dsp/nco.cpp
dsp/ncof.cpp
dsp/phaselock.cpp
+ dsp/projector.cpp
dsp/samplesinkfifo.cpp
dsp/samplesourcefifo.cpp
dsp/samplesinkfifodoublebuffered.cpp
@@ -139,6 +140,7 @@ set(sdrbase_HEADERS
dsp/ncof.h
dsp/phasediscri.h
dsp/phaselock.h
+ dsp/projector.h
dsp/recursivefilters.h
dsp/samplesinkfifo.h
dsp/samplesourcefifo.h
diff --git a/sdrbase/dsp/projector.cpp b/sdrbase/dsp/projector.cpp
new file mode 100644
index 000000000..6eeea26cd
--- /dev/null
+++ b/sdrbase/dsp/projector.cpp
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2017 F4EXB //
+// written by Edouard Griffiths //
+// //
+// 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 //
+// //
+// 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 "projector.h"
+#include "symsync.h" // dependency on liquid-dsp
+
+Projector::Projector(ProjectionType projectionType) :
+ m_projectionType(projectionType),
+ m_prevArg(0.0f),
+ m_cache(0),
+ m_cacheMaster(true)
+{}
+
+Projector::~Projector()
+{}
+
+Real Projector::run(const Sample& s)
+{
+ Real v;
+
+ if ((m_cache) && !m_cacheMaster) {
+ return m_cache[(int) m_projectionType];
+ }
+ else
+ {
+ switch (m_projectionType)
+ {
+ case ProjectionImag:
+ v = s.m_imag / SDR_RX_SCALEF;
+ break;
+ case ProjectionMagLin:
+ {
+ Real re = s.m_real / SDR_RX_SCALEF;
+ Real im = s.m_imag / SDR_RX_SCALEF;
+ Real magsq = re*re + im*im;
+ v = std::sqrt(magsq);
+ }
+ break;
+ case ProjectionMagDB:
+ {
+ Real re = s.m_real / SDR_RX_SCALEF;
+ Real im = s.m_imag / SDR_RX_SCALEF;
+ Real magsq = re*re + im*im;
+ v = log10f(magsq) * 10.0f;
+ }
+ break;
+ case ProjectionPhase:
+ v = std::atan2((float) s.m_imag, (float) s.m_real) / M_PI;
+ break;
+ case ProjectionDPhase:
+ {
+ Real curArg = std::atan2((float) s.m_imag, (float) s.m_real);
+ Real dPhi = (curArg - m_prevArg) / M_PI;
+ m_prevArg = curArg;
+
+ if (dPhi < -1.0f) {
+ dPhi += 2.0f;
+ } else if (dPhi > 1.0f) {
+ dPhi -= 2.0f;
+ }
+
+ v = dPhi;
+ }
+ break;
+ case ProjectionReal:
+ default:
+ v = s.m_real / SDR_RX_SCALEF;
+ break;
+ }
+
+ if (m_cache) {
+ m_cache[(int) m_projectionType] = v;
+ }
+
+ return v;
+ }
+}
+
diff --git a/sdrbase/dsp/projector.h b/sdrbase/dsp/projector.h
new file mode 100644
index 000000000..1370fca44
--- /dev/null
+++ b/sdrbase/dsp/projector.h
@@ -0,0 +1,53 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2017 F4EXB //
+// written by Edouard Griffiths //
+// //
+// 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 //
+// //
+// 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 "dsptypes.h"
+
+class SymbolSynchronizer;
+
+class Projector
+{
+public:
+ enum ProjectionType
+ {
+ ProjectionReal = 0, //!< Extract real part
+ ProjectionImag, //!< Extract imaginary part
+ ProjectionMagLin, //!< Calculate linear magnitude or modulus
+ ProjectionMagDB, //!< Calculate logarithmic (dB) of squared magnitude
+ ProjectionPhase, //!< Calculate phase
+ ProjectionDPhase, //!< Calculate phase derivative i.e. instantaneous frequency scaled to sample rate
+ ProjectionClock, //!< Clock projection (symbol synchronization)
+ nbProjectionTypes //!< Gives the number of projections in the enum
+ };
+
+ Projector(ProjectionType projectionType);
+ ~Projector();
+
+ ProjectionType getProjectionType() const { return m_projectionType; }
+ void settProjectionType(ProjectionType projectionType) { m_projectionType = projectionType; }
+ void setCache(Real *cache) { m_cache = cache; }
+ void setCacheMaster(bool cacheMaster) { m_cacheMaster = cacheMaster; }
+
+ Real run(const Sample& s);
+
+private:
+ ProjectionType m_projectionType;
+ Real m_prevArg;
+ Real *m_cache;
+ bool m_cacheMaster;
+ SymbolSynchronizer *m_symSync;
+};
diff --git a/sdrgui/dsp/scopevisng.cpp b/sdrgui/dsp/scopevisng.cpp
index f44485055..c8fdb6ed2 100644
--- a/sdrgui/dsp/scopevisng.cpp
+++ b/sdrgui/dsp/scopevisng.cpp
@@ -62,7 +62,7 @@ ScopeVisNG::ScopeVisNG(GLScopeNG* glScope) :
setObjectName("ScopeVisNG");
m_traceDiscreteMemory.resize(m_traceChunkSize); // arbitrary
m_glScope->setTraces(&m_traces.m_tracesData, &m_traces.m_traces[0]);
- for (int i = 0; i < (int) nbProjectionTypes; i++) {
+ for (int i = 0; i < (int) Projector::nbProjectionTypes; i++) {
m_projectorCache[i] = 0.0;
}
}
@@ -449,18 +449,18 @@ int ScopeVisNG::processTraces(const SampleVector::const_iterator& cbegin, const
continue;
}
- ProjectionType projectionType = itData->m_projectionType;
+ Projector::ProjectionType projectionType = itData->m_projectionType;
if (itCtl->m_traceCount[m_traces.currentBufferIndex()] < m_traceSize)
{
uint32_t& traceCount = itCtl->m_traceCount[m_traces.currentBufferIndex()]; // reference for code clarity
float v;
- if (projectionType == ProjectionMagLin)
+ if (projectionType == Projector::ProjectionMagLin)
{
v = (itCtl->m_projector.run(*begin) - itData->m_ofs)*itData->m_amp - 1.0f;
}
- else if (projectionType == ProjectionMagDB)
+ else if (projectionType == Projector::ProjectionMagDB)
{
// there is no processing advantage in direct calculation without projector
// uint32_t magsq = begin->m_real*begin->m_real + begin->m_imag*begin->m_imag;
@@ -786,8 +786,8 @@ void ScopeVisNG::updateMaxTraceDelay()
{
int maxTraceDelay = 0;
bool allocateCache = false;
- uint32_t projectorCounts[(int) nbProjectionTypes];
- memset(projectorCounts, 0, ((int) nbProjectionTypes)*sizeof(uint32_t));
+ uint32_t projectorCounts[(int) Projector::nbProjectionTypes];
+ memset(projectorCounts, 0, ((int) Projector::nbProjectionTypes)*sizeof(uint32_t));
std::vector::iterator itData = m_traces.m_tracesData.begin();
std::vector::iterator itCtrl = m_traces.m_tracesControl.begin();
@@ -799,7 +799,7 @@ void ScopeVisNG::updateMaxTraceDelay()
}
if (itData->m_projectionType < 0) {
- itData->m_projectionType = ProjectionReal;
+ itData->m_projectionType = Projector::ProjectionReal;
}
if (projectorCounts[(int) itData->m_projectionType] > 0)
@@ -861,11 +861,11 @@ void ScopeVisNG::computeDisplayTriggerLevels()
float levelPowerdB = (100.0f * (level - 1.0f));
float v;
- if (itData->m_projectionType == ProjectionMagLin)
+ if (itData->m_projectionType == Projector::ProjectionMagLin)
{
v = (levelPowerLin - itData->m_ofs)*itData->m_amp - 1.0f;
}
- else if (itData->m_projectionType == ProjectionMagDB)
+ else if (itData->m_projectionType == Projector::ProjectionMagDB)
{
float ofsdB = itData->m_ofs * 100.0f;
v = ((levelPowerdB + 100.0f - ofsdB)*itData->m_amp)/50.0f - 1.0f;
diff --git a/sdrgui/dsp/scopevisng.h b/sdrgui/dsp/scopevisng.h
index dc5ba22bd..5f022c2bc 100644
--- a/sdrgui/dsp/scopevisng.h
+++ b/sdrgui/dsp/scopevisng.h
@@ -29,6 +29,7 @@
#include
#include "dsp/dsptypes.h"
#include "dsp/basebandsamplesink.h"
+#include "dsp/projector.h"
#include "export.h"
#include "util/message.h"
#include "util/doublebuffer.h"
@@ -41,20 +42,9 @@ class GLScopeNG;
class SDRGUI_API ScopeVisNG : public BasebandSampleSink {
public:
- enum ProjectionType
- {
- ProjectionReal = 0, //!< Extract real part
- ProjectionImag, //!< Extract imaginary part
- ProjectionMagLin, //!< Calculate linear magnitude or modulus
- ProjectionMagDB, //!< Calculate logarithmic (dB) of squared magnitude
- ProjectionPhase, //!< Calculate phase
- ProjectionDPhase, //!< Calculate phase derivative i.e. instantaneous frequency scaled to sample rate
- nbProjectionTypes //!< Gives the number of projections in the enum
- };
-
struct TraceData
{
- ProjectionType m_projectionType; //!< Complex to real projection type
+ 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
@@ -74,7 +64,7 @@ public:
bool m_viewTrace; //!< Trace visibility
TraceData() :
- m_projectionType(ProjectionReal),
+ m_projectionType(Projector::ProjectionReal),
m_inputIndex(0),
m_amp(1.0f),
m_ampIndex(0),
@@ -106,7 +96,7 @@ public:
struct TriggerData
{
- ProjectionType m_projectionType; //!< Complex to real projection type
+ 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;
@@ -124,7 +114,7 @@ public:
float m_triggerColorB; //!< Trigger line display color - blue shortcut
TriggerData() :
- m_projectionType(ProjectionReal),
+ m_projectionType(Projector::ProjectionReal),
m_inputIndex(0),
m_triggerLevel(0.0f),
m_triggerLevelCoarse(0),
@@ -512,96 +502,6 @@ private:
// ---------------------------------------------
- /**
- * Projection stuff
- */
- class Projector
- {
- public:
- Projector(ProjectionType projectionType) :
- m_projectionType(projectionType),
- m_prevArg(0.0f),
- m_cache(0),
- m_cacheMaster(true)
- {}
-
- ~Projector()
- {}
-
- ProjectionType getProjectionType() const { return m_projectionType; }
- void settProjectionType(ProjectionType projectionType) { m_projectionType = projectionType; }
- void setCache(Real *cache) { m_cache = cache; }
- void setCacheMaster(bool cacheMaster) { m_cacheMaster = cacheMaster; }
-
- Real run(const Sample& s)
- {
- Real v;
-
- if ((m_cache) && !m_cacheMaster) {
- return m_cache[(int) m_projectionType];
- }
- else
- {
- switch (m_projectionType)
- {
- case ProjectionImag:
- v = s.m_imag / SDR_RX_SCALEF;
- break;
- case ProjectionMagLin:
- {
- Real re = s.m_real / SDR_RX_SCALEF;
- Real im = s.m_imag / SDR_RX_SCALEF;
- Real magsq = re*re + im*im;
- v = std::sqrt(magsq);
- }
- break;
- case ProjectionMagDB:
- {
- Real re = s.m_real / SDR_RX_SCALEF;
- Real im = s.m_imag / SDR_RX_SCALEF;
- Real magsq = re*re + im*im;
- v = log10f(magsq) * 10.0f;
- }
- break;
- case ProjectionPhase:
- v = std::atan2((float) s.m_imag, (float) s.m_real) / M_PI;
- break;
- case ProjectionDPhase:
- {
- Real curArg = std::atan2((float) s.m_imag, (float) s.m_real);
- Real dPhi = (curArg - m_prevArg) / M_PI;
- m_prevArg = curArg;
-
- if (dPhi < -1.0f) {
- dPhi += 2.0f;
- } else if (dPhi > 1.0f) {
- dPhi -= 2.0f;
- }
-
- v = dPhi;
- }
- break;
- case ProjectionReal:
- default:
- v = s.m_real / SDR_RX_SCALEF;
- break;
- }
-
- if (m_cache) {
- m_cache[(int) m_projectionType] = v;
- }
-
- return v;
- }
- }
-
- private:
- ProjectionType m_projectionType;
- Real m_prevArg;
- Real *m_cache;
- bool m_cacheMaster;
- };
-
/**
* Trigger stuff
*/
@@ -623,7 +523,7 @@ private:
uint32_t m_triggerCounter; //!< Counter of trigger occurences
TriggerCondition(const TriggerData& triggerData) :
- m_projector(ProjectionReal),
+ m_projector(Projector::ProjectionReal),
m_triggerData(triggerData),
m_prevCondition(false),
m_triggerDelayCount(0),
@@ -785,7 +685,7 @@ private:
Real m_sumPow; //!< Cumulative power over the current trace for MagDB overlay display
int m_nbPow; //!< Number of power samples over the current trace for MagDB overlay display
- TraceControl() : m_projector(ProjectionReal)
+ TraceControl() : m_projector(Projector::ProjectionReal)
{
reset();
}
@@ -794,7 +694,7 @@ private:
{
}
- void initProjector(ProjectionType projectionType)
+ void initProjector(Projector::ProjectionType projectionType)
{
m_projector.settProjectionType(projectionType);
}
@@ -967,9 +867,9 @@ private:
bool condition, trigger;
- if (triggerCondition.m_projector.getProjectionType() == ProjectionMagDB) {
+ if (triggerCondition.m_projector.getProjectionType() == Projector::ProjectionMagDB) {
condition = triggerCondition.m_projector.run(s) > m_levelPowerDB;
- } else if (triggerCondition.m_projector.getProjectionType() == ProjectionMagLin) {
+ } else if (triggerCondition.m_projector.getProjectionType() == Projector::ProjectionMagLin) {
condition = triggerCondition.m_projector.run(s) > m_levelPowerLin;
} else {
condition = triggerCondition.m_projector.run(s) > m_level;
@@ -1040,7 +940,7 @@ private:
int m_maxTraceDelay; //!< Maximum trace delay
TriggerComparator m_triggerComparator; //!< Compares sample level to trigger level
QMutex m_mutex;
- Real m_projectorCache[(int) nbProjectionTypes];
+ Real m_projectorCache[(int) Projector::nbProjectionTypes];
bool m_triggerOneShot; //!< True when one shot mode is active
bool m_triggerWaitForReset; //!< In one shot mode suspended until reset by UI
uint32_t m_currentTraceMemoryIndex; //!< The current index of trace in memory (0: current)
diff --git a/sdrgui/gui/glscopeng.cpp b/sdrgui/gui/glscopeng.cpp
index 30f32bac0..3bda3ff10 100644
--- a/sdrgui/gui/glscopeng.cpp
+++ b/sdrgui/gui/glscopeng.cpp
@@ -1868,22 +1868,22 @@ void GLScopeNG::setYScale(ScaleEngine& scale, uint32_t highlightedTraceIndex)
switch (traceData.m_projectionType)
{
- case ScopeVisNG::ProjectionMagDB: // dB scale
+ case Projector::ProjectionMagDB: // dB scale
scale.setRange(Unit::Decibel, pow_floor, pow_floor + pow_range);
break;
- case ScopeVisNG::ProjectionMagLin:
+ case Projector::ProjectionMagLin:
if (amp_range < 2.0) {
scale.setRange(Unit::None, amp_ofs * 1000.0, amp_range * 1000.0 + amp_ofs * 1000.0);
} else {
scale.setRange(Unit::None, amp_ofs, amp_range + amp_ofs);
}
break;
- case ScopeVisNG::ProjectionPhase: // Phase or frequency
- case ScopeVisNG::ProjectionDPhase:
+ case Projector::ProjectionPhase: // Phase or frequency
+ case Projector::ProjectionDPhase:
scale.setRange(Unit::None, -1.0/traceData.m_amp + amp_ofs, 1.0/traceData.m_amp + amp_ofs);
break;
- case ScopeVisNG::ProjectionReal: // Linear generic
- case ScopeVisNG::ProjectionImag:
+ case Projector::ProjectionReal: // Linear generic
+ case Projector::ProjectionImag:
default:
if (amp_range < 2.0) {
scale.setRange(Unit::None, - amp_range * 500.0 + amp_ofs * 1000.0, amp_range * 500.0 + amp_ofs * 1000.0);
diff --git a/sdrgui/gui/glscopenggui.cpp b/sdrgui/gui/glscopenggui.cpp
index 894d88ced..12f043b35 100644
--- a/sdrgui/gui/glscopenggui.cpp
+++ b/sdrgui/gui/glscopenggui.cpp
@@ -944,10 +944,10 @@ void GLScopeNGGUI::setTimeOfsDisplay()
void GLScopeNGGUI::setAmpScaleDisplay()
{
- ScopeVisNG::ProjectionType projectionType = (ScopeVisNG::ProjectionType) ui->traceMode->currentIndex();
+ Projector::ProjectionType projectionType = (Projector::ProjectionType) ui->traceMode->currentIndex();
double ampValue = amps[ui->amp->value()];
- if (projectionType == ScopeVisNG::ProjectionMagDB)
+ if (projectionType == Projector::ProjectionMagDB)
{
double displayValue = ampValue*500.0f;
@@ -975,10 +975,10 @@ void GLScopeNGGUI::setAmpScaleDisplay()
void GLScopeNGGUI::setAmpOfsDisplay()
{
- ScopeVisNG::ProjectionType projectionType = (ScopeVisNG::ProjectionType) ui->traceMode->currentIndex();
+ Projector::ProjectionType projectionType = (Projector::ProjectionType) ui->traceMode->currentIndex();
double o = (ui->ofsCoarse->value() * 10.0f) + (ui->ofsFine->value() / 20.0f);
- if (projectionType == ScopeVisNG::ProjectionMagDB)
+ if (projectionType == Projector::ProjectionMagDB)
{
ui->ofsText->setText(tr("%1\ndB").arg(o/10.0f - 100.0f, 0, 'f', 1));
}
@@ -986,7 +986,7 @@ void GLScopeNGGUI::setAmpOfsDisplay()
{
double a;
- if (projectionType == ScopeVisNG::ProjectionMagLin)
+ if (projectionType == Projector::ProjectionMagLin)
{
a = o/2000.0f;
}
@@ -1040,19 +1040,19 @@ void GLScopeNGGUI::setTrigIndexDisplay()
void GLScopeNGGUI::setTrigLevelDisplay()
{
double t = (ui->trigLevelCoarse->value() / 100.0f) + (ui->trigLevelFine->value() / 20000.0f);
- ScopeVisNG::ProjectionType projectionType = (ScopeVisNG::ProjectionType) ui->trigMode->currentIndex();
+ Projector::ProjectionType projectionType = (Projector::ProjectionType) ui->trigMode->currentIndex();
ui->trigLevelCoarse->setToolTip(QString("Trigger level coarse: %1 %").arg(ui->trigLevelCoarse->value() / 100.0f));
ui->trigLevelFine->setToolTip(QString("Trigger level fine: %1 ppm").arg(ui->trigLevelFine->value() * 50));
- if (projectionType == ScopeVisNG::ProjectionMagDB) {
+ if (projectionType == Projector::ProjectionMagDB) {
ui->trigLevelText->setText(tr("%1\ndB").arg(100.0 * (t - 1.0), 0, 'f', 1));
}
else
{
double a;
- if (projectionType == ScopeVisNG::ProjectionMagLin) {
+ if (projectionType == Projector::ProjectionMagLin) {
a = 1.0 + t;
} else {
a = t;
@@ -1146,12 +1146,12 @@ void GLScopeNGGUI::changeCurrentTrigger()
void GLScopeNGGUI::fillProjectionCombo(QComboBox* comboBox)
{
- comboBox->addItem("Real", ScopeVisNG::ProjectionReal);
- comboBox->addItem("Imag", ScopeVisNG::ProjectionImag);
- comboBox->addItem("Mag", ScopeVisNG::ProjectionMagLin);
- comboBox->addItem("MagdB", ScopeVisNG::ProjectionMagDB);
- comboBox->addItem("Phi", ScopeVisNG::ProjectionPhase);
- comboBox->addItem("dPhi", ScopeVisNG::ProjectionDPhase);
+ comboBox->addItem("Real", Projector::ProjectionReal);
+ comboBox->addItem("Imag", Projector::ProjectionImag);
+ comboBox->addItem("Mag", Projector::ProjectionMagLin);
+ comboBox->addItem("MagdB", Projector::ProjectionMagDB);
+ comboBox->addItem("Phi", Projector::ProjectionPhase);
+ comboBox->addItem("dPhi", Projector::ProjectionDPhase);
}
void GLScopeNGGUI::disableLiveMode(bool disable)
@@ -1176,8 +1176,8 @@ void GLScopeNGGUI::disableLiveMode(bool disable)
void GLScopeNGGUI::fillTraceData(ScopeVisNG::TraceData& traceData)
{
- traceData.m_projectionType = (ScopeVisNG::ProjectionType) ui->traceMode->currentIndex();
- traceData.m_hasTextOverlay = (traceData.m_projectionType == ScopeVisNG::ProjectionMagDB);
+ traceData.m_projectionType = (Projector::ProjectionType) ui->traceMode->currentIndex();
+ traceData.m_hasTextOverlay = (traceData.m_projectionType == Projector::ProjectionMagDB);
traceData.m_textOverlay.clear();
traceData.m_inputIndex = 0;
traceData.m_amp = 0.2 / amps[ui->amp->value()];
@@ -1186,7 +1186,7 @@ void GLScopeNGGUI::fillTraceData(ScopeVisNG::TraceData& traceData)
traceData.m_ofsCoarse = ui->ofsCoarse->value();
traceData.m_ofsFine = ui->ofsFine->value();
- if (traceData.m_projectionType == ScopeVisNG::ProjectionMagLin) {
+ if (traceData.m_projectionType == Projector::ProjectionMagLin) {
traceData.m_ofs = ((10.0 * ui->ofsCoarse->value()) + (ui->ofsFine->value() / 20.0)) / 2000.0f;
} else {
traceData.m_ofs = ((10.0 * ui->ofsCoarse->value()) + (ui->ofsFine->value() / 20.0)) / 1000.0f;
@@ -1201,7 +1201,7 @@ void GLScopeNGGUI::fillTraceData(ScopeVisNG::TraceData& traceData)
void GLScopeNGGUI::fillTriggerData(ScopeVisNG::TriggerData& triggerData)
{
- triggerData.m_projectionType = (ScopeVisNG::ProjectionType) ui->trigMode->currentIndex();
+ triggerData.m_projectionType = (Projector::ProjectionType) ui->trigMode->currentIndex();
triggerData.m_inputIndex = 0;
triggerData.m_triggerLevel = (ui->trigLevelCoarse->value() / 100.0) + (ui->trigLevelFine->value() / 20000.0);
triggerData.m_triggerLevelCoarse = ui->trigLevelCoarse->value();