diff --git a/sdrbase/dsp/scopevisng.cpp b/sdrbase/dsp/scopevisng.cpp index 96f56fded..01048798b 100644 --- a/sdrbase/dsp/scopevisng.cpp +++ b/sdrbase/dsp/scopevisng.cpp @@ -81,7 +81,10 @@ void ScopeVisNG::addTrace(const TraceData& traceData) void ScopeVisNG::changeTrace(const TraceData& traceData, uint32_t traceIndex) { - qDebug("ScopeVisNG::changeTrace: trace #%d", traceIndex); + qDebug() << "ScopeVisNG::changeTrace:" + << " trace: " << traceIndex + << " m_amp: " << traceData.m_amp + << " m_ofs: " << traceData.m_ofs; Message* cmd = MsgScopeVisNGChangeTrace::create(traceData, traceIndex); getInputMessageQueue()->push(cmd); } @@ -158,56 +161,18 @@ void ScopeVisNG::feed(const SampleVector::const_iterator& cbegin, const SampleVe while (begin < end) { - if (m_triggerState == TriggerDelay) - { - if (triggerCondition.m_triggerDelayCount > 0) - { - triggerCondition.m_triggerDelayCount--; // pass - } - else // delay expired => fire this trigger - { - if (!nextTrigger()) // finished - { - m_traceStart = true; // start trace processing - m_triggerPoint = begin; - break; - } - } - } - else // look for trigger - { - bool condition = compareTrigger(*begin, triggerCondition); // triggerCondition.m_projector->run(*begin) > triggerCondition.m_triggerData.m_triggerLevel; - bool trigger; - - if (triggerCondition.m_triggerData.m_triggerBothEdges) { - trigger = triggerCondition.m_prevCondition ^ condition; - } else { - trigger = (triggerCondition.m_prevCondition ^ condition) && (condition ^ !triggerCondition.m_triggerData.m_triggerPositiveEdge); - } - - triggerCondition.m_prevCondition = condition; - - if (trigger) // trigger condition - { - if (triggerCondition.m_triggerData.m_triggerDelay > 0) // there is a delay => initialize the delay - { - triggerCondition.m_triggerDelayCount = triggerCondition.m_triggerData.m_triggerDelay; - m_triggerState = TriggerDelay; - } - else - { - if (!nextTrigger()) // finished - { - m_traceStart = true; // start trace processing - m_triggerPoint = begin; - break; - } - } - } - } + // look for trigger + if (m_triggerComparator.triggered(*begin, triggerCondition)) + { + m_traceStart = true; // start trace processing + m_triggerPoint = begin; + m_triggerComparator.reset(); + m_triggerState = TriggerTriggered; + break; + } ++begin; - } // begin < end + } } else { @@ -307,24 +272,22 @@ int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackB if (itCtl->m_traceCount[m_traces.currentBufferIndex()] < m_traceSize) { - float posLimit = 1.0 / itData->m_amp; - float negLimit = -1.0 / itData->m_amp; ProjectionType projectionType = itData->m_projectionType; float v; if (projectionType == ProjectionMagLin) { - v = itCtl->m_projector->run(*begin)*itData->m_amp - itData->m_ofs - 1.0/itData->m_amp; - } else if (projectionType == ProjectionMagDB) { // TODO: optimize computation using a specialized projector (2 projectors: value and trace) - v = 1.0f + 2.0f*(((itCtl->m_projector->run(*begin))/100.0f) - itData->m_ofs) + 1.0f - 1.0f/itData->m_amp; - //v = itCtl->m_projector->run(*begin) * itData->m_amp - itData->m_ofs; + v = (itCtl->m_projector->run(*begin) - itData->m_ofs)*itData->m_amp - 1.0f; + } else if (projectionType == ProjectionMagDB) { + float p = itCtl->m_projector->run(*begin) - (100.0f * itData->m_ofs); + v = ((p/50.0f) + 2.0f)*itData->m_amp - 1.0f; } else { - v = itCtl->m_projector->run(*begin) * itData->m_amp - itData->m_ofs; + v = (itCtl->m_projector->run(*begin) - itData->m_ofs) * itData->m_amp; } - if(v > posLimit) { - v = posLimit; - } else if (v < negLimit) { - v = negLimit; + if(v > 1.0f) { + v = 1.0f; + } else if (v < -1.0f) { + v = -1.0f; } (*itTrace)[2*(itCtl->m_traceCount[m_traces.currentBufferIndex()])] diff --git a/sdrbase/dsp/scopevisng.h b/sdrbase/dsp/scopevisng.h index 896bafb81..d9d61efbd 100644 --- a/sdrbase/dsp/scopevisng.h +++ b/sdrbase/dsp/scopevisng.h @@ -350,16 +350,27 @@ private: virtual Real run(const Sample& s) { Real curArg = std::atan2((float) s.m_imag, (float) s.m_real); - Real dPhi = curArg - m_prevArg; + Real dPhi = (curArg - m_prevArg) / M_PI; m_prevArg = curArg; - if (dPhi < -M_PI) { - dPhi += 2.0 * M_PI; - } else if (dPhi > M_PI) { - dPhi -= 2.0 * M_PI; + if (dPhi < -1.0f) { + dPhi += 2.0f; + } else if (dPhi > 1.0f) { + dPhi -= 2.0f; } - return dPhi/M_PI; + return dPhi; + +// Real dPhi = curArg - m_prevArg; +// m_prevArg = curArg; +// +// if (dPhi < -M_PI) { +// dPhi += 2.0 * M_PI; +// } else if (dPhi > M_PI) { +// dPhi -= 2.0 * M_PI; +// } +// +// return dPhi/M_PI; } private: @@ -668,6 +679,77 @@ private: } }; + class TriggerComparator + { + public: + TriggerComparator() : m_level(0), m_reset(true) + { + computeLevels(); + } + + bool triggered(const Sample& s, TriggerCondition& triggerCondition) + { + if (triggerCondition.m_triggerData.m_triggerLevel != m_level) + { + m_level = triggerCondition.m_triggerData.m_triggerLevel; + computeLevels(); + } + + bool condition, trigger; + + if (triggerCondition.m_projector->getProjectionType() == ProjectionMagDB) { + condition = triggerCondition.m_projector->run(s) > m_levelPwoerDB; + } else if (triggerCondition.m_projector->getProjectionType() == ProjectionMagLin) { + condition = triggerCondition.m_projector->run(s) > m_levelPowerLin; + } else { + condition = triggerCondition.m_projector->run(s) > m_level; + } + + if (m_reset) + { + triggerCondition.m_prevCondition = condition; + m_reset = false; + return false; + } + + if (triggerCondition.m_triggerData.m_triggerBothEdges) { + trigger = triggerCondition.m_prevCondition ? !condition : condition; // This is a XOR between bools + } else if (triggerCondition.m_triggerData.m_triggerPositiveEdge) { + trigger = !triggerCondition.m_prevCondition && condition; + } else { + trigger = triggerCondition.m_prevCondition && !condition; + } + +// if (trigger) { +// qDebug("ScopeVisNG::triggered: %s/%s %f/%f", +// triggerCondition.m_prevCondition ? "T" : "F", +// condition ? "T" : "F", +// triggerCondition.m_projector->run(s), +// triggerCondition.m_triggerData.m_triggerLevel); +// } + + triggerCondition.m_prevCondition = condition; + return trigger; + } + + void reset() + { + m_reset = true; + } + + private: + void computeLevels() + { + m_levelPowerLin = m_level + 1.0f; + m_levelPwoerDB = (100.0f * (m_level - 1.0f)); + } + + Real m_level; + Real m_levelPwoerDB; + Real m_levelPowerLin; + bool m_reset; + }; + GLScopeNG* m_glScope; uint32_t m_preTriggerDelay; //!< Pre-trigger delay in number of samples std::vector m_triggerConditions; //!< Chain of triggers @@ -686,21 +768,7 @@ private: TraceBackDiscreteMemory m_traceDiscreteMemory; //!< Complex trace memory for triggered states TODO: vectorize when more than on input is allowed bool m_freeRun; //!< True if free running (trigger globally disabled) int m_maxTraceDelay; //!< Maximum trace delay - - /** - * Test sample against trigger level. Returns true if sample is above level. - * TODO: optimize power level computation by storing value when it changes - */ - bool compareTrigger(const Sample& s, TriggerCondition& triggerCondition) - { - if (triggerCondition.m_projector->getProjectionType() == ProjectionMagDB) { - return triggerCondition.m_projector->run(s) > (100.0f * (triggerCondition.m_triggerData.m_triggerLevel - 1.0f)); - } else if (triggerCondition.m_projector->getProjectionType() == ProjectionMagLin) { - return triggerCondition.m_projector->run(s) > triggerCondition.m_triggerData.m_triggerLevel + 1.0f; - } else { - return triggerCondition.m_projector->run(s) > triggerCondition.m_triggerData.m_triggerLevel; - } - } + TriggerComparator m_triggerComparator; //!< Compares sample level to trigger level /** * Moves on to the next trigger if any or increments trigger count if in repeat mode diff --git a/sdrbase/gui/glscopeng.cpp b/sdrbase/gui/glscopeng.cpp index a44708bf7..7a1fa20b1 100644 --- a/sdrbase/gui/glscopeng.cpp +++ b/sdrbase/gui/glscopeng.cpp @@ -305,7 +305,8 @@ 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) * traceData.m_amp; + //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); QMatrix4x4 mat; @@ -994,9 +995,9 @@ void GLScopeNG::setYScale(ScaleEngine& scale, uint32_t highlightedTraceIndex) break; case ScopeVisNG::ProjectionMagLin: if (amp_range < 2.0) { - scale.setRange(Unit::None, amp_ofs * 500.0, amp_range * 1000.0 + amp_ofs * 500.0); + scale.setRange(Unit::None, amp_ofs * 1000.0, amp_range * 1000.0 + amp_ofs * 1000.0); } else { - scale.setRange(Unit::None, amp_ofs/2.0, amp_range + amp_ofs/2.0); + scale.setRange(Unit::None, amp_ofs, amp_range + amp_ofs); } break; case ScopeVisNG::ProjectionPhase: // Phase or frequency diff --git a/sdrbase/gui/glscopenggui.cpp b/sdrbase/gui/glscopenggui.cpp index d3cd1c31c..6c49d499d 100644 --- a/sdrbase/gui/glscopenggui.cpp +++ b/sdrbase/gui/glscopenggui.cpp @@ -352,7 +352,10 @@ void GLScopeNGGUI::on_trigDelay_valueChanged(int value) void GLScopeNGGUI::on_trigPre_valueChanged(int value) { setTrigPreDisplay(); - changeCurrentTrigger(); + m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, + m_timeOffset*10, + (uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)), + ui->freerun->isChecked()); // TODO: implement one shot feature } void GLScopeNGGUI::on_trigOneShot_toggled(bool checked) @@ -615,8 +618,13 @@ 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)) / 1000.0f; traceData.m_traceDelay = 0; + + if (traceData.m_projectionType == ScopeVisNG::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; + } } void GLScopeNGGUI::fillTriggerData(ScopeVisNG::TriggerData& triggerData)