1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-17 13:51:47 -05:00

New scope: basic single X display

This commit is contained in:
f4exb 2017-02-06 02:40:31 +01:00
parent 0f5c055eca
commit 4d36eeb4c7
7 changed files with 265 additions and 178 deletions

View File

@ -45,10 +45,13 @@ ScopeVisNG::ScopeVisNG(GLScopeNG* glScope) :
m_traceCompleteCount(0), m_traceCompleteCount(0),
m_timeOfsProMill(0), m_timeOfsProMill(0),
m_sampleRate(0), m_sampleRate(0),
m_traceDiscreteMemory(10) m_traceDiscreteMemory(10),
m_freeRun(true),
m_maxTraceDelay(0)
{ {
setObjectName("ScopeVisNG"); setObjectName("ScopeVisNG");
m_traceDiscreteMemory.resize(m_traceChunkSize); // arbitrary m_traceDiscreteMemory.resize(m_traceChunkSize); // arbitrary
m_glScope->setTraces(&m_traces.m_tracesData, &m_traces.m_traces[0]);
} }
ScopeVisNG::~ScopeVisNG() 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); 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) 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; m_triggerPoint = cbegin;
} }
else if (m_triggerState == TriggerTriggered) { 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 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 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;
} // begin < end } // begin < end
} }
else
{
m_traceStart = true;
}
int remainder = -1; int remainder = -1;
int count = end - begin; // number of samples in traceback buffer past the current point 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; SampleVector::iterator nbegin = nend - count;
// trace process // 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 // trace back
if (m_traceStart) if ((m_traceStart) && (m_preTriggerDelay + m_maxTraceDelay > 0))
{ {
int maxTraceDelay = 0; remainder = processTraces(count + m_preTriggerDelay + m_maxTraceDelay, count, m_traceDiscreteMemory.current(), true);
for (std::vector<Trace>::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);
m_traceStart = false; m_traceStart = false;
} }
@ -239,16 +236,9 @@ void ScopeVisNG::feed(const SampleVector::const_iterator& cbegin, const SampleVe
if (remainder >= 0) // finished if (remainder >= 0) // finished
{ {
m_glScope->newTraces();
nbegin = nend - remainder; nbegin = nend - remainder;
m_traceDiscreteMemory.current().m_endPoint = nbegin; m_traceDiscreteMemory.current().m_endPoint = nbegin;
m_traceDiscreteMemory.store(); // next memory trace m_traceDiscreteMemory.store(); // next memory trace
for (std::vector<Trace>::iterator itTrace = m_traces.begin(); itTrace != m_traces.end(); ++itTrace) {
itTrace->reset();
}
m_traceCompleteCount = 0; m_traceCompleteCount = 0;
} }
} }
@ -292,7 +282,7 @@ bool ScopeVisNG::nextTrigger()
return false; // final 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::iterator begin = traceBuffer.current() - beginPointDelta;
SampleVector::const_iterator end = traceBuffer.current() - endPointDelta; SampleVector::const_iterator end = traceBuffer.current() - endPointDelta;
@ -300,18 +290,22 @@ int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackB
while (begin < end) while (begin < end)
{ {
for (std::vector<Trace>::iterator itTrace = m_traces.begin(); itTrace != m_traces.end(); ++itTrace) std::vector<TraceControl>::iterator itCtl = m_traces.m_tracesControl.begin();
std::vector<TraceData>::iterator itData = m_traces.m_tracesData.begin();
std::vector<float *>::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; 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 posLimit = 1.0 / itData->m_amp;
float negLimit = -1.0 / itTrace->m_traceData.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) { if(v > posLimit) {
v = posLimit; v = posLimit;
@ -319,13 +313,14 @@ int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackB
v = negLimit; v = negLimit;
} }
itTrace->m_trace[2*(itTrace->m_traceCount)] = (itTrace->m_traceCount - shift); // display x (*itTrace)[2*(itCtl->m_traceCount[m_traces.currentBufferIndex()])]
itTrace->m_trace[2*(itTrace->m_traceCount) + 1] = v; // display y = (itCtl->m_traceCount[m_traces.currentBufferIndex()] - shift); // display x
itTrace->m_traceCount++; (*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()) 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 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; traceBuffer.m_endPoint = begin;
return end - begin; // return remainder count return end - begin; // return remainder count
} }
@ -351,19 +347,6 @@ int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackB
{ {
return -1; // mark not finished 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() void ScopeVisNG::start()
@ -391,20 +374,14 @@ bool ScopeVisNG::handleMessage(const Message& message)
uint32_t traceSize = conf.getTraceSize(); uint32_t traceSize = conf.getTraceSize();
uint32_t timeOfsProMill = conf.getTimeOfsProMill(); uint32_t timeOfsProMill = conf.getTimeOfsProMill();
bool freeRun = conf.getFreeRun();
if (m_traceSize != traceSize) if (m_traceSize != traceSize)
{ {
m_traceSize = traceSize; m_traceSize = traceSize;
m_traces.resize(m_traceSize);
std::vector<Trace>::iterator it = m_traces.begin();
for (; it != m_traces.end(); ++it)
{
it->resize(m_traceSize);
initTrace(*it);
}
m_traceDiscreteMemory.resize(m_traceSize); m_traceDiscreteMemory.resize(m_traceSize);
initTraceBuffers();
if (m_glScope) { if (m_glScope) {
m_glScope->setTraceSize(m_traceSize); 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:" qDebug() << "ScopeVisNG::handleMessage: MsgConfigureScopeVisNG:"
<< " m_traceSize: " << m_traceSize << " m_traceSize: " << m_traceSize
<< " m_timeOfsProMill: " << m_timeOfsProMill; << " m_timeOfsProMill: " << m_timeOfsProMill
<< " m_freeRun: " << m_freeRun;
return true; return true;
} }
@ -458,21 +441,16 @@ bool ScopeVisNG::handleMessage(const Message& message)
else if (MsgScopeVisNGAddTrace::match(message)) else if (MsgScopeVisNGAddTrace::match(message))
{ {
MsgScopeVisNGAddTrace& conf = (MsgScopeVisNGAddTrace&) message; MsgScopeVisNGAddTrace& conf = (MsgScopeVisNGAddTrace&) message;
m_traces.push_back(Trace(conf.getTraceData(), m_traceSize)); m_traces.addTrace(conf.getTraceData(), m_traceSize);
m_traces.back().init(); initTraceBuffers();
initTrace(m_traces.back()); updateMaxTraceDelay();
m_glScope->addTrace(&m_traces.back());
return true; return true;
} }
else if (MsgScopeVisNGChangeTrace::match(message)) else if (MsgScopeVisNGChangeTrace::match(message))
{ {
MsgScopeVisNGChangeTrace& conf = (MsgScopeVisNGChangeTrace&) message; MsgScopeVisNGChangeTrace& conf = (MsgScopeVisNGChangeTrace&) message;
int traceIndex = conf.getTraceIndex(); m_traces.changeTrace(conf.getTraceData(), conf.getTraceIndex());
updateMaxTraceDelay();
if (traceIndex < m_traces.size()) {
m_traces[traceIndex].setData(conf.getTraceData());
}
m_glScope->updateDisplay(); m_glScope->updateDisplay();
return true; return true;
@ -480,13 +458,8 @@ bool ScopeVisNG::handleMessage(const Message& message)
else if (MsgScopeVisNGRemoveTrace::match(message)) else if (MsgScopeVisNGRemoveTrace::match(message))
{ {
MsgScopeVisNGRemoveTrace& conf = (MsgScopeVisNGRemoveTrace&) message; MsgScopeVisNGRemoveTrace& conf = (MsgScopeVisNGRemoveTrace&) message;
int traceIndex = conf.getTraceIndex(); m_traces.removeTrace(conf.getTraceIndex());
updateMaxTraceDelay();
if (traceIndex < m_traces.size()) {
m_traces.erase(m_traces.begin() + traceIndex);
m_glScope->removeTrace(traceIndex);
}
return true; return true;
} }
else else
@ -495,3 +468,38 @@ bool ScopeVisNG::handleMessage(const Message& message)
} }
} }
void ScopeVisNG::updateMaxTraceDelay()
{
int maxTraceDelay = 0;
for (std::vector<TraceData>::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<float *>::iterator it0 = m_traces.m_traces[0].begin();
std::vector<float *>::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
}
}
}

View File

@ -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 struct TriggerData
{ {
ProjectionType m_projectionType; //!< Complex to real projection type ProjectionType m_projectionType; //!< Complex to real projection type
@ -91,8 +80,6 @@ public:
{} {}
}; };
typedef std::vector<DisplayTrace*> DisplayTraces;
static const uint m_traceChunkSize; static const uint m_traceChunkSize;
static const uint m_nbTriggers = 10; static const uint m_nbTriggers = 10;
@ -100,7 +87,7 @@ public:
virtual ~ScopeVisNG(); virtual ~ScopeVisNG();
void setSampleRate(int sampleRate); 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 addTrace(const TraceData& traceData);
void changeTrace(const TraceData& traceData, uint32_t traceIndex); void changeTrace(const TraceData& traceData, uint32_t traceIndex);
void removeTrace(uint32_t traceIndex); void removeTrace(uint32_t traceIndex);
@ -123,22 +110,27 @@ private:
public: public:
static MsgConfigureScopeVisNG* create( static MsgConfigureScopeVisNG* create(
uint32_t traceSize, 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 getTraceSize() const { return m_traceSize; }
uint32_t getTimeOfsProMill() const { return m_timeOfsProMill; } uint32_t getTimeOfsProMill() const { return m_timeOfsProMill; }
bool getFreeRun() const { return m_freeRun; }
private: private:
uint32_t m_traceSize; uint32_t m_traceSize;
uint32_t m_timeOfsProMill; uint32_t m_timeOfsProMill;
bool m_freeRun;
MsgConfigureScopeVisNG(uint32_t traceSize, MsgConfigureScopeVisNG(uint32_t traceSize,
uint32_t timeOfsProMill) : uint32_t timeOfsProMill,
bool freeRun) :
m_traceSize(traceSize), m_traceSize(traceSize),
m_timeOfsProMill(timeOfsProMill) m_timeOfsProMill(timeOfsProMill),
m_freeRun(freeRun)
{} {}
}; };
@ -328,7 +320,8 @@ private:
virtual Real run(const Sample& s) virtual Real run(const Sample& s)
{ {
uint32_t magsq = s.m_real*s.m_real + s.m_imag*s.m_imag; 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: private:
static const Real mult; static const Real mult;
@ -351,7 +344,7 @@ private:
virtual ~ProjectorDPhase() {} virtual ~ProjectorDPhase() {}
virtual Real run(const Sample& s) 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; Real dPhi = curArg - m_prevArg;
m_prevArg = curArg; m_prevArg = curArg;
@ -361,7 +354,7 @@ private:
dPhi -= 2.0 * M_PI; dPhi -= 2.0 * M_PI;
} }
return dPhi; return dPhi/M_PI;
} }
private: private:
@ -394,7 +387,6 @@ private:
*/ */
enum TriggerState enum TriggerState
{ {
TriggerFreeRun, //!< Trigger is disabled
TriggerUntriggered, //!< Trigger is not kicked off yet (or trigger list is empty) TriggerUntriggered, //!< Trigger is not kicked off yet (or trigger list is empty)
TriggerTriggered, //!< Trigger has been kicked off TriggerTriggered, //!< Trigger has been kicked off
TriggerWait, //!< In one shot mode trigger waits for manual re-enabling TriggerWait, //!< In one shot mode trigger waits for manual re-enabling
@ -488,11 +480,12 @@ private:
std::vector<TraceBackBuffer> m_traceBackBuffers; std::vector<TraceBackBuffer> m_traceBackBuffers;
uint32_t m_memSize; uint32_t m_memSize;
uint32_t m_currentMemIndex; uint32_t m_currentMemIndex;
uint32_t m_traceSize;
/** /**
* Give memory size in number of traces * 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); m_traceBackBuffers.resize(m_memSize);
} }
@ -502,19 +495,25 @@ private:
*/ */
void resize(uint32_t size) void resize(uint32_t size)
{ {
m_traceSize = size;
for (std::vector<TraceBackBuffer>::iterator it = m_traceBackBuffers.begin(); it != m_traceBackBuffers.end(); ++it) for (std::vector<TraceBackBuffer>::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 * 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() TraceBackBuffer &store()
{ {
m_currentMemIndex = m_currentMemIndex < m_memSize ? m_currentMemIndex+1 : 0; uint32_t nextMemIndex = m_currentMemIndex < (m_memSize-1) ? m_currentMemIndex+1 : 0;
m_traceBackBuffers[m_currentMemIndex].reset(); 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 return m_traceBackBuffers[m_currentMemIndex]; // new trace
} }
@ -534,66 +533,133 @@ private:
{ {
return m_traceBackBuffers[m_currentMemIndex]; return m_traceBackBuffers[m_currentMemIndex];
} }
/**
* Return current memory index
*/
uint32_t currentIndex() const { return m_currentMemIndex; }
}; };
/** /**
* Displayable trace stuff * Displayable trace stuff
*/ */
struct Trace : public DisplayTrace struct TraceControl
{ {
Projector *m_projector; //!< Projector transform from complex trace to real (displayable) trace Projector *m_projector; //!< Projector transform from complex trace to real (displayable) trace
int m_traceSize; //!< Size of the trace in buffer int m_traceCount[2]; //!< Count of samples processed (double buffered)
int m_maxTraceSize;
int m_traceCount; //!< Count of samples processed
Trace(const TraceData& traceData, int traceSize) : TraceControl() : m_projector(0)
DisplayTrace(traceData),
m_projector(0),
m_traceSize(traceSize),
m_maxTraceSize(traceSize),
m_traceCount(0)
{ {
reset();
} }
~Trace() ~TraceControl()
{ {
if (m_projector) delete m_projector; 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); if (m_projector) delete m_projector;
m_trace = new float[2*m_traceSize]; 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<TraceControl> m_tracesControl; //!< Corresponding traces control data
std::vector<TraceData> m_tracesData; //!< Corresponding traces data
std::vector<float *> 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<float *>::iterator it0 = m_traces[0].begin();
std::vector<float *>::iterator it1 = m_traces[1].begin();
for (; it0 != m_traces[0].end(); ++it0, ++it1)
{ {
delete m_projector; delete[] (*it0);
m_projector = createProjector(m_traceData.m_projectionType); 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) void resize(int traceSize)
{ {
m_traceSize = traceSize; m_traceSize = traceSize;
m_traceCount = 0;
if (m_traceSize > m_maxTraceSize) if (m_traceSize > m_maxTraceSize)
{ {
delete[] m_trace; std::vector<float *>::iterator it0 = m_traces[0].begin();
m_trace = new float[2*m_traceSize]; std::vector<float *>::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; 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<TraceControl>::iterator it = m_tracesControl.begin(); it != m_tracesControl.end(); ++it)
{
it->m_traceCount[currentBufferIndex()] = 0;
}
} }
}; };
@ -602,7 +668,7 @@ private:
std::vector<TriggerCondition> m_triggerConditions; //!< Chain of triggers std::vector<TriggerCondition> m_triggerConditions; //!< Chain of triggers
int m_currentTriggerIndex; //!< Index of current index in the chain int m_currentTriggerIndex; //!< Index of current index in the chain
TriggerState m_triggerState; //!< Current trigger state TriggerState m_triggerState; //!< Current trigger state
std::vector<Trace> 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_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_memTraceSize; //!< Trace size in memory in number of samples up to trace size
int m_timeOfsProMill; //!< Start trace shift in 1/1000 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 SampleVector::const_iterator m_triggerPoint; //!< Trigger start location in the samples vector
int m_sampleRate; int m_sampleRate;
TraceBackDiscreteMemory m_traceDiscreteMemory; //!< Complex trace memory for triggered states TODO: vectorize when more than on input is allowed 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 * 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 finished it returns the number of unprocessed samples left in the buffer
* - if not finished it returns -1 * - 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();
}; };

View File

@ -27,10 +27,12 @@
GLScopeNG::GLScopeNG(QWidget* parent) : GLScopeNG::GLScopeNG(QWidget* parent) :
QGLWidget(parent), QGLWidget(parent),
m_tracesData(0),
m_traces(0),
m_bufferIndex(0),
m_displayMode(DisplayX), m_displayMode(DisplayX),
m_dataChanged(false), m_dataChanged(false),
m_configChanged(false), m_configChanged(false),
m_traces(0),
m_displayGridIntensity(10), m_displayGridIntensity(10),
m_displayTraceIntensity(50), m_displayTraceIntensity(50),
m_timeBase(1), m_timeBase(1),
@ -63,23 +65,6 @@ GLScopeNG::~GLScopeNG()
cleanup(); 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) void GLScopeNG::setDisplayGridIntensity(int intensity)
{ {
m_displayGridIntensity = intensity; m_displayGridIntensity = intensity;
@ -102,13 +87,20 @@ void GLScopeNG::setDisplayTraceIntensity(int intensity)
update(); update();
} }
void GLScopeNG::newTraces() void GLScopeNG::setTraces(std::vector<ScopeVisNG::TraceData>* tracesData, std::vector<float *>* traces)
{ {
if (m_traces.size() > 0) m_tracesData = tracesData;
m_traces = traces;
}
void GLScopeNG::newTraces(std::vector<float *>* traces)
{
if (traces->size() > 0)
{ {
if(!m_mutex.tryLock(2)) if(!m_mutex.tryLock(2))
return; return;
m_traces = traces;
m_dataChanged = true; m_dataChanged = true;
m_mutex.unlock(); m_mutex.unlock();
@ -301,23 +293,26 @@ void GLScopeNG::paintGL()
// paint trace #1 // paint trace #1
if (m_traceSize > 0) 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 start = (m_timeOfsProMill/1000.0) * m_traceSize;
int end = std::min(start + m_traceSize/m_timeBase, m_traceSize); int end = std::min(start + m_traceSize/m_timeBase, m_traceSize);
if(end - start < 2) if(end - start < 2)
start--; start--;
float rectX = m_glScopeRect1.x(); float rectX = m_glScopeRect1.x();
float rectY = m_glScopeRect1.y() + m_glScopeRect1.height() / 2.0f; float rectY = m_glScopeRect1.y() + m_glScopeRect1.height() / 2.0f;
float rectW = m_glScopeRect1.width() * (float)m_timeBase / (float)(m_traceSize - 1); 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); QVector4D color(1.0f, 1.0f, 0.25f, m_displayTraceIntensity / 100.0f);
QMatrix4x4 mat; QMatrix4x4 mat;
mat.setToIdentity(); mat.setToIdentity();
mat.translate(-1.0f + 2.0f * rectX, 1.0f - 2.0f * rectY); mat.translate(-1.0f + 2.0f * rectX, 1.0f - 2.0f * rectY);
mat.scale(2.0f * rectW, -2.0f * rectH); 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_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 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) 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) 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) void GLScopeNG::setYScale(ScaleEngine& scale, uint32_t highlightedTraceIndex)
{ {
ScopeVisNG::DisplayTrace *trace = m_traces[highlightedTraceIndex]; ScopeVisNG::TraceData& traceData = (*m_tracesData)[highlightedTraceIndex];
float amp_range = 2.0 / trace->m_traceData.m_amp; float amp_range = 2.0 / traceData.m_amp;
float amp_ofs = trace->m_traceData.m_ofs; float amp_ofs = traceData.m_ofs;
float pow_floor = -100.0 + trace->m_traceData.m_ofs * 100.0; float pow_floor = -100.0 + traceData.m_ofs * 100.0 + 50.0f - 50.0f/traceData.m_amp;
float pow_range = 100.0 / trace->m_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 case ScopeVisNG::ProjectionMagDB: // dB scale
scale.setRange(Unit::Decibel, pow_floor, pow_floor + pow_range); scale.setRange(Unit::Decibel, pow_floor, pow_floor + pow_range);
break; break;
case ScopeVisNG::ProjectionPhase: // Phase or frequency case ScopeVisNG::ProjectionPhase: // Phase or frequency
case ScopeVisNG::ProjectionDPhase: 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; break;
case ScopeVisNG::ProjectionReal: // Linear generic case ScopeVisNG::ProjectionReal: // Linear generic
case ScopeVisNG::ProjectionImag: case ScopeVisNG::ProjectionImag:
@ -1015,8 +1010,9 @@ void GLScopeNG::setYScale(ScaleEngine& scale, uint32_t highlightedTraceIndex)
void GLScopeNG::tick() void GLScopeNG::tick()
{ {
if(m_dataChanged) if(m_dataChanged) {
update(); update();
}
} }
void GLScopeNG::connectTimer(const QTimer& timer) void GLScopeNG::connectTimer(const QTimer& timer)

View File

@ -51,9 +51,8 @@ public:
void connectTimer(const QTimer& timer); void connectTimer(const QTimer& timer);
void addTrace(ScopeVisNG::DisplayTrace *trace); void setTraces(std::vector<ScopeVisNG::TraceData>* tracesData, std::vector<float *>* traces);
void removeTrace(int index); void newTraces(std::vector<float *>* traces);
void newTraces();
int getSampleRate() const { return m_sampleRate; } int getSampleRate() const { return m_sampleRate; }
int getTraceSize() const { return m_traceSize; } int getTraceSize() const { return m_traceSize; }
@ -73,12 +72,14 @@ signals:
void sampleRateChanged(int); void sampleRateChanged(int);
private: private:
std::vector<ScopeVisNG::TraceData> *m_tracesData;
std::vector<float *> *m_traces;
uint32_t m_bufferIndex;
DisplayMode m_displayMode; DisplayMode m_displayMode;
QTimer m_timer; QTimer m_timer;
QMutex m_mutex; QMutex m_mutex;
bool m_dataChanged; bool m_dataChanged;
bool m_configChanged; bool m_configChanged;
ScopeVisNG::DisplayTraces m_traces;
int m_sampleRate; int m_sampleRate;
int m_timeOfsProMill; int m_timeOfsProMill;
Real m_triggerPre; Real m_triggerPre;

View File

@ -84,8 +84,8 @@ void GLScopeNGGUI::setBuddies(MessageQueue* messageQueue, ScopeVisNG* scopeVis,
ui->trigMode->clear(); ui->trigMode->clear();
fillProjectionCombo(ui->trigMode); fillProjectionCombo(ui->trigMode);
m_scopeVis->configure(2*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); m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize, m_timeOffset*10, ui->freerun->isChecked());
setTraceLenDisplay(); setTraceLenDisplay();
setTimeScaleDisplay(); setTimeScaleDisplay();
@ -225,7 +225,7 @@ void GLScopeNGGUI::on_timeOfs_valueChanged(int value)
m_timeOffset = value; m_timeOffset = value;
setTimeOfsDisplay(); 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) void GLScopeNGGUI::on_traceLen_valueChanged(int value)
@ -235,7 +235,7 @@ void GLScopeNGGUI::on_traceLen_valueChanged(int value)
} }
m_traceLenMult = 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(); setTraceLenDisplay();
setTimeScaleDisplay(); setTimeScaleDisplay();
setTimeOfsDisplay(); setTimeOfsDisplay();
@ -253,6 +253,11 @@ void GLScopeNGGUI::on_amp_valueChanged(int value)
changeCurrentTrace(); 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() void GLScopeNGGUI::setTimeScaleDisplay()
{ {
m_sampleRate = m_glScope->getSampleRate(); m_sampleRate = m_glScope->getSampleRate();

View File

@ -78,6 +78,7 @@ private:
private slots: private slots:
void on_scope_sampleRateChanged(int value); void on_scope_sampleRateChanged(int value);
// First row
void on_onlyX_toggled(bool checked); void on_onlyX_toggled(bool checked);
void on_onlyY_toggled(bool checked); void on_onlyY_toggled(bool checked);
void on_horizontalXY_toggled(bool checked); void on_horizontalXY_toggled(bool checked);
@ -88,8 +89,11 @@ private slots:
void on_time_valueChanged(int value); void on_time_valueChanged(int value);
void on_timeOfs_valueChanged(int value); void on_timeOfs_valueChanged(int value);
void on_traceLen_valueChanged(int value); void on_traceLen_valueChanged(int value);
// Second row
void on_traceMode_currentIndexChanged(int index); void on_traceMode_currentIndexChanged(int index);
void on_amp_valueChanged(int value); void on_amp_valueChanged(int value);
// Third row
void on_freerun_toggled(bool checked);
}; };

View File

@ -465,7 +465,7 @@ kS/s</string>
<widget class="QLabel" name="traceLabel"> <widget class="QLabel" name="traceLabel">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>20</width> <width>24</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -971,7 +971,7 @@ kS/s</string>
<widget class="QLabel" name="trigLabel"> <widget class="QLabel" name="trigLabel">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>20</width> <width>24</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>