diff --git a/CMakeLists.txt b/CMakeLists.txt index 89f67de79..412f4b449 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ find_package(Qt5Multimedia 5.0 REQUIRED) find_package(OpenGL REQUIRED) find_package(PkgConfig) +find_package(Boost) find_package(FFTW3F) ############################################################################## diff --git a/include-gpl/dsp/scopevis.h b/include-gpl/dsp/scopevis.h index f3cc18554..a6ceef2f7 100644 --- a/include-gpl/dsp/scopevis.h +++ b/include-gpl/dsp/scopevis.h @@ -1,6 +1,7 @@ #ifndef INCLUDE_SCOPEVIS_H #define INCLUDE_SCOPEVIS_H +#include #include "dsp/samplesink.h" #include "util/export.h" #include "util/message.h" @@ -21,7 +22,7 @@ public: ScopeVis(GLScope* glScope = NULL); - void configure(MessageQueue* msgQueue, TriggerChannel triggerChannel, Real triggerLevel, bool triggerPositiveEdge); + void configure(MessageQueue* msgQueue, TriggerChannel triggerChannel, Real triggerLevel, bool triggerPositiveEdge, uint triggerDelay); void setOneShot(bool oneShot); void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); @@ -42,22 +43,25 @@ private: int getTriggerChannel() const { return m_triggerChannel; } Real getTriggerLevel() const { return m_triggerLevel; } Real getTriggerPositiveEdge() const { return m_triggerPositiveEdge; } + uint getTriggerDelay() const { return m_triggerDelay; } - static MsgConfigureScopeVis* create(int triggerChannel, Real triggerLevel, bool triggerPositiveEdge) + static MsgConfigureScopeVis* create(int triggerChannel, Real triggerLevel, bool triggerPositiveEdge, uint triggerDelay) { - return new MsgConfigureScopeVis(triggerChannel, triggerLevel, triggerPositiveEdge); + return new MsgConfigureScopeVis(triggerChannel, triggerLevel, triggerPositiveEdge, triggerDelay); } private: int m_triggerChannel; Real m_triggerLevel; bool m_triggerPositiveEdge; + uint m_triggerDelay; - MsgConfigureScopeVis(int triggerChannel, Real triggerLevel, bool triggerPositiveEdge) : + MsgConfigureScopeVis(int triggerChannel, Real triggerLevel, bool triggerPositiveEdge, uint triggerDelay) : Message(), m_triggerChannel(triggerChannel), m_triggerLevel(triggerLevel), - m_triggerPositiveEdge(triggerPositiveEdge) + m_triggerPositiveEdge(triggerPositiveEdge), + m_triggerDelay(triggerDelay) { } }; @@ -68,12 +72,15 @@ private: }; GLScope* m_glScope; - std::vector m_trace; + std::vector m_trace; //!< Raw trace to be used by GLScope + boost::circular_buffer m_traceback; //!< FIFO for samples prior to triggering point to support trigger delay (when in triggered mode) + uint m_tracebackCount; //!< Count of samples stored into trace memory since triggering is active up to trace memory size uint m_fill; TriggerState m_triggerState; TriggerChannel m_triggerChannel; Real m_triggerLevel; bool m_triggerPositiveEdge; + uint m_triggerDelay; //!< Trigger delay in number of samples bool m_triggerOneShot; bool m_armed; int m_sampleRate; diff --git a/sdrbase/dsp/scopevis.cpp b/sdrbase/dsp/scopevis.cpp index 98af789c8..e931fbcb9 100644 --- a/sdrbase/dsp/scopevis.cpp +++ b/sdrbase/dsp/scopevis.cpp @@ -2,6 +2,7 @@ #include "gui/glscope.h" #include "dsp/dspcommands.h" #include "util/messagequeue.h" +#include #include #include @@ -11,6 +12,8 @@ MESSAGE_CLASS_DEFINITION(ScopeVis::MsgConfigureScopeVis, Message) ScopeVis::ScopeVis(GLScope* glScope) : m_glScope(glScope), m_trace(96000), + m_traceback(96000), + m_tracebackCount(0), m_fill(0), m_triggerState(Untriggered), m_triggerChannel(TriggerFreeRun), @@ -22,9 +25,9 @@ ScopeVis::ScopeVis(GLScope* glScope) : { } -void ScopeVis::configure(MessageQueue* msgQueue, TriggerChannel triggerChannel, Real triggerLevel, bool triggerPositiveEdge) +void ScopeVis::configure(MessageQueue* msgQueue, TriggerChannel triggerChannel, Real triggerLevel, bool triggerPositiveEdge, uint triggerDelay) { - Message* cmd = MsgConfigureScopeVis::create(triggerChannel, triggerLevel, triggerPositiveEdge); + Message* cmd = MsgConfigureScopeVis::create(triggerChannel, triggerLevel, triggerPositiveEdge, triggerDelay); cmd->submit(msgQueue, this); } @@ -74,15 +77,24 @@ void ScopeVis::feed(SampleVector::const_iterator begin, SampleVector::const_iter { while(begin < end) { - if (triggerCondition(begin) ^ !m_triggerPositiveEdge) { - if (m_armed) { + bool trigger = triggerCondition(begin); + if ((trigger ^ !m_triggerPositiveEdge) && (m_tracebackCount > m_triggerDelay)) + { + if (m_armed) + { m_triggerState = Triggered; m_armed = false; m_triggerPoint = begin; + // fill beginning of m_trace with delayed samples from the trace memory FIFO. Increment m_fill accordingly. + if (m_triggerDelay) { // do this process only if there is a delayed trigger + std::copy(m_traceback.end() - m_triggerDelay, m_traceback.end() - 1, m_trace.begin()); + m_fill = m_triggerDelay; // Increment m_fill accordingly (from 0). + } break; } } - else { + else + { m_armed = true; } ++begin; @@ -105,6 +117,7 @@ void ScopeVis::feed(SampleVector::const_iterator begin, SampleVector::const_iter if (m_triggerOneShot) { m_triggerState = WaitForReset; } else { + m_tracebackCount = 0; m_triggerState = Untriggered; } } @@ -133,14 +146,20 @@ bool ScopeVis::handleMessageKeep(Message* message) return true; } else if(MsgConfigureScopeVis::match(message)) { MsgConfigureScopeVis* conf = (MsgConfigureScopeVis*)message; + m_tracebackCount = 0; m_triggerState = Untriggered; m_triggerChannel = (TriggerChannel) conf->getTriggerChannel(); m_triggerLevel = conf->getTriggerLevel(); m_triggerPositiveEdge = conf->getTriggerPositiveEdge(); + m_triggerDelay = conf->getTriggerDelay(); + if (m_triggerDelay >= m_traceback.size()) { + m_triggerDelay = m_traceback.size() - 1; // top sample in FIFO is always the triggering one (delay = 0) + } std::cerr << "ScopeVis::handleMessageKeep:" << " m_triggerChannel: " << m_triggerChannel << " m_triggerLevel: " << m_triggerLevel - << " m_triggerPositiveEdge: " << (m_triggerPositiveEdge ? "edge+" : "edge-") << std::endl; + << " m_triggerPositiveEdge: " << (m_triggerPositiveEdge ? "edge+" : "edge-") + << " m_triggerDelay: " << m_triggerDelay << std::endl; return true; /* } else if(DSPConfigureScopeVis::match(message)) { @@ -175,7 +194,12 @@ void ScopeVis::setSampleRate(int sampleRate) bool ScopeVis::triggerCondition(SampleVector::const_iterator& it) { Complex c(it->real()/32768.0, it->imag()/32768.0); - + m_traceback.push_back(c); // store into trace memory FIFO + + if (m_tracebackCount < m_traceback.size()) { // increment count up to trace memory size + m_tracebackCount++; + } + if (m_triggerChannel == TriggerChannelI) { return c.real() > m_triggerLevel; } @@ -203,6 +227,7 @@ void ScopeVis::setOneShot(bool oneShot) m_triggerOneShot = oneShot; if ((m_triggerState == WaitForReset) && !oneShot) { + m_tracebackCount = 0; m_triggerState = Untriggered; } } diff --git a/sdrbase/gui/glscopegui.cpp b/sdrbase/gui/glscopegui.cpp index cdd966d2b..bc3b57ac7 100644 --- a/sdrbase/gui/glscopegui.cpp +++ b/sdrbase/gui/glscopegui.cpp @@ -180,7 +180,7 @@ void GLScopeGUI::applyTriggerSettings() m_glScope->setTriggerChannel((ScopeVis::TriggerChannel) m_triggerChannel); m_glScope->setTriggerLevel(m_triggerLevel / 100.0); - m_scopeVis->configure(m_messageQueue, (ScopeVis::TriggerChannel) m_triggerChannel, triggerLevel, m_triggerPositiveEdge); + m_scopeVis->configure(m_messageQueue, (ScopeVis::TriggerChannel) m_triggerChannel, triggerLevel, m_triggerPositiveEdge, 0); // TODO: pass trigger delay as the last parameter } void GLScopeGUI::setTrigLevelDisplay() diff --git a/sdrbase/gui/glspectrum.cpp b/sdrbase/gui/glspectrum.cpp index 61618a421..c31940c8f 100644 --- a/sdrbase/gui/glspectrum.cpp +++ b/sdrbase/gui/glspectrum.cpp @@ -378,7 +378,7 @@ void GLSpectrum::updateHistogram(const std::vector& spectrum) m_currentSpectrum = &spectrum; // Store spectrum for current spectrum line display -#define NO_AVX +//#define NO_AVX #ifdef NO_AVX for(int i = 0; i < m_fftSize; i++) { int v = (int)((spectrum[i] - m_referenceLevel) * 100.0 / m_powerRange + 100.0); @@ -410,7 +410,7 @@ void GLSpectrum::updateHistogram(const std::vector& spectrum) if((v >= 0) && (v <= 99)) { b = m_histogram + (i + j) * 100 + v; if(*b < 220) - *b += 4; + *b += m_histogramStroke; // was 4 else if(*b < 239) *b += 1; }