From 44e764f4925de53807ac523bf43412c05cbf8f11 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 5 Feb 2017 04:41:32 +0100 Subject: [PATCH] New scope: interim state (7) --- sdrbase/dsp/scopevisng.cpp | 65 +++++++++--- sdrbase/dsp/scopevisng.h | 82 ++++++++++++--- sdrbase/gui/glscopeng.cpp | 77 ++++++++++---- sdrbase/gui/glscopeng.h | 9 +- sdrbase/gui/glscopenggui.cpp | 196 ++++++++++++++++++++++++++++++++--- sdrbase/gui/glscopenggui.h | 17 ++- sdrbase/gui/glscopenggui.ui | 120 ++++++++++++++++++--- 7 files changed, 483 insertions(+), 83 deletions(-) diff --git a/sdrbase/dsp/scopevisng.cpp b/sdrbase/dsp/scopevisng.cpp index d3f439cd8..df9c3d2a6 100644 --- a/sdrbase/dsp/scopevisng.cpp +++ b/sdrbase/dsp/scopevisng.cpp @@ -53,12 +53,6 @@ ScopeVisNG::ScopeVisNG(GLScopeNG* glScope) : ScopeVisNG::~ScopeVisNG() { - std::vector::iterator it = m_triggerConditions.begin(); - - for (; it != m_triggerConditions.end(); ++it) - { - delete it->m_projector; - } } void ScopeVisNG::setSampleRate(int sampleRate) @@ -70,9 +64,9 @@ void ScopeVisNG::setSampleRate(int sampleRate) } } -void ScopeVisNG::configure(uint traceSize) +void ScopeVisNG::configure(uint32_t traceSize, uint32_t timeOfsProMill) { - Message* cmd = MsgConfigureScopeVisNG::create(traceSize); + Message* cmd = MsgConfigureScopeVisNG::create(traceSize, timeOfsProMill); getInputMessageQueue()->push(cmd); } @@ -359,6 +353,18 @@ int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackB } +void ScopeVisNG::initTrace(Trace& trace) +{ + int shift = (m_timeOfsProMill / 1000.0) * m_traceSize; + + for (int i = 0; i < m_traceSize; i++) + { + trace.m_trace[2*(trace.m_traceCount)] = (trace.m_traceCount - shift); // display x + trace.m_trace[2*(trace.m_traceCount) + 1] = 0.0f; // display y + trace.m_traceCount++; + } +} + void ScopeVisNG::start() { } @@ -381,22 +387,49 @@ bool ScopeVisNG::handleMessage(const Message& message) else if (MsgConfigureScopeVisNG::match(message)) { MsgConfigureScopeVisNG& conf = (MsgConfigureScopeVisNG&) message; - m_traceSize = conf.getTraceSize(); - std::vector::iterator it = m_traces.begin(); - for (; it != m_traces.end(); ++it) { - it->resize(m_traceSize); + uint32_t traceSize = conf.getTraceSize(); + uint32_t timeOfsProMill = conf.getTimeOfsProMill(); + + if (m_traceSize != traceSize) + { + m_traceSize = traceSize; + + std::vector::iterator it = m_traces.begin(); + + for (; it != m_traces.end(); ++it) + { + it->resize(m_traceSize); + initTrace(*it); + } + + m_traceDiscreteMemory.resize(m_traceSize); + + if (m_glScope) { + m_glScope->setTraceSize(m_traceSize); + } } - m_traceDiscreteMemory.resize(m_traceSize); + if (m_timeOfsProMill != timeOfsProMill) + { + m_timeOfsProMill = timeOfsProMill; + + if (m_glScope) { + m_glScope->setTimeOfsProMill(m_timeOfsProMill); + } + } + + qDebug() << "ScopeVisNG::handleMessage: MsgConfigureScopeVisNG:" + << " m_traceSize: " << m_traceSize + << " m_timeOfsProMill: " << m_timeOfsProMill; - qDebug() << "ScopeVisNG::handleMessage: MsgConfigureScopeVisNG: m_traceSize: " << m_traceSize; return true; } else if (MsgScopeVisNGAddTrigger::match(message)) { MsgScopeVisNGAddTrigger& conf = (MsgScopeVisNGAddTrigger&) message; m_triggerConditions.push_back(TriggerCondition(conf.getTriggerData())); + m_triggerConditions.back().init(); return true; } else if (MsgScopeVisNGChangeTrigger::match(message)) @@ -425,6 +458,9 @@ bool ScopeVisNG::handleMessage(const Message& message) { MsgScopeVisNGAddTrace& conf = (MsgScopeVisNGAddTrace&) message; m_traces.push_back(Trace(conf.getTraceData(), m_traceSize)); + m_traces.back().init(); + initTrace(m_traces.back()); + m_glScope->addTrace(&m_traces.back()); return true; } else if (MsgScopeVisNGChangeTrace::match(message)) @@ -445,6 +481,7 @@ bool ScopeVisNG::handleMessage(const Message& message) if (traceIndex < m_traces.size()) { m_traces.erase(m_traces.begin() + traceIndex); + m_glScope->removeTrace(traceIndex); } return true; diff --git a/sdrbase/dsp/scopevisng.h b/sdrbase/dsp/scopevisng.h index 2898283b0..608c4266e 100644 --- a/sdrbase/dsp/scopevisng.h +++ b/sdrbase/dsp/scopevisng.h @@ -91,7 +91,7 @@ public: {} }; - typedef std::vector DisplayTraces; + typedef std::vector DisplayTraces; static const uint m_traceChunkSize; static const uint m_nbTriggers = 10; @@ -100,7 +100,7 @@ public: virtual ~ScopeVisNG(); void setSampleRate(int sampleRate); - void configure(uint32_t traceSize); + void configure(uint32_t traceSize, uint32_t timeOfsProMill); void addTrace(const TraceData& traceData); void changeTrace(const TraceData& traceData, uint32_t traceIndex); void removeTrace(uint32_t traceIndex); @@ -122,18 +122,23 @@ private: public: static MsgConfigureScopeVisNG* create( - uint32_t traceSize) + uint32_t traceSize, + uint32_t timeOfsProMill) { - return new MsgConfigureScopeVisNG(traceSize); + return new MsgConfigureScopeVisNG(traceSize, timeOfsProMill); } uint32_t getTraceSize() const { return m_traceSize; } + uint32_t getTimeOfsProMill() const { return m_timeOfsProMill; } private: uint32_t m_traceSize; + uint32_t m_timeOfsProMill; - MsgConfigureScopeVisNG(uint32_t traceSize) : - m_traceSize(traceSize) + MsgConfigureScopeVisNG(uint32_t traceSize, + uint32_t timeOfsProMill) : + m_traceSize(traceSize), + m_timeOfsProMill(timeOfsProMill) {} }; @@ -275,9 +280,10 @@ private: { public: Projector(ProjectionType projectionType) : m_projectionType(projectionType) {} + virtual ~Projector() {} ProjectionType getProjectionType() const { return m_projectionType; } - virtual Real run(const Sample& s) {} + virtual Real run(const Sample& s) = 0; private: ProjectionType m_projectionType; }; @@ -287,6 +293,7 @@ private: { public: ProjectorReal() : Projector(ProjectionReal) {} + virtual ~ProjectorReal() {} virtual Real run(const Sample& s) { return s.m_real / 32768.0f; } }; @@ -295,6 +302,7 @@ private: { public: ProjectorImag() : Projector(ProjectionImag) {} + virtual ~ProjectorImag() {} virtual Real run(const Sample& s) { return s.m_imag / 32768.0f; } }; @@ -303,6 +311,7 @@ private: { public: ProjectorMagLin() : Projector(ProjectionMagLin) {} + virtual ~ProjectorMagLin() {} virtual Real run(const Sample& s) { uint32_t magsq = s.m_real*s.m_real + s.m_imag*s.m_imag; @@ -315,6 +324,7 @@ private: { public: ProjectorMagDB() : Projector(ProjectionMagDB) {} + virtual ~ProjectorMagDB() {} virtual Real run(const Sample& s) { uint32_t magsq = s.m_real*s.m_real + s.m_imag*s.m_imag; @@ -329,6 +339,7 @@ private: { public: ProjectorPhase() : Projector(ProjectionPhase) {} + virtual ~ProjectorPhase() {} virtual Real run(const Sample& s) { return std::atan2((float) s.m_imag, (float) s.m_real) / M_PI; } }; @@ -337,6 +348,7 @@ private: { public: ProjectorDPhase() : Projector(ProjectionDPhase), m_prevArg(0.0f) {} + virtual ~ProjectorDPhase() {} virtual Real run(const Sample& s) { Real curArg = std::atan2((float) s.m_imag, (float) s.m_real) / M_PI; @@ -356,6 +368,26 @@ private: Real m_prevArg; }; + static Projector *createProjector(ProjectionType projectionType) + { + //qDebug("ScopeVisNG::createProjector: projectionType: %d", projectionType); + switch (projectionType) + { + case ProjectionImag: + return new ProjectorImag(); + case ProjectionMagLin: + return new ProjectorMagLin(); + case ProjectionMagDB: + return new ProjectorMagDB(); + case ProjectionPhase: + return new ProjectorPhase(); + case ProjectionDPhase: + return new ProjectorDPhase(); + case ProjectionReal: + default: + return new ProjectorReal(); + } + } /** * Trigger stuff @@ -373,22 +405,30 @@ private: struct TriggerCondition { public: - Projector *m_projector; //!< Projector transform from complex trace to reaL trace usable for triggering + Projector *m_projector; TriggerData m_triggerData; //!< Trigger data bool m_prevCondition; //!< Condition (above threshold) at previous sample uint32_t m_triggerDelayCount; //!< Counter of samples for delay uint32_t m_triggerCounter; //!< Counter of trigger occurences TriggerCondition(const TriggerData& triggerData) : + m_projector(0), m_triggerData(triggerData), m_prevCondition(false), m_triggerDelayCount(0), m_triggerCounter(0) { - m_projector = new Projector(m_triggerData.m_projectionType); } - ~TriggerCondition() { delete m_projector; } + ~TriggerCondition() + { + if (m_projector) delete m_projector; + } + + void init() + { + m_projector = createProjector(m_triggerData.m_projectionType); + } void setData(const TriggerData& triggerData) { @@ -397,7 +437,7 @@ private: if (m_projector->getProjectionType() != m_triggerData.m_projectionType) { delete m_projector; - m_projector = new Projector(m_triggerData.m_projectionType); + m_projector = createProjector(m_triggerData.m_projectionType); } m_prevCondition = false; @@ -508,18 +548,23 @@ private: Trace(const TraceData& traceData, int traceSize) : DisplayTrace(traceData), + m_projector(0), m_traceSize(traceSize), m_maxTraceSize(traceSize), m_traceCount(0) { - m_projector = new Projector(m_traceData.m_projectionType); - m_trace = new float[2*m_traceSize]; } ~Trace() { - delete m_projector; - delete[] m_trace; + if (m_projector) delete m_projector; + if (m_trace) delete[] m_trace; + } + + void init() + { + m_projector = createProjector(m_traceData.m_projectionType); + m_trace = new float[2*m_traceSize]; } void setData(const TraceData& traceData) @@ -529,7 +574,7 @@ private: if (m_projector->getProjectionType() != m_traceData.m_projectionType) { delete m_projector; - m_projector = new Projector(m_traceData.m_projectionType); + m_projector = createProjector(m_traceData.m_projectionType); } } @@ -582,6 +627,11 @@ private: * - if not finished it returns -1 */ int processTraces(int beginPointDelta, int endPointDelta, TraceBackBuffer& traceBuffer, bool traceStart = false); + + /** + * Initialize a trace with zero values + */ + void initTrace(Trace& trace); }; diff --git a/sdrbase/gui/glscopeng.cpp b/sdrbase/gui/glscopeng.cpp index bf2104736..86003f383 100644 --- a/sdrbase/gui/glscopeng.cpp +++ b/sdrbase/gui/glscopeng.cpp @@ -38,7 +38,8 @@ GLScopeNG::GLScopeNG(QWidget* parent) : m_sampleRate(0), m_triggerPre(0), m_timeOfsProMill(0), - m_highlightedTraceIndex(0) + m_highlightedTraceIndex(0), + m_timeOffset(0) { setAttribute(Qt::WA_OpaquePaintEvent); connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick())); @@ -62,9 +63,46 @@ GLScopeNG::~GLScopeNG() cleanup(); } +void GLScopeNG::addTrace(ScopeVisNG::DisplayTrace *trace) +{ + m_traces.push_back(trace); + m_configChanged = true; +} + +void GLScopeNG::removeTrace(int index) +{ + if (index < m_traces.size()) { + m_traces.erase(m_traces.begin() + index); + } + + m_configChanged = true; +} + +void GLScopeNG::setDisplayGridIntensity(int intensity) +{ + m_displayGridIntensity = intensity; + if (m_displayGridIntensity > 100) { + m_displayGridIntensity = 100; + } else if (m_displayGridIntensity < 0) { + m_displayGridIntensity = 0; + } + update(); +} + +void GLScopeNG::setDisplayTraceIntensity(int intensity) +{ + m_displayTraceIntensity = intensity; + if (m_displayTraceIntensity > 100) { + m_displayTraceIntensity = 100; + } else if (m_displayTraceIntensity < 0) { + m_displayTraceIntensity = 0; + } + update(); +} + void GLScopeNG::newTraces() { - if (m_traces) + if (m_traces.size() > 0) { if(!m_mutex.tryLock(2)) return; @@ -261,7 +299,7 @@ void GLScopeNG::paintGL() // paint trace #1 if (m_traceSize > 0) { - const ScopeVisNG::DisplayTrace& trace = (*m_traces)[0]; + const ScopeVisNG::DisplayTrace* trace = m_traces[0]; int start = (m_timeOfsProMill/1000.0) * m_traceSize; int end = std::min(start + m_traceSize/m_timeBase, m_traceSize); if(end - start < 2) @@ -270,14 +308,14 @@ void GLScopeNG::paintGL() float rectX = m_glScopeRect1.x(); float rectY = m_glScopeRect1.y() + m_glScopeRect1.height() / 2.0f; float rectW = m_glScopeRect1.width() * (float)m_timeBase / (float)(m_traceSize - 1); - float rectH = -(m_glScopeRect1.height() / 2.0f) * trace.m_traceData.m_amp; + float rectH = -(m_glScopeRect1.height() / 2.0f) * trace->m_traceData.m_amp; QVector4D color(1.0f, 1.0f, 0.25f, m_displayTraceIntensity / 100.0f); QMatrix4x4 mat; mat.setToIdentity(); mat.translate(-1.0f + 2.0f * rectX, 1.0f - 2.0f * rectY); mat.scale(2.0f * rectW, -2.0f * rectH); - m_glShaderSimple.drawPolyline(mat, color, (GLfloat *) &trace.m_trace[2*start], end - start); + m_glShaderSimple.drawPolyline(mat, color, (GLfloat *) &trace->m_trace[2*start], end - start); } } @@ -347,17 +385,14 @@ void GLScopeNG::applyConfig() m_x1Scale.setRange(Unit::Time, t_start, t_start + t_len); // time scale m_x2Scale.setRange(Unit::Time, t_start, t_start + t_len); // time scale - if (m_traces) + if (m_traces.size() > 0) { - if (m_traces->size() > 0) - { - setYScale(m_y1Scale, 0); // This is always the X trace (trace #0) - } + setYScale(m_y1Scale, 0); // This is always the X trace (trace #0) + } - if ((m_traces->size() > 1) && (m_highlightedTraceIndex < m_traces->size())) - { - setYScale(m_y2Scale, m_highlightedTraceIndex > 0 ? m_highlightedTraceIndex : 1); // if Highlighted trace is #0 (X trace) set it to first Y trace (trace #1) - } + if ((m_traces.size() > 1) && (m_highlightedTraceIndex < m_traces.size())) + { + setYScale(m_y2Scale, m_highlightedTraceIndex > 0 ? m_highlightedTraceIndex : 1); // if Highlighted trace is #0 (X trace) set it to first Y trace (trace #1) } if ((m_displayMode == DisplayX) || (m_displayMode == DisplayY)) // unique display @@ -942,20 +977,20 @@ void GLScopeNG::applyConfig() void GLScopeNG::setYScale(ScaleEngine& scale, uint32_t highlightedTraceIndex) { - ScopeVisNG::DisplayTrace trace = (*m_traces)[highlightedTraceIndex]; - float amp_range = 2.0 / trace.m_traceData.m_amp; - float amp_ofs = trace.m_traceData.m_ofs; - float pow_floor = -100.0 + trace.m_traceData.m_ofs * 100.0; - float pow_range = 100.0 / trace.m_traceData.m_amp; + ScopeVisNG::DisplayTrace *trace = m_traces[highlightedTraceIndex]; + float amp_range = 2.0 / trace->m_traceData.m_amp; + float amp_ofs = trace->m_traceData.m_ofs; + float pow_floor = -100.0 + trace->m_traceData.m_ofs * 100.0; + float pow_range = 100.0 / trace->m_traceData.m_amp; - switch (trace.m_traceData.m_projectionType) + switch (trace->m_traceData.m_projectionType) { case ScopeVisNG::ProjectionMagDB: // dB scale scale.setRange(Unit::Decibel, pow_floor, pow_floor + pow_range); break; case ScopeVisNG::ProjectionPhase: // Phase or frequency case ScopeVisNG::ProjectionDPhase: - scale.setRange(Unit::None, -1.0/trace.m_traceData.m_amp + amp_ofs, 1.0/trace.m_traceData.m_amp + amp_ofs); + scale.setRange(Unit::None, -1.0/trace->m_traceData.m_amp + amp_ofs, 1.0/trace->m_traceData.m_amp + amp_ofs); break; case ScopeVisNG::ProjectionReal: // Linear generic case ScopeVisNG::ProjectionImag: diff --git a/sdrbase/gui/glscopeng.h b/sdrbase/gui/glscopeng.h index e1bd2610a..be7b2afb9 100644 --- a/sdrbase/gui/glscopeng.h +++ b/sdrbase/gui/glscopeng.h @@ -51,10 +51,12 @@ public: void connectTimer(const QTimer& timer); - void setTraces(const ScopeVisNG::DisplayTraces *traces) { m_traces = traces; m_configChanged = true; } + void addTrace(ScopeVisNG::DisplayTrace *trace); + void removeTrace(int index); void newTraces(); int getSampleRate() const { return m_sampleRate; } + int getTraceSize() const { return m_traceSize; } void setTriggerPre(Real triggerPre); void setTimeOfsProMill(int timeOfsProMill); @@ -63,6 +65,8 @@ public: void setHighlightedTraceIndex(uint32_t traceIndex); void setDisplayMode(DisplayMode displayMode); void setTraceSize(int trceSize); + void setDisplayGridIntensity(int intensity); + void setDisplayTraceIntensity(int intensity); signals: void sampleRateChanged(int); @@ -73,12 +77,13 @@ private: QMutex m_mutex; bool m_dataChanged; bool m_configChanged; - const ScopeVisNG::DisplayTraces *m_traces; + ScopeVisNG::DisplayTraces m_traces; int m_sampleRate; int m_timeOfsProMill; Real m_triggerPre; int m_traceSize; int m_timeBase; + int m_timeOffset; uint32_t m_highlightedTraceIndex; // graphics stuff diff --git a/sdrbase/gui/glscopenggui.cpp b/sdrbase/gui/glscopenggui.cpp index e3a9bb5b6..0b6472642 100644 --- a/sdrbase/gui/glscopenggui.cpp +++ b/sdrbase/gui/glscopenggui.cpp @@ -20,15 +20,27 @@ #include "ui_glscopenggui.h" #include "util/simpleserializer.h" +const double GLScopeNGGUI::amps[11] = { 0.2, 0.1, 0.05, 0.02, 0.01, 0.005, 0.002, 0.001, 0.0005, 0.0002, 0.0001 }; + GLScopeNGGUI::GLScopeNGGUI(QWidget* parent) : QWidget(parent), ui(new Ui::GLScopeNGGUI), m_messageQueue(0), m_glScope(0), m_scopeVis(0), - m_sampleRate(0) + m_sampleRate(0), + m_traceLenMult(1), + m_timeBase(1), + m_timeOffset(0) { ui->setupUi(this); + setEnabled(false); + + ui->traceMode->clear(); + fillProjectionCombo(ui->traceMode); + + ui->trigMode->clear(); + fillProjectionCombo(ui->trigMode); } GLScopeNGGUI::~GLScopeNGGUI() @@ -41,8 +53,40 @@ void GLScopeNGGUI::setBuddies(MessageQueue* messageQueue, ScopeVisNG* scopeVis, m_messageQueue = messageQueue; m_scopeVis = scopeVis; m_glScope = glScope; + + // initialize display combo + ui->onlyX->setChecked(true); + ui->onlyY->setChecked(false); + ui->horizontalXY->setChecked(false); + ui->verticalXY->setChecked(false); + ui->polar->setChecked(false); + m_glScope->setDisplayMode(GLScopeNG::DisplayX); + + // initialize trigger combo + ui->trigPos->setChecked(true); + ui->trigNeg->setChecked(false); + ui->trigBoth->setChecked(false); + ui->freerun->setChecked(true); + + // Add a trace + ScopeVisNG::TraceData traceData; + fillTraceData(traceData); + m_scopeVis->addTrace(traceData); + + // Add a trigger + ScopeVisNG::TriggerData triggerData; + fillTriggerData(triggerData); + m_scopeVis->addTrigger(triggerData); + + setEnabled(true); connect(m_glScope, SIGNAL(sampleRateChanged(int)), this, SLOT(on_scope_sampleRateChanged(int))); - applySettings(); + + m_scopeVis->configure(2*m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10); + m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10); + + setTraceLenDisplay(); + setTimeScaleDisplay(); + setTimeOfsDisplay(); } void GLScopeNGGUI::setSampleRate(int sampleRate) @@ -55,6 +99,9 @@ void GLScopeNGGUI::on_scope_sampleRateChanged(int sampleRate) //m_sampleRate = m_glScope->getSampleRate(); m_sampleRate = sampleRate; ui->sampleRateText->setText(tr("%1\nkS/s").arg(m_sampleRate / 1000.0f, 0, 'f', 2)); + setTraceLenDisplay(); + setTimeScaleDisplay(); + setTimeOfsDisplay(); } void GLScopeNGGUI::resetToDefaults() @@ -125,47 +172,166 @@ void GLScopeNGGUI::on_horizontalXY_toggled(bool checked) void GLScopeNGGUI::on_verticalXY_toggled(bool checked) { - ui->onlyX->setChecked(false); - ui->onlyY->setChecked(false); - ui->horizontalXY->setChecked(false); - ui->polar->setChecked(false); - m_glScope->setDisplayMode(GLScopeNG::DisplayXYV); + if (checked) + { + ui->onlyX->setChecked(false); + ui->onlyY->setChecked(false); + ui->horizontalXY->setChecked(false); + ui->polar->setChecked(false); + m_glScope->setDisplayMode(GLScopeNG::DisplayXYV); + } } void GLScopeNGGUI::on_polar_toggled(bool checked) { - ui->onlyX->setChecked(false); - ui->onlyY->setChecked(false); - ui->horizontalXY->setChecked(false); - ui->verticalXY->setChecked(false); - m_glScope->setDisplayMode(GLScopeNG::DisplayPol); + if (checked) + { + ui->onlyX->setChecked(false); + ui->onlyY->setChecked(false); + ui->horizontalXY->setChecked(false); + ui->verticalXY->setChecked(false); + m_glScope->setDisplayMode(GLScopeNG::DisplayPol); + } } void GLScopeNGGUI::on_traceIntensity_valueChanged(int value) { - + ui->traceIntensity->setToolTip(QString("Trace intensity: %1").arg(value)); + m_glScope->setDisplayTraceIntensity(value); } void GLScopeNGGUI::on_gridIntensity_valueChanged(int value) { - + ui->gridIntensity->setToolTip(QString("Grid intensity: %1").arg(value)); + m_glScope->setDisplayGridIntensity(value); } void GLScopeNGGUI::on_time_valueChanged(int value) { - + m_timeBase = value; + setTimeScaleDisplay(); + m_glScope->setTimeBase(m_timeBase); } void GLScopeNGGUI::on_timeOfs_valueChanged(int value) { + if ((value < 0) || (value > 100)) { + return; + } + m_timeOffset = value; + setTimeOfsDisplay(); + m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10); } void GLScopeNGGUI::on_traceLen_valueChanged(int value) { + if ((value < 1) || (value > 100)) { + return; + } + m_traceLenMult = value; + m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10); + setTraceLenDisplay(); + setTimeScaleDisplay(); + setTimeOfsDisplay(); } +void GLScopeNGGUI::setTimeScaleDisplay() +{ + m_sampleRate = m_glScope->getSampleRate(); + double t = (m_glScope->getTraceSize() * 1.0 / m_sampleRate) / (double) m_timeBase; + + if(t < 0.000001) + { + t = round(t * 100000000000.0) / 100.0; + ui->timeText->setText(tr("%1\nns").arg(t)); + } + else if(t < 0.001) + { + t = round(t * 100000000.0) / 100.0; + ui->timeText->setText(tr("%1\nµs").arg(t)); + } + else if(t < 1.0) + { + t = round(t * 100000.0) / 100.0; + ui->timeText->setText(tr("%1\nms").arg(t)); + } + else + { + t = round(t * 100.0) / 100.0; + ui->timeText->setText(tr("%1\ns").arg(t)); + } +} + +void GLScopeNGGUI::setTraceLenDisplay() +{ + uint n_samples = m_traceLenMult * ScopeVisNG::m_traceChunkSize; + + if (n_samples < 1000) { + ui->traceLenText->setToolTip(tr("%1S").arg(n_samples)); + } else if (n_samples < 1000000) { + ui->traceLenText->setToolTip(tr("%1kS").arg(n_samples/1000.0)); + } else { + ui->traceLenText->setToolTip(tr("%1MS").arg(n_samples/1000000.0)); + } + + m_sampleRate = m_glScope->getSampleRate(); + qreal t = (m_glScope->getTraceSize() * 1.0 / m_sampleRate); + + if(t < 0.000001) + ui->traceLenText->setText(tr("%1\nns").arg(t * 1000000000.0)); + else if(t < 0.001) + ui->traceLenText->setText(tr("%1\nµs").arg(t * 1000000.0)); + else if(t < 1.0) + ui->traceLenText->setText(tr("%1\nms").arg(t * 1000.0)); + else + ui->traceLenText->setText(tr("%1\ns").arg(t * 1.0)); +} + +void GLScopeNGGUI::setTimeOfsDisplay() +{ + qreal dt = m_glScope->getTraceSize() * (m_timeOffset/100.0) / m_sampleRate; + + if(dt < 0.000001) + ui->timeOfsText->setText(tr("%1\nns").arg(dt * 1000000000.0)); + else if(dt < 0.001) + ui->timeOfsText->setText(tr("%1\nµs").arg(dt * 1000000.0)); + else if(dt < 1.0) + ui->timeOfsText->setText(tr("%1\nms").arg(dt * 1000.0)); + else + ui->timeOfsText->setText(tr("%1\ns").arg(dt * 1.0)); +} + +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); +} + +void GLScopeNGGUI::fillTraceData(ScopeVisNG::TraceData& traceData) +{ + traceData.m_projectionType = (ScopeVisNG::ProjectionType) ui->traceMode->currentIndex(); + traceData.m_inputIndex = 0; + traceData.m_amp = 0.2 / amps[ui->amp->value()]; + traceData.m_ofs = (10.0 * ui->ofsCoarse->value()) + (ui->ofsFine->value() / 20.0); + traceData.m_traceDelay = 0; +} + +void GLScopeNGGUI::fillTriggerData(ScopeVisNG::TriggerData& triggerData) +{ + triggerData.m_projectionType = (ScopeVisNG::ProjectionType) ui->traceMode->currentIndex(); + triggerData.m_inputIndex = 0; + triggerData.m_triggerLevel = (ui->trigLevelCoarse->value() / 100.0) + (ui->trigLevelFine->value() / 20000.0); + triggerData.m_triggerPositiveEdge = ui->trigPos->isChecked(); + triggerData.m_triggerBothEdges = ui->trigBoth->isChecked(); + triggerData.m_triggerDelay = ui->trigDelay->value(); + triggerData.m_triggerRepeat = ui->trigCount->value(); +} void GLScopeNGGUI::applySettings() { diff --git a/sdrbase/gui/glscopenggui.h b/sdrbase/gui/glscopenggui.h index d0f4da94c..d8f86aea3 100644 --- a/sdrbase/gui/glscopenggui.h +++ b/sdrbase/gui/glscopenggui.h @@ -19,9 +19,12 @@ #define SDRBASE_GUI_GLSCOPENGGUI_H_ #include +#include + #include "dsp/dsptypes.h" #include "util/export.h" #include "util/message.h" +#include "dsp/scopevisng.h" namespace Ui { class GLScopeNGGUI; @@ -29,7 +32,6 @@ namespace Ui { class MessageQueue; class GLScopeNG; -class ScopeVisNG; class SDRANGEL_API GLScopeNGGUI : public QWidget { Q_OBJECT @@ -55,8 +57,21 @@ private: GLScopeNG* m_glScope; int m_sampleRate; + int m_timeBase; + int m_timeOffset; + int m_traceLenMult; + + static const double amps[11]; void applySettings(); + void setTimeScaleDisplay(); + void setTraceLenDisplay(); + void setTimeOfsDisplay(); + + void fillTraceData(ScopeVisNG::TraceData& traceData); + void fillTriggerData(ScopeVisNG::TriggerData& triggerData); + + void fillProjectionCombo(QComboBox* comboBox); private slots: void on_scope_sampleRateChanged(int value); diff --git a/sdrbase/gui/glscopenggui.ui b/sdrbase/gui/glscopenggui.ui index 4c17cc2f6..987d7b820 100644 --- a/sdrbase/gui/glscopenggui.ui +++ b/sdrbase/gui/glscopenggui.ui @@ -6,7 +6,7 @@ 0 0 - 634 + 692 120 @@ -246,6 +246,9 @@ 1 + + 50 + @@ -265,6 +268,9 @@ 1 + + 10 + @@ -277,7 +283,7 @@ - t: + T: @@ -326,7 +332,7 @@ - d: + O: @@ -407,7 +413,7 @@ 1 - 20 + 1 Qt::Horizontal @@ -472,13 +478,16 @@ kS/s - 0 + 10 0 0 + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + @@ -492,6 +501,12 @@ kS/s Trace index (0 is X trace) + + 0 + + + 1 + @@ -726,7 +741,7 @@ kS/s - d: + O: @@ -807,6 +822,49 @@ kS/s + + + + D: + + + + + + + + 32 + 0 + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 100 + + + 1 + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + @@ -845,6 +903,13 @@ kS/s + + + + Qt::Vertical + + + @@ -858,13 +923,6 @@ kS/s - - - - Qt::Vertical - - - @@ -926,13 +984,16 @@ kS/s - 0 + 10 0 0 + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + @@ -946,6 +1007,12 @@ kS/s Sellect triggger in trigger chain + + 0 + + + 1 + @@ -1132,6 +1199,12 @@ kS/s Number of trigger condition before trigger is actuated + + 100 + + + 1 + @@ -1317,6 +1390,12 @@ kS/s Trigger delay + + 100 + + + 1 + Qt::Horizontal @@ -1369,6 +1448,19 @@ kS/s + + + + Qt::Horizontal + + + + 40 + 20 + + + +