From 77072ec96754fb0ea062bbf6b56c4d0486a11b9d Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 13 Feb 2017 01:32:02 +0100 Subject: [PATCH] New scope: add/delete traces interim state (1) --- sdrbase/dsp/scopevisng.cpp | 23 +++++ sdrbase/dsp/scopevisng.h | 31 ++++++ sdrbase/gui/glscopeng.cpp | 179 ++++++++++++++++++++++++++++++++--- sdrbase/gui/glscopeng.h | 4 +- sdrbase/gui/glscopenggui.cpp | 102 +++++++++++++++++++- sdrbase/gui/glscopenggui.h | 4 + sdrbase/gui/glscopenggui.ui | 4 +- 7 files changed, 331 insertions(+), 16 deletions(-) diff --git a/sdrbase/dsp/scopevisng.cpp b/sdrbase/dsp/scopevisng.cpp index 044d70303..fab38df77 100644 --- a/sdrbase/dsp/scopevisng.cpp +++ b/sdrbase/dsp/scopevisng.cpp @@ -28,6 +28,7 @@ MESSAGE_CLASS_DEFINITION(ScopeVisNG::MsgScopeVisNGFocusOnTrigger, Message) MESSAGE_CLASS_DEFINITION(ScopeVisNG::MsgScopeVisNGAddTrace, Message) MESSAGE_CLASS_DEFINITION(ScopeVisNG::MsgScopeVisNGChangeTrace, Message) MESSAGE_CLASS_DEFINITION(ScopeVisNG::MsgScopeVisNGRemoveTrace, Message) +MESSAGE_CLASS_DEFINITION(ScopeVisNG::MsgScopeVisNGFocusOnTrace, Message) const uint ScopeVisNG::m_traceChunkSize = 4800; const Real ScopeVisNG::ProjectorMagDB::mult = (10.0f / log2f(10.0f)); @@ -39,6 +40,7 @@ ScopeVisNG::ScopeVisNG(GLScopeNG* glScope) : m_currentTriggerIndex(0), m_focusedTriggerIndex(0), m_triggerState(TriggerUntriggered), + m_focusedTraceIndex(0), m_traceSize(m_traceChunkSize), m_nbSamples(0), m_traceStart(true), @@ -96,6 +98,12 @@ void ScopeVisNG::removeTrace(uint32_t traceIndex) getInputMessageQueue()->push(cmd); } +void ScopeVisNG::focusOnTrace(uint32_t traceIndex) +{ + Message* cmd = MsgScopeVisNGFocusOnTrace::create(traceIndex); + getInputMessageQueue()->push(cmd); +} + void ScopeVisNG::addTrigger(const TriggerData& triggerData) { Message* cmd = MsgScopeVisNGAddTrigger::create(triggerData); @@ -573,6 +581,21 @@ bool ScopeVisNG::handleMessage(const Message& message) m_glScope->updateDisplay(); return true; } + else if (MsgScopeVisNGFocusOnTrace::match(message)) + { + MsgScopeVisNGFocusOnTrace& conf = (MsgScopeVisNGFocusOnTrace&) message; + int traceIndex = conf.getTraceIndex(); + + if (traceIndex < m_traces.m_tracesData.size()) + { + m_focusedTraceIndex = traceIndex; + computeDisplayTriggerLevels(); + m_glScope->setFocusedTraceIndex(m_focusedTraceIndex); + m_glScope->updateDisplay(); + } + + return true; + } else { return false; diff --git a/sdrbase/dsp/scopevisng.h b/sdrbase/dsp/scopevisng.h index c7dee023d..c42499735 100644 --- a/sdrbase/dsp/scopevisng.h +++ b/sdrbase/dsp/scopevisng.h @@ -50,8 +50,12 @@ public: 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_traceDelayValue; //!< Trace 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 @@ -62,8 +66,12 @@ public: m_projectionType(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_traceDelayValue(0), m_triggerDisplayLevel(2.0), // OVer scale by default (2.0) m_traceColor(255,255,64) { @@ -141,6 +149,7 @@ public: void addTrace(const TraceData& traceData); void changeTrace(const TraceData& traceData, uint32_t traceIndex); void removeTrace(uint32_t traceIndex); + void focusOnTrace(uint32_t traceIndex); void addTrigger(const TriggerData& triggerData); void changeTrigger(const TriggerData& triggerData, uint32_t triggerIndex); void removeTrigger(uint32_t triggerIndex); @@ -359,6 +368,27 @@ private: {} }; + // --------------------------------------------- + class MsgScopeVisNGFocusOnTrace : public Message { + MESSAGE_CLASS_DECLARATION + + public: + static MsgScopeVisNGFocusOnTrace* create( + uint32_t traceIndex) + { + return new MsgScopeVisNGFocusOnTrace(traceIndex); + } + + uint32_t getTraceIndex() const { return m_traceIndex; } + + private: + uint32_t m_traceIndex; + + MsgScopeVisNGFocusOnTrace(uint32_t traceIndex) : + m_traceIndex(traceIndex) + {} + }; + // === projectors === // --------------------------------------------- class Projector @@ -852,6 +882,7 @@ private: int m_focusedTriggerIndex; //!< Index of the trigger that has focus TriggerState m_triggerState; //!< Current trigger state Traces m_traces; //!< Displayable traces + int m_focusedTraceIndex; //!< Index of the trace that has focus int m_traceSize; //!< Size of traces in number of samples int m_nbSamples; //!< Number of samples yet to process in one complex trace int m_timeOfsProMill; //!< Start trace shift in 1/1000 trace size diff --git a/sdrbase/gui/glscopeng.cpp b/sdrbase/gui/glscopeng.cpp index 51f596915..66be14569 100644 --- a/sdrbase/gui/glscopeng.cpp +++ b/sdrbase/gui/glscopeng.cpp @@ -40,7 +40,7 @@ GLScopeNG::GLScopeNG(QWidget* parent) : m_sampleRate(0), m_triggerPre(0), m_timeOfsProMill(0), - m_highlightedTraceIndex(0), + m_focusedTraceIndex(0), m_timeOffset(0) { setAttribute(Qt::WA_OpaquePaintEvent); @@ -295,8 +295,6 @@ void GLScopeNG::paintGL() m_glShaderBottom1Scale.drawSurface(m_glBot1ScaleMatrix, tex1, vtx1, 4); } - // TODO: paint trigger level #1 - // paint trace #1 if (m_traceSize > 0) { @@ -346,13 +344,172 @@ void GLScopeNG::paintGL() mat.translate(-1.0f + 2.0f * rectX, 1.0f - 2.0f * rectY); mat.scale(2.0f * rectW, -2.0f * rectH); m_glShaderSimple.drawSegments(mat, color, q3, 2); - } - } - } + } // display trace + } // trace length > 0 + } // Display X only else if (m_displayMode == DisplayY) // display only traces #1..n { - } + // draw rect around + { + GLfloat q3[] { + 1, 1, + 0, 1, + 0, 0, + 1, 0 + }; + + QVector4D color(1.0f, 1.0f, 1.0f, 0.5f); + m_glShaderSimple.drawContour(m_glScopeMatrix1, color, q3, 4); + } + + // paint grid + const ScaleEngine::TickList* tickList; + const ScaleEngine::Tick* tick; + + // Y2 (Focused Y trace) + { + tickList = &m_y2Scale.getTickList(); + + GLfloat q3[4*tickList->count()]; + int effectiveTicks = 0; + + for (int i= 0; i < tickList->count(); i++) + { + tick = &(*tickList)[i]; + + if (tick->major) + { + if (tick->textSize > 0) + { + float y = 1 - (tick->pos / m_y2Scale.getSize()); + q3[4*effectiveTicks] = 0; + q3[4*effectiveTicks+1] = y; + q3[4*effectiveTicks+2] = 1; + q3[4*effectiveTicks+3] = y; + effectiveTicks++; + } + } + } + + float blue = 1.0f; + QVector4D color(1.0f, 1.0f, blue, (float) m_displayGridIntensity / 100.0f); + m_glShaderSimple.drawSegments(m_glScopeMatrix1, color, q3, 2*effectiveTicks); + } + + // X1 (time) + { + tickList = &m_x1Scale.getTickList(); + + GLfloat q3[4*tickList->count()]; + int effectiveTicks = 0; + for(int i= 0; i < tickList->count(); i++) { + tick = &(*tickList)[i]; + if(tick->major) { + if(tick->textSize > 0) { + float x = tick->pos / m_x1Scale.getSize(); + q3[4*effectiveTicks] = x; + q3[4*effectiveTicks+1] = 0; + q3[4*effectiveTicks+2] = x; + q3[4*effectiveTicks+3] = 1; + effectiveTicks++; + } + } + } + + QVector4D color(1.0f, 1.0f, 1.0f, (float) m_displayGridIntensity / 100.0f); + m_glShaderSimple.drawSegments(m_glScopeMatrix1, color, q3, 2*effectiveTicks); + } + + // paint left #1 scale + { + GLfloat vtx1[] = { + 0, 1, + 1, 1, + 1, 0, + 0, 0 + }; + GLfloat tex1[] = { + 0, 1, + 1, 1, + 1, 0, + 0, 0 + }; + m_glShaderLeft1Scale.drawSurface(m_glLeft1ScaleMatrix, tex1, vtx1, 4); + } + + // paint bottom #1 scale + { + GLfloat vtx1[] = { + 0, 1, + 1, 1, + 1, 0, + 0, 0 + }; + GLfloat tex1[] = { + 0, 1, + 1, 1, + 1, 0, + 0, 0 + }; + m_glShaderBottom1Scale.drawSurface(m_glBot1ScaleMatrix, tex1, vtx1, 4); + } + + // paint traces #1..n + if (m_traceSize > 0) + { + for (int i = 1; i < m_traces->size(); i++) + { + const float *trace = (*m_traces)[i]; + const ScopeVisNG::TraceData& traceData = (*m_tracesData)[i]; + + int start = (m_timeOfsProMill/1000.0) * m_traceSize; + int end = std::min(start + m_traceSize/m_timeBase, m_traceSize); + + if(end - start < 2) + start--; + + 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) * traceData.m_amp; + float rectH = -m_glScopeRect1.height() / 2.0f; + + //QVector4D color(1.0f, 1.0f, 0.25f, m_displayTraceIntensity / 100.0f); + QVector4D color(traceData.m_traceColorR, traceData.m_traceColorG, traceData.m_traceColorB, 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[2*start], end - start); + + // Paint trigger level if any + if ((traceData.m_triggerDisplayLevel > -1.0f) && (traceData.m_triggerDisplayLevel < 1.0f)) + { + GLfloat q3[] { + 0, traceData.m_triggerDisplayLevel, + 1, traceData.m_triggerDisplayLevel + }; + + float rectX = m_glScopeRect1.x(); + float rectY = m_glScopeRect1.y() + m_glScopeRect1.height() / 2.0f; + float rectW = m_glScopeRect1.width(); + float rectH = -m_glScopeRect1.height() / 2.0f; + + QVector4D color( + m_focusedTriggerData.m_triggerColorR, + m_focusedTriggerData.m_triggerColorG, + m_focusedTriggerData.m_triggerColorB, + 0.4f); + 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.drawSegments(mat, color, q3, 2); + } + } // one trace display + } // trace length > 0 + } // Display Y only m_mutex.unlock(); } @@ -386,9 +543,9 @@ void GLScopeNG::setTimeOfsProMill(int timeOfsProMill) update(); } -void GLScopeNG::setHighlightedTraceIndex(uint32_t traceIndex) +void GLScopeNG::setFocusedTraceIndex(uint32_t traceIndex) { - m_highlightedTraceIndex = traceIndex; + m_focusedTraceIndex = traceIndex; m_configChanged = true; update(); } @@ -431,9 +588,9 @@ void GLScopeNG::applyConfig() setYScale(m_y1Scale, 0); // This is always the X trace (trace #0) } - if ((m_traces->size() > 1) && (m_highlightedTraceIndex < m_traces->size())) + if ((m_traces->size() > 1) && (m_focusedTraceIndex < 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) + setYScale(m_y2Scale, m_focusedTraceIndex > 0 ? m_focusedTraceIndex : 1); // if Highlighted trace is #0 (X trace) set it to first Y trace (trace #1) } else { diff --git a/sdrbase/gui/glscopeng.h b/sdrbase/gui/glscopeng.h index 75fb3800a..a353d4a3f 100644 --- a/sdrbase/gui/glscopeng.h +++ b/sdrbase/gui/glscopeng.h @@ -61,7 +61,7 @@ public: void setTimeOfsProMill(int timeOfsProMill); void setSampleRate(int sampleRate); void setTimeBase(int timeBase); - void setHighlightedTraceIndex(uint32_t traceIndex); + void setFocusedTraceIndex(uint32_t traceIndex); void setDisplayMode(DisplayMode displayMode); void setTraceSize(int trceSize); void updateDisplay(); @@ -92,7 +92,7 @@ private: int m_traceSize; int m_timeBase; int m_timeOffset; - uint32_t m_highlightedTraceIndex; + uint32_t m_focusedTraceIndex; // graphics stuff QRectF m_glScopeRect1; diff --git a/sdrbase/gui/glscopenggui.cpp b/sdrbase/gui/glscopenggui.cpp index 350b23525..627b3a2ff 100644 --- a/sdrbase/gui/glscopenggui.cpp +++ b/sdrbase/gui/glscopenggui.cpp @@ -270,6 +270,64 @@ void GLScopeNGGUI::on_traceLen_valueChanged(int value) setTrigPreDisplay(); } +void GLScopeNGGUI::on_trace_valueChanged(int value) +{ + ui->traceText->setText(tr("%1").arg(value)); + + ScopeVisNG::TraceData traceData; + m_scopeVis->getTraceData(traceData, value); + + qDebug() << "GLScopeNGGUI::on_trace_valueChanged:" + << " m_projectionType: " << (int) traceData.m_projectionType + << " m_amp" << traceData.m_amp + << " m_ofs" << traceData.m_ofs + << " m_traceDelay" << traceData.m_traceDelay; + + setTraceUI(traceData); + + m_scopeVis->focusOnTrace(value); +} + +void GLScopeNGGUI::on_traceAdd_clicked(bool checked) +{ + if (ui->trace->maximum() < 9) + { + if (ui->trace->value() == 0) + { + ui->onlyY->setEnabled(true); + ui->horizontalXY->setEnabled(true); + ui->verticalXY->setEnabled(true); + ui->polar->setEnabled(true); + } + + ScopeVisNG::TraceData traceData; + fillTraceData(traceData); + m_scopeVis->addTrace(traceData); + ui->trace->setMaximum(ui->trace->maximum() + 1); + } +} + +void GLScopeNGGUI::on_traceDel_clicked(bool checked) +{ + if (ui->trace->value() > 0) + { + ui->trace->setMaximum(ui->trace->maximum() - 1); + + if (ui->trace->value() == 0) + { + ui->onlyX->setChecked(true); + ui->onlyY->setEnabled(false); + ui->horizontalXY->setEnabled(false); + ui->verticalXY->setEnabled(false); + ui->polar->setEnabled(false); + m_glScope->setDisplayMode(GLScopeNG::DisplayX); + } + + m_scopeVis->removeTrace(ui->trace->value()); + } +} + + void GLScopeNGGUI::on_trig_valueChanged(int value) { ui->trigText->setText(tr("%1").arg(value)); @@ -720,7 +778,12 @@ 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_traceDelay = 0; + traceData.m_ampIndex = ui->amp->value(); + traceData.m_traceDelay = 0; // TODO + traceData.m_traceDelayValue = 0; // TODO + + traceData.m_ofsCoarse = ui->ofsCoarse->value(); + traceData.m_ofsFine = ui->ofsFine->value(); if (traceData.m_projectionType == ScopeVisNG::ProjectionMagLin) { traceData.m_ofs = ((10.0 * ui->ofsCoarse->value()) + (ui->ofsFine->value() / 20.0)) / 2000.0f; @@ -748,6 +811,43 @@ void GLScopeNGGUI::fillTriggerData(ScopeVisNG::TriggerData& triggerData) triggerData.setColor(m_focusedTriggerColor); } +void GLScopeNGGUI::setTraceUI(ScopeVisNG::TraceData& traceData) +{ + bool oldStateTraceMode = ui->traceMode->blockSignals(true); + bool oldStateAmp = ui->amp->blockSignals(true); + bool oldStateOfsCoarse = ui->ofsCoarse->blockSignals(true); + bool oldStateOfsFine = ui->ofsFine->blockSignals(true); + bool oldStateTraceDelay = ui->traceDelay->blockSignals(true); + bool oldStateZSelect = ui->zSelect->blockSignals(true); + bool oldStateZTraceMode = ui->zTraceMode->blockSignals(true); + bool oldStateTraceColor = ui->traceColor->blockSignals(true); + + ui->traceMode->setCurrentIndex((int) traceData.m_projectionType); + ui->amp->setValue(traceData.m_ampIndex); + setAmpScaleDisplay(); + + ui->ofsCoarse->setValue(traceData.m_ofsCoarse); + ui->ofsFine->setValue(traceData.m_ofsFine); + setAmpOfsDisplay(); + + ui->traceDelay->setValue(traceData.m_traceDelayValue); + // TODO: set trace delay display + + m_focusedTraceColor = traceData.m_traceColor; + int r, g, b, a; + m_focusedTraceColor.getRgb(&r, &g, &b, &a); + ui->traceColor->setStyleSheet(tr("QLabel { background-color : rgb(%1,%2,%3); }").arg(r).arg(g).arg(b)); + + ui->traceMode->blockSignals(oldStateTraceMode); + ui->amp->blockSignals(oldStateAmp); + ui->ofsCoarse->blockSignals(oldStateOfsCoarse); + ui->ofsFine->blockSignals(oldStateOfsFine); + ui->traceDelay->blockSignals(oldStateTraceDelay); + ui->zSelect->blockSignals(oldStateZSelect); + ui->zTraceMode->blockSignals(oldStateZTraceMode); + ui->traceColor->blockSignals(oldStateTraceColor); +} + void GLScopeNGGUI::setTriggerUI(ScopeVisNG::TriggerData& triggerData) { bool oldStateTrigMode = ui->trigMode->blockSignals(true); diff --git a/sdrbase/gui/glscopenggui.h b/sdrbase/gui/glscopenggui.h index 06c57db63..fae6a219d 100644 --- a/sdrbase/gui/glscopenggui.h +++ b/sdrbase/gui/glscopenggui.h @@ -87,6 +87,7 @@ private: void fillTraceData(ScopeVisNG::TraceData& traceData); void fillTriggerData(ScopeVisNG::TriggerData& triggerData); void setTriggerUI(ScopeVisNG::TriggerData& triggerData); + void setTraceUI(ScopeVisNG::TraceData& traceData); void fillProjectionCombo(QComboBox* comboBox); @@ -104,6 +105,9 @@ private slots: void on_timeOfs_valueChanged(int value); void on_traceLen_valueChanged(int value); // Second row + void on_trace_valueChanged(int value); + void on_traceAdd_clicked(bool checked); + void on_traceDel_clicked(bool checked); void on_traceMode_currentIndexChanged(int index); void on_amp_valueChanged(int value); void on_ofsCoarse_valueChanged(int value); diff --git a/sdrbase/gui/glscopenggui.ui b/sdrbase/gui/glscopenggui.ui index 7fe32818c..379bd67ec 100644 --- a/sdrbase/gui/glscopenggui.ui +++ b/sdrbase/gui/glscopenggui.ui @@ -515,7 +515,7 @@ kS/s 0 - + 18 @@ -573,7 +573,7 @@ kS/s - + 18