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:
parent
0f5c055eca
commit
4d36eeb4c7
@ -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<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);
|
||||
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<Trace>::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<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;
|
||||
}
|
||||
|
||||
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<Trace>::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<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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<DisplayTrace*> 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<TraceBackBuffer> 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<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
|
||||
* 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<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;
|
||||
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<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[] (*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<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
|
||||
int m_currentTriggerIndex; //!< Index of current index in the chain
|
||||
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_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();
|
||||
};
|
||||
|
||||
|
||||
|
@ -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<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))
|
||||
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)
|
||||
|
@ -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<ScopeVisNG::TraceData>* tracesData, std::vector<float *>* traces);
|
||||
void newTraces(std::vector<float *>* traces);
|
||||
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
int getTraceSize() const { return m_traceSize; }
|
||||
@ -73,12 +72,14 @@ signals:
|
||||
void sampleRateChanged(int);
|
||||
|
||||
private:
|
||||
std::vector<ScopeVisNG::TraceData> *m_tracesData;
|
||||
std::vector<float *> *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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
@ -465,7 +465,7 @@ kS/s</string>
|
||||
<widget class="QLabel" name="traceLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<width>24</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -971,7 +971,7 @@ kS/s</string>
|
||||
<widget class="QLabel" name="trigLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<width>24</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
|
Loading…
Reference in New Issue
Block a user