diff --git a/sdrbase/dsp/scopevisng.cpp b/sdrbase/dsp/scopevisng.cpp index a572088d0..e20bc59ce 100644 --- a/sdrbase/dsp/scopevisng.cpp +++ b/sdrbase/dsp/scopevisng.cpp @@ -45,10 +45,13 @@ ScopeVisNG::ScopeVisNG(GLScopeNG* glScope) : m_traceCompleteCount(0), m_timeOfsProMill(0), m_sampleRate(0), - m_traceDiscreteMemory(10) + m_traceDiscreteMemory(10), + m_freeRun(true), + m_maxTraceDelay(0) { setObjectName("ScopeVisNG"); m_traceDiscreteMemory.resize(m_traceChunkSize); // arbitrary + m_glScope->setTraces(&m_traces.m_tracesData, &m_traces.m_traces[0]); } ScopeVisNG::~ScopeVisNG() @@ -64,9 +67,9 @@ void ScopeVisNG::setSampleRate(int sampleRate) } } -void ScopeVisNG::configure(uint32_t traceSize, uint32_t timeOfsProMill) +void ScopeVisNG::configure(uint32_t traceSize, uint32_t timeOfsProMill, bool freeRun) { - Message* cmd = MsgConfigureScopeVisNG::create(traceSize, timeOfsProMill); + Message* cmd = MsgConfigureScopeVisNG::create(traceSize, timeOfsProMill, freeRun); getInputMessageQueue()->push(cmd); } @@ -110,7 +113,7 @@ void ScopeVisNG::removeTrigger(uint32_t triggerIndex) void ScopeVisNG::feed(const SampleVector::const_iterator& cbegin, const SampleVector::const_iterator& end, bool positiveOnly) { - if (m_triggerState == TriggerFreeRun) { + if (m_freeRun) { m_triggerPoint = cbegin; } else if (m_triggerState == TriggerTriggered) { @@ -147,9 +150,9 @@ void ScopeVisNG::feed(const SampleVector::const_iterator& cbegin, const SampleVe return; // not enough samples in memory } - // trigger process + // trigger process - if ((m_triggerConditions.size() > 0) && ((m_triggerState == TriggerUntriggered) || (m_triggerState == TriggerDelay))) + if (!m_freeRun && (m_triggerConditions.size() > 0) && ((m_triggerState == TriggerUntriggered) || (m_triggerState == TriggerDelay))) { TriggerCondition& triggerCondition = m_triggerConditions[m_currentTriggerIndex]; // current trigger condition @@ -204,6 +207,10 @@ void ScopeVisNG::feed(const SampleVector::const_iterator& cbegin, const SampleVe ++begin; } // begin < end } + else + { + m_traceStart = true; + } int remainder = -1; int count = end - begin; // number of samples in traceback buffer past the current point @@ -211,23 +218,13 @@ void ScopeVisNG::feed(const SampleVector::const_iterator& cbegin, const SampleVe SampleVector::iterator nbegin = nend - count; // trace process - if ((m_triggerState == TriggerFreeRun) || (m_triggerConditions.size() == 0) || (m_triggerState == TriggerTriggered)) + if ((m_freeRun) || (m_triggerConditions.size() == 0) || (m_triggerState == TriggerTriggered)) { // trace back - if (m_traceStart) + if ((m_traceStart) && (m_preTriggerDelay + m_maxTraceDelay > 0)) { - int maxTraceDelay = 0; - - for (std::vector::iterator itTrace = m_traces.begin(); itTrace != m_traces.end(); ++itTrace) - { - if (itTrace->m_traceData.m_traceDelay > maxTraceDelay) - { - maxTraceDelay = itTrace->m_traceData.m_traceDelay; - } - } - - remainder = processTraces(count + m_preTriggerDelay + maxTraceDelay, count, m_traceDiscreteMemory.current(), true); + remainder = processTraces(count + m_preTriggerDelay + m_maxTraceDelay, count, m_traceDiscreteMemory.current(), true); m_traceStart = false; } @@ -239,16 +236,9 @@ void ScopeVisNG::feed(const SampleVector::const_iterator& cbegin, const SampleVe if (remainder >= 0) // finished { - m_glScope->newTraces(); - nbegin = nend - remainder; m_traceDiscreteMemory.current().m_endPoint = nbegin; m_traceDiscreteMemory.store(); // next memory trace - - for (std::vector::iterator itTrace = m_traces.begin(); itTrace != m_traces.end(); ++itTrace) { - itTrace->reset(); - } - m_traceCompleteCount = 0; } } @@ -292,7 +282,7 @@ bool ScopeVisNG::nextTrigger() return false; // final } -int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackBuffer& traceBuffer, bool traceStart) +int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackBuffer& traceBuffer, bool traceBack) { SampleVector::iterator begin = traceBuffer.current() - beginPointDelta; SampleVector::const_iterator end = traceBuffer.current() - endPointDelta; @@ -300,18 +290,22 @@ int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackB while (begin < end) { - for (std::vector::iterator itTrace = m_traces.begin(); itTrace != m_traces.end(); ++itTrace) + std::vector::iterator itCtl = m_traces.m_tracesControl.begin(); + std::vector::iterator itData = m_traces.m_tracesData.begin(); + std::vector::iterator itTrace = m_traces.m_traces[m_traces.currentBufferIndex()].begin(); + + for (; itCtl != m_traces.m_tracesControl.end(); ++itCtl, ++itData, ++itTrace) { - if (traceStart && ((end - begin) > m_preTriggerDelay + itTrace->m_traceData.m_traceDelay)) { + if (traceBack && ((end - begin) > m_preTriggerDelay + itData->m_traceDelay)) { continue; } - if (itTrace->m_traceCount < m_traceSize) + if (itCtl->m_traceCount[m_traces.currentBufferIndex()] < m_traceSize) { - float posLimit = 1.0 / itTrace->m_traceData.m_amp; - float negLimit = -1.0 / itTrace->m_traceData.m_amp; + float posLimit = 1.0 / itData->m_amp; + float negLimit = -1.0 / itData->m_amp; - float v = itTrace->m_projector->run(*begin) * itTrace->m_traceData.m_amp + itTrace->m_traceData.m_ofs; + float v = itCtl->m_projector->run(*begin) * itData->m_amp + itData->m_ofs; if(v > posLimit) { v = posLimit; @@ -319,13 +313,14 @@ int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackB v = negLimit; } - itTrace->m_trace[2*(itTrace->m_traceCount)] = (itTrace->m_traceCount - shift); // display x - itTrace->m_trace[2*(itTrace->m_traceCount) + 1] = v; // display y - itTrace->m_traceCount++; + (*itTrace)[2*(itCtl->m_traceCount[m_traces.currentBufferIndex()])] + = (itCtl->m_traceCount[m_traces.currentBufferIndex()] - shift); // display x + (*itTrace)[2*(itCtl->m_traceCount[m_traces.currentBufferIndex()]) + 1] = v; // display y + itCtl->m_traceCount[m_traces.currentBufferIndex()]++; } - else if (itTrace->m_traceCount < m_traceSize) + else { - itTrace->m_traceCount++; + itCtl->m_traceCount[m_traces.currentBufferIndex()]++; if (m_traceCompleteCount < m_traces.size()) { @@ -338,12 +333,13 @@ int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackB } } - begin++; + ++begin; } if (m_traceCompleteCount == m_traces.size()) // finished { - m_glScope->newTraces(); + m_glScope->newTraces(&m_traces.m_traces[m_traces.currentBufferIndex()]); + m_traces.switchBuffer(); traceBuffer.m_endPoint = begin; return end - begin; // return remainder count } @@ -351,19 +347,6 @@ int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackB { return -1; // mark not finished } - -} - -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() @@ -391,20 +374,14 @@ bool ScopeVisNG::handleMessage(const Message& message) uint32_t traceSize = conf.getTraceSize(); uint32_t timeOfsProMill = conf.getTimeOfsProMill(); + bool freeRun = conf.getFreeRun(); 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_traces.resize(m_traceSize); m_traceDiscreteMemory.resize(m_traceSize); + initTraceBuffers(); if (m_glScope) { m_glScope->setTraceSize(m_traceSize); @@ -420,9 +397,15 @@ bool ScopeVisNG::handleMessage(const Message& message) } } + if (freeRun != m_freeRun) + { + m_freeRun = freeRun; + } + qDebug() << "ScopeVisNG::handleMessage: MsgConfigureScopeVisNG:" << " m_traceSize: " << m_traceSize - << " m_timeOfsProMill: " << m_timeOfsProMill; + << " m_timeOfsProMill: " << m_timeOfsProMill + << " m_freeRun: " << m_freeRun; return true; } @@ -458,21 +441,16 @@ bool ScopeVisNG::handleMessage(const Message& message) else if (MsgScopeVisNGAddTrace::match(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()); + m_traces.addTrace(conf.getTraceData(), m_traceSize); + initTraceBuffers(); + updateMaxTraceDelay(); return true; } else if (MsgScopeVisNGChangeTrace::match(message)) { MsgScopeVisNGChangeTrace& conf = (MsgScopeVisNGChangeTrace&) message; - int traceIndex = conf.getTraceIndex(); - - if (traceIndex < m_traces.size()) { - m_traces[traceIndex].setData(conf.getTraceData()); - } - + m_traces.changeTrace(conf.getTraceData(), conf.getTraceIndex()); + updateMaxTraceDelay(); m_glScope->updateDisplay(); return true; @@ -480,13 +458,8 @@ bool ScopeVisNG::handleMessage(const Message& message) else if (MsgScopeVisNGRemoveTrace::match(message)) { MsgScopeVisNGRemoveTrace& conf = (MsgScopeVisNGRemoveTrace&) message; - int traceIndex = conf.getTraceIndex(); - - if (traceIndex < m_traces.size()) { - m_traces.erase(m_traces.begin() + traceIndex); - m_glScope->removeTrace(traceIndex); - } - + m_traces.removeTrace(conf.getTraceIndex()); + updateMaxTraceDelay(); return true; } else @@ -495,3 +468,38 @@ bool ScopeVisNG::handleMessage(const Message& message) } } + +void ScopeVisNG::updateMaxTraceDelay() +{ + int maxTraceDelay = 0; + + for (std::vector::iterator itData = m_traces.m_tracesData.begin(); itData != m_traces.m_tracesData.end(); ++itData) + { + if (itData->m_traceDelay > maxTraceDelay) + { + maxTraceDelay = itData->m_traceDelay; + } + } + + m_maxTraceDelay = maxTraceDelay; +} + +void ScopeVisNG::initTraceBuffers() +{ + int shift = (m_timeOfsProMill / 1000.0) * m_traceSize; + + std::vector::iterator it0 = m_traces.m_traces[0].begin(); + std::vector::iterator it1 = m_traces.m_traces[1].begin(); + + for (; it0 != m_traces.m_traces[0].end(); ++it0, ++it1) + { + for (int i = 0; i < m_traceSize; i++) + { + (*it0)[2*i] = (i - shift); // display x + (*it0)[2*i + 1] = 0.0f; // display y + (*it1)[2*i] = (i - shift); // display x + (*it1)[2*i + 1] = 0.0f; // display y + } + } +} + diff --git a/sdrbase/dsp/scopevisng.h b/sdrbase/dsp/scopevisng.h index 608c4266e..97f8c75e4 100644 --- a/sdrbase/dsp/scopevisng.h +++ b/sdrbase/dsp/scopevisng.h @@ -59,17 +59,6 @@ public: {} }; - struct DisplayTrace - { - TraceData m_traceData; //!< Trace data - float *m_trace; //!< Displayable trace (interleaved x,y of GLfloat) - - DisplayTrace(const TraceData& traceData) : - m_traceData(traceData), - m_trace(0) - {} - }; - struct TriggerData { ProjectionType m_projectionType; //!< Complex to real projection type @@ -91,8 +80,6 @@ public: {} }; - typedef std::vector DisplayTraces; - static const uint m_traceChunkSize; static const uint m_nbTriggers = 10; @@ -100,7 +87,7 @@ public: virtual ~ScopeVisNG(); void setSampleRate(int sampleRate); - void configure(uint32_t traceSize, uint32_t timeOfsProMill); + void configure(uint32_t traceSize, uint32_t timeOfsProMill, bool freeRun); void addTrace(const TraceData& traceData); void changeTrace(const TraceData& traceData, uint32_t traceIndex); void removeTrace(uint32_t traceIndex); @@ -123,22 +110,27 @@ private: public: static MsgConfigureScopeVisNG* create( uint32_t traceSize, - uint32_t timeOfsProMill) + uint32_t timeOfsProMill, + bool freeRun) { - return new MsgConfigureScopeVisNG(traceSize, timeOfsProMill); + return new MsgConfigureScopeVisNG(traceSize, timeOfsProMill, freeRun); } uint32_t getTraceSize() const { return m_traceSize; } uint32_t getTimeOfsProMill() const { return m_timeOfsProMill; } + bool getFreeRun() const { return m_freeRun; } private: uint32_t m_traceSize; uint32_t m_timeOfsProMill; + bool m_freeRun; MsgConfigureScopeVisNG(uint32_t traceSize, - uint32_t timeOfsProMill) : + uint32_t timeOfsProMill, + bool freeRun) : m_traceSize(traceSize), - m_timeOfsProMill(timeOfsProMill) + m_timeOfsProMill(timeOfsProMill), + m_freeRun(freeRun) {} }; @@ -328,7 +320,8 @@ private: virtual Real run(const Sample& s) { uint32_t magsq = s.m_real*s.m_real + s.m_imag*s.m_imag; - return mult * log2f(magsq/1073741824.0f); + //return mult * log2f(magsq/1073741824.0f); + return (log10f(magsq/1073741824.0f) / 5.0f) + 1.0f; } private: static const Real mult; @@ -351,7 +344,7 @@ private: virtual ~ProjectorDPhase() {} virtual Real run(const Sample& s) { - Real curArg = std::atan2((float) s.m_imag, (float) s.m_real) / M_PI; + Real curArg = std::atan2((float) s.m_imag, (float) s.m_real); Real dPhi = curArg - m_prevArg; m_prevArg = curArg; @@ -361,7 +354,7 @@ private: dPhi -= 2.0 * M_PI; } - return dPhi; + return dPhi/M_PI; } private: @@ -394,7 +387,6 @@ private: */ enum TriggerState { - TriggerFreeRun, //!< Trigger is disabled TriggerUntriggered, //!< Trigger is not kicked off yet (or trigger list is empty) TriggerTriggered, //!< Trigger has been kicked off TriggerWait, //!< In one shot mode trigger waits for manual re-enabling @@ -488,11 +480,12 @@ private: std::vector m_traceBackBuffers; uint32_t m_memSize; uint32_t m_currentMemIndex; + uint32_t m_traceSize; /** * Give memory size in number of traces */ - TraceBackDiscreteMemory(uint32_t size) : m_memSize(size), m_currentMemIndex(0) + TraceBackDiscreteMemory(uint32_t size) : m_memSize(size), m_currentMemIndex(0), m_traceSize(0) { m_traceBackBuffers.resize(m_memSize); } @@ -502,19 +495,25 @@ private: */ void resize(uint32_t size) { + m_traceSize = size; + for (std::vector::iterator it = m_traceBackBuffers.begin(); it != m_traceBackBuffers.end(); ++it) { - it->resize(size); + it->resize(4*m_traceSize); } } /** * Move index forward by one position and return reference to the trace at this position + * Copy a trace length of samples into the new memory slot */ TraceBackBuffer &store() { - m_currentMemIndex = m_currentMemIndex < m_memSize ? m_currentMemIndex+1 : 0; - m_traceBackBuffers[m_currentMemIndex].reset(); + uint32_t nextMemIndex = m_currentMemIndex < (m_memSize-1) ? m_currentMemIndex+1 : 0; + m_traceBackBuffers[nextMemIndex].reset(); + m_traceBackBuffers[nextMemIndex].write(m_traceBackBuffers[m_currentMemIndex].m_endPoint - m_traceSize, + m_traceBackBuffers[m_currentMemIndex].m_endPoint); + m_currentMemIndex = nextMemIndex; return m_traceBackBuffers[m_currentMemIndex]; // new trace } @@ -534,66 +533,133 @@ private: { return m_traceBackBuffers[m_currentMemIndex]; } + + /** + * Return current memory index + */ + uint32_t currentIndex() const { return m_currentMemIndex; } }; /** * Displayable trace stuff */ - struct Trace : public DisplayTrace + struct TraceControl { Projector *m_projector; //!< Projector transform from complex trace to real (displayable) trace - int m_traceSize; //!< Size of the trace in buffer - int m_maxTraceSize; - int m_traceCount; //!< Count of samples processed + int m_traceCount[2]; //!< Count of samples processed (double buffered) - Trace(const TraceData& traceData, int traceSize) : - DisplayTrace(traceData), - m_projector(0), - m_traceSize(traceSize), - m_maxTraceSize(traceSize), - m_traceCount(0) + TraceControl() : m_projector(0) { + reset(); } - ~Trace() + ~TraceControl() { if (m_projector) delete m_projector; - if (m_trace) delete[] m_trace; } - void init() + void init(ProjectionType projectionType) { - m_projector = createProjector(m_traceData.m_projectionType); - m_trace = new float[2*m_traceSize]; + if (m_projector) delete m_projector; + m_projector = createProjector(projectionType); } - void setData(const TraceData& traceData) + void reset() { - m_traceData = traceData; + m_traceCount[0] = 0; + m_traceCount[1] = 0; + } + }; - if (m_projector->getProjectionType() != m_traceData.m_projectionType) + struct Traces + { + std::vector m_tracesControl; //!< Corresponding traces control data + std::vector m_tracesData; //!< Corresponding traces data + std::vector m_traces[2]; //!< Double buffer of traces processed by glScope + int m_traceSize; //!< Current size of a trace in buffer + int m_maxTraceSize; //!< Maximum Size of a trace in buffer + bool evenOddIndex; //!< Even (true) or odd (false) index + + Traces() : evenOddIndex(true), m_traceSize(0), m_maxTraceSize(0) {} + + ~Traces() + { + std::vector::iterator it0 = m_traces[0].begin(); + std::vector::iterator it1 = m_traces[1].begin(); + + for (; it0 != m_traces[0].end(); ++it0, ++it1) { - delete m_projector; - m_projector = createProjector(m_traceData.m_projectionType); + delete[] (*it0); + delete[] (*it1); + } + } + + void addTrace(const TraceData& traceData, int traceSize) + { + resize(traceSize); + + m_tracesData.push_back(traceData); + m_tracesControl.push_back(TraceControl()); + m_tracesControl.back().init(traceData.m_projectionType); + float *x0 = new float[2*m_traceSize]; + float *x1 = new float[2*m_traceSize]; + m_traces[0].push_back(x0); + m_traces[1].push_back(x1); + } + + void changeTrace(const TraceData& traceData, uint32_t traceIndex) + { + if (traceIndex < m_tracesControl.size()) { + m_tracesControl[traceIndex].init(traceData.m_projectionType); + m_tracesData[traceIndex] = traceData; + } + } + + void removeTrace(uint32_t traceIndex) + { + if (traceIndex < m_tracesControl.size()) + { + m_tracesControl.erase(m_tracesControl.begin() + traceIndex); + m_tracesData.erase(m_tracesData.begin() + traceIndex); + delete[] (m_traces[0])[traceIndex]; + delete[] (m_traces[1])[traceIndex]; + m_traces[0].erase(m_traces[0].begin() + traceIndex); + m_traces[1].erase(m_traces[1].begin() + traceIndex); } } void resize(int traceSize) { m_traceSize = traceSize; - m_traceCount = 0; if (m_traceSize > m_maxTraceSize) { - delete[] m_trace; - m_trace = new float[2*m_traceSize]; + std::vector::iterator it0 = m_traces[0].begin(); + std::vector::iterator it1 = m_traces[1].begin(); + + for (; it0 != m_traces[0].end(); ++it0, ++it1) + { + delete[] (*it0); + delete[] (*it1); + *it0 = new float[2*m_traceSize]; + *it1 = new float[2*m_traceSize]; + } + m_maxTraceSize = m_traceSize; } } - void reset() + uint32_t currentBufferIndex() const { return evenOddIndex? 0 : 1; } + uint32_t size() const { return m_tracesControl.size(); } + + void switchBuffer() { - m_traceCount = 0; + evenOddIndex = !evenOddIndex; + + for (std::vector::iterator it = m_tracesControl.begin(); it != m_tracesControl.end(); ++it) + { + it->m_traceCount[currentBufferIndex()] = 0; + } } }; @@ -602,7 +668,7 @@ private: std::vector m_triggerConditions; //!< Chain of triggers int m_currentTriggerIndex; //!< Index of current index in the chain TriggerState m_triggerState; //!< Current trigger state - std::vector m_traces; //!< One trace control object per display trace allocated to X, Y[n] or Z + Traces m_traces; //!< Displayable traces int m_traceSize; //!< Size of traces in number of samples int m_memTraceSize; //!< Trace size in memory in number of samples up to trace size int m_timeOfsProMill; //!< Start trace shift in 1/1000 trace size @@ -613,6 +679,8 @@ private: SampleVector::const_iterator m_triggerPoint; //!< Trigger start location in the samples vector int m_sampleRate; 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 /** * Moves on to the next trigger if any or increments trigger count if in repeat mode @@ -626,12 +694,17 @@ private: * - if finished it returns the number of unprocessed samples left in the buffer * - if not finished it returns -1 */ - int processTraces(int beginPointDelta, int endPointDelta, TraceBackBuffer& traceBuffer, bool traceStart = false); + int processTraces(int beginPointDelta, int endPointDelta, TraceBackBuffer& traceBuffer, bool traceBack = false); /** - * Initialize a trace with zero values + * Get maximum trace delay */ - void initTrace(Trace& trace); + void updateMaxTraceDelay(); + + /** + * Initialize trace buffers + */ + void initTraceBuffers(); }; diff --git a/sdrbase/gui/glscopeng.cpp b/sdrbase/gui/glscopeng.cpp index 141031033..f41005144 100644 --- a/sdrbase/gui/glscopeng.cpp +++ b/sdrbase/gui/glscopeng.cpp @@ -27,10 +27,12 @@ GLScopeNG::GLScopeNG(QWidget* parent) : QGLWidget(parent), + m_tracesData(0), + m_traces(0), + m_bufferIndex(0), m_displayMode(DisplayX), m_dataChanged(false), m_configChanged(false), - m_traces(0), m_displayGridIntensity(10), m_displayTraceIntensity(50), m_timeBase(1), @@ -63,23 +65,6 @@ GLScopeNG::~GLScopeNG() cleanup(); } -void GLScopeNG::addTrace(ScopeVisNG::DisplayTrace *trace) -{ - m_traces.push_back(trace); - m_configChanged = true; - update(); -} - -void GLScopeNG::removeTrace(int index) -{ - if (index < m_traces.size()) { - m_traces.erase(m_traces.begin() + index); - } - - m_configChanged = true; - update(); -} - void GLScopeNG::setDisplayGridIntensity(int intensity) { m_displayGridIntensity = intensity; @@ -102,13 +87,20 @@ void GLScopeNG::setDisplayTraceIntensity(int intensity) update(); } -void GLScopeNG::newTraces() +void GLScopeNG::setTraces(std::vector* tracesData, std::vector* traces) { - if (m_traces.size() > 0) + m_tracesData = tracesData; + m_traces = traces; +} + +void GLScopeNG::newTraces(std::vector* traces) +{ + if (traces->size() > 0) { if(!m_mutex.tryLock(2)) return; + m_traces = traces; m_dataChanged = true; m_mutex.unlock(); @@ -301,23 +293,26 @@ void GLScopeNG::paintGL() // paint trace #1 if (m_traceSize > 0) { - const ScopeVisNG::DisplayTrace* trace = m_traces[0]; + const float *trace = (*m_traces)[0]; + const ScopeVisNG::TraceData& traceData = (*m_tracesData)[0]; + 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) * trace->m_traceData.m_amp; + float rectH = -(m_glScopeRect1.height() / 2.0f) * 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[2*start], end - start); } } @@ -393,12 +388,12 @@ 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.size() > 0) + if (m_traces->size() > 0) { 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_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) } @@ -985,20 +980,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::TraceData& traceData = (*m_tracesData)[highlightedTraceIndex]; + float amp_range = 2.0 / traceData.m_amp; + float amp_ofs = traceData.m_ofs; + float pow_floor = -100.0 + traceData.m_ofs * 100.0 + 50.0f - 50.0f/traceData.m_amp; + float pow_range = 100.0 / traceData.m_amp; - switch (trace->m_traceData.m_projectionType) + switch (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/traceData.m_amp + amp_ofs, 1.0/traceData.m_amp + amp_ofs); break; case ScopeVisNG::ProjectionReal: // Linear generic case ScopeVisNG::ProjectionImag: @@ -1015,8 +1010,9 @@ void GLScopeNG::setYScale(ScaleEngine& scale, uint32_t highlightedTraceIndex) void GLScopeNG::tick() { - if(m_dataChanged) + if(m_dataChanged) { update(); + } } void GLScopeNG::connectTimer(const QTimer& timer) diff --git a/sdrbase/gui/glscopeng.h b/sdrbase/gui/glscopeng.h index bc7a333c6..07cbff8be 100644 --- a/sdrbase/gui/glscopeng.h +++ b/sdrbase/gui/glscopeng.h @@ -51,9 +51,8 @@ public: void connectTimer(const QTimer& timer); - void addTrace(ScopeVisNG::DisplayTrace *trace); - void removeTrace(int index); - void newTraces(); + void setTraces(std::vector* tracesData, std::vector* traces); + void newTraces(std::vector* traces); int getSampleRate() const { return m_sampleRate; } int getTraceSize() const { return m_traceSize; } @@ -73,12 +72,14 @@ signals: void sampleRateChanged(int); private: + std::vector *m_tracesData; + std::vector *m_traces; + uint32_t m_bufferIndex; DisplayMode m_displayMode; QTimer m_timer; QMutex m_mutex; bool m_dataChanged; bool m_configChanged; - ScopeVisNG::DisplayTraces m_traces; int m_sampleRate; int m_timeOfsProMill; Real m_triggerPre; diff --git a/sdrbase/gui/glscopenggui.cpp b/sdrbase/gui/glscopenggui.cpp index 08397e7ca..d7d07e16e 100644 --- a/sdrbase/gui/glscopenggui.cpp +++ b/sdrbase/gui/glscopenggui.cpp @@ -84,8 +84,8 @@ void GLScopeNGGUI::setBuddies(MessageQueue* messageQueue, ScopeVisNG* scopeVis, ui->trigMode->clear(); fillProjectionCombo(ui->trigMode); - m_scopeVis->configure(2*m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10); - m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10); + m_scopeVis->configure(2*m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10, ui->freerun->isChecked()); + m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10, ui->freerun->isChecked()); setTraceLenDisplay(); setTimeScaleDisplay(); @@ -225,7 +225,7 @@ void GLScopeNGGUI::on_timeOfs_valueChanged(int value) m_timeOffset = value; setTimeOfsDisplay(); - m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10); + m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10, ui->freerun->isChecked()); } void GLScopeNGGUI::on_traceLen_valueChanged(int value) @@ -235,7 +235,7 @@ void GLScopeNGGUI::on_traceLen_valueChanged(int value) } m_traceLenMult = value; - m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10); + m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10, ui->freerun->isChecked()); setTraceLenDisplay(); setTimeScaleDisplay(); setTimeOfsDisplay(); @@ -253,6 +253,11 @@ void GLScopeNGGUI::on_amp_valueChanged(int value) changeCurrentTrace(); } +void GLScopeNGGUI::on_freerun_toggled(bool checked) +{ + m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10, ui->freerun->isChecked()); +} + void GLScopeNGGUI::setTimeScaleDisplay() { m_sampleRate = m_glScope->getSampleRate(); diff --git a/sdrbase/gui/glscopenggui.h b/sdrbase/gui/glscopenggui.h index c2f1160c2..164d30f3f 100644 --- a/sdrbase/gui/glscopenggui.h +++ b/sdrbase/gui/glscopenggui.h @@ -78,6 +78,7 @@ private: private slots: void on_scope_sampleRateChanged(int value); + // First row void on_onlyX_toggled(bool checked); void on_onlyY_toggled(bool checked); void on_horizontalXY_toggled(bool checked); @@ -88,8 +89,11 @@ private slots: void on_time_valueChanged(int value); void on_timeOfs_valueChanged(int value); void on_traceLen_valueChanged(int value); + // Second row void on_traceMode_currentIndexChanged(int index); void on_amp_valueChanged(int value); + // Third row + void on_freerun_toggled(bool checked); }; diff --git a/sdrbase/gui/glscopenggui.ui b/sdrbase/gui/glscopenggui.ui index 1f00ea483..0135de025 100644 --- a/sdrbase/gui/glscopenggui.ui +++ b/sdrbase/gui/glscopenggui.ui @@ -465,7 +465,7 @@ kS/s - 20 + 24 0 @@ -971,7 +971,7 @@ kS/s - 20 + 24 0