GLScope redesign: ScopeVis multiple I/Q streams support

This commit is contained in:
f4exb 2021-06-07 01:46:11 +02:00
parent e1a13841cf
commit 016ec01826
3 changed files with 121 additions and 70 deletions

View File

@ -50,6 +50,7 @@ ScopeVis::ScopeVis() :
m_focusedTriggerIndex(0), m_focusedTriggerIndex(0),
m_triggerState(TriggerUntriggered), m_triggerState(TriggerUntriggered),
m_focusedTraceIndex(0), m_focusedTraceIndex(0),
m_nbStreams(1),
m_traceChunkSize(GLScopeSettings::m_traceChunkDefaultSize), m_traceChunkSize(GLScopeSettings::m_traceChunkDefaultSize),
m_traceSize(GLScopeSettings::m_traceChunkDefaultSize), m_traceSize(GLScopeSettings::m_traceChunkDefaultSize),
m_liveTraceSize(GLScopeSettings::m_traceChunkDefaultSize), m_liveTraceSize(GLScopeSettings::m_traceChunkDefaultSize),
@ -129,9 +130,16 @@ void ScopeVis::setPreTriggerDelay(uint32_t preTriggerDelay, bool emitSignal)
} }
} }
void ScopeVis::configure(uint32_t traceSize, uint32_t timeBase, uint32_t timeOfsProMill, uint32_t triggerPre, bool freeRun) void ScopeVis::configure(
uint32_t nbStreams,
uint32_t traceSize,
uint32_t timeBase,
uint32_t timeOfsProMill,
uint32_t triggerPre,
bool freeRun
)
{ {
Message* cmd = MsgConfigureScopeVisNG::create(traceSize, timeBase, timeOfsProMill, triggerPre, freeRun); Message* cmd = MsgConfigureScopeVisNG::create(nbStreams, traceSize, timeBase, timeOfsProMill, triggerPre, freeRun);
getInputMessageQueue()->push(cmd); getInputMessageQueue()->push(cmd);
} }
@ -311,8 +319,8 @@ void ScopeVis::processMemoryTrace()
TraceBackDiscreteMemory::moveIt(mbegin, mbegin_tb, -m_maxTraceDelay); TraceBackDiscreteMemory::moveIt(mbegin, mbegin_tb, -m_maxTraceDelay);
m_nbSamples = m_traceSize + m_maxTraceDelay; m_nbSamples = m_traceSize + m_maxTraceDelay;
processTraces(mbegin_tb[0], m_maxTraceDelay, true); // traceback processTraces(mbegin_tb, m_maxTraceDelay, true); // traceback
processTraces(mbegin[0], m_traceSize, false); processTraces(mbegin, m_traceSize, false);
} }
} }
@ -454,24 +462,24 @@ void ScopeVis::processTrace(const std::vector<SampleVector::const_iterator>& vcb
{ // trace back { // trace back
std::vector<SampleVector::const_iterator> tbegin(mbegin.size()); std::vector<SampleVector::const_iterator> tbegin(mbegin.size());
TraceBackDiscreteMemory::moveIt(mbegin, tbegin, - m_preTriggerDelay - m_maxTraceDelay); TraceBackDiscreteMemory::moveIt(mbegin, tbegin, - m_preTriggerDelay - m_maxTraceDelay);
processTraces(tbegin[0] , m_maxTraceDelay, true); processTraces(tbegin, m_maxTraceDelay, true);
} }
if (m_preTriggerDelay > 0) if (m_preTriggerDelay > 0)
{ // pre-trigger { // pre-trigger
std::vector<SampleVector::const_iterator> tbegin(mbegin.size()); std::vector<SampleVector::const_iterator> tbegin(mbegin.size());
TraceBackDiscreteMemory::moveIt(mbegin, tbegin, -m_preTriggerDelay); TraceBackDiscreteMemory::moveIt(mbegin, tbegin, -m_preTriggerDelay);
processTraces(tbegin[0], m_preTriggerDelay); processTraces(tbegin, m_preTriggerDelay);
} }
// process the rest of the trace // process the rest of the trace
remainder = processTraces(mbegin[0], count); remainder = processTraces(mbegin, count);
m_traceStart = false; m_traceStart = false;
} }
else // process the current trace else // process the current trace
{ {
remainder = processTraces(mbegin[0], count); remainder = processTraces(mbegin, count);
} }
if (remainder >= 0) // finished if (remainder >= 0) // finished
@ -535,15 +543,15 @@ bool ScopeVis::nextTrigger()
} }
} }
int ScopeVis::processTraces(const SampleVector::const_iterator& cbegin, int ilength, bool traceBack) int ScopeVis::processTraces(const std::vector<SampleVector::const_iterator>& vcbegin, int ilength, bool traceBack)
{ {
SampleVector::const_iterator begin(cbegin); std::vector<SampleVector::const_iterator> vbegin(vcbegin);
uint32_t shift = (m_timeOfsProMill / 1000.0) * m_traceSize; uint32_t shift = (m_timeOfsProMill / 1000.0) * m_traceSize;
uint32_t length = m_traceSize / m_timeBase; uint32_t length = m_traceSize / m_timeBase;
int remainder = ilength; int remainder = ilength;
if (m_spectrumVis) { if (m_spectrumVis) {
m_spectrumVis->feed(cbegin, cbegin + ilength, false); m_spectrumVis->feed(vcbegin[0], vcbegin[0] + ilength, false); // TODO: use spectrum stream index
} }
while ((remainder > 0) && (m_nbSamples > 0)) while ((remainder > 0) && (m_nbSamples > 0))
@ -564,14 +572,15 @@ int ScopeVis::processTraces(const SampleVector::const_iterator& cbegin, int ilen
{ {
uint32_t& traceCount = (*itCtl)->m_traceCount[m_traces.currentBufferIndex()]; // reference for code clarity uint32_t& traceCount = (*itCtl)->m_traceCount[m_traces.currentBufferIndex()]; // reference for code clarity
float v; float v;
uint32_t streamIndex = itData->m_streamIndex;
if (projectionType == Projector::ProjectionMagLin) if (projectionType == Projector::ProjectionMagLin)
{ {
v = ((*itCtl)->m_projector.run(*begin) - itData->m_ofs)*itData->m_amp - 1.0f; v = ((*itCtl)->m_projector.run(*vbegin[streamIndex]) - itData->m_ofs)*itData->m_amp - 1.0f;
} }
else if (projectionType == Projector::ProjectionMagSq) else if (projectionType == Projector::ProjectionMagSq)
{ {
Real magsq = (*itCtl)->m_projector.run(*begin); Real magsq = (*itCtl)->m_projector.run(*vbegin[streamIndex]);
v = (magsq - itData->m_ofs)*itData->m_amp - 1.0f; v = (magsq - itData->m_ofs)*itData->m_amp - 1.0f;
if ((traceCount >= shift) && (traceCount < shift+length)) // power display overlay values construction if ((traceCount >= shift) && (traceCount < shift+length)) // power display overlay values construction
@ -604,8 +613,8 @@ int ScopeVis::processTraces(const SampleVector::const_iterator& cbegin, int ilen
} }
else if (projectionType == Projector::ProjectionMagDB) else if (projectionType == Projector::ProjectionMagDB)
{ {
Real re = begin->m_real / SDR_RX_SCALEF; Real re = vbegin[streamIndex]->m_real / SDR_RX_SCALEF;
Real im = begin->m_imag / SDR_RX_SCALEF; Real im = vbegin[streamIndex]->m_imag / SDR_RX_SCALEF;
double magsq = re*re + im*im; double magsq = re*re + im*im;
float pdB = log10f(magsq) * 10.0f; float pdB = log10f(magsq) * 10.0f;
float p = pdB - (100.0f * itData->m_ofs); float p = pdB - (100.0f * itData->m_ofs);
@ -643,7 +652,7 @@ int ScopeVis::processTraces(const SampleVector::const_iterator& cbegin, int ilen
} }
else else
{ {
v = ((*itCtl)->m_projector.run(*begin) - itData->m_ofs) * itData->m_amp; v = ((*itCtl)->m_projector.run(*vbegin[streamIndex]) - itData->m_ofs) * itData->m_amp;
} }
if(v > 1.0f) { if(v > 1.0f) {
@ -659,7 +668,9 @@ int ScopeVis::processTraces(const SampleVector::const_iterator& cbegin, int ilen
} }
} }
++begin; for (unsigned int i = 0; i < vbegin.size(); i++) {
++vbegin[i];
}
remainder--; remainder--;
m_nbSamples--; m_nbSamples--;
} }
@ -731,17 +742,23 @@ bool ScopeVis::handleMessage(const Message& message)
QMutexLocker configLocker(&m_mutex); QMutexLocker configLocker(&m_mutex);
MsgConfigureScopeVisNG& conf = (MsgConfigureScopeVisNG&) message; MsgConfigureScopeVisNG& conf = (MsgConfigureScopeVisNG&) message;
uint32_t nbStreams = conf.getNbStreams();
uint32_t traceSize = conf.getTraceSize(); uint32_t traceSize = conf.getTraceSize();
uint32_t timeBase = conf.getTimeBase(); uint32_t timeBase = conf.getTimeBase();
uint32_t timeOfsProMill = conf.getTimeOfsProMill(); uint32_t timeOfsProMill = conf.getTimeOfsProMill();
uint32_t triggerPre = conf.getTriggerPre(); uint32_t triggerPre = conf.getTriggerPre();
bool freeRun = conf.getFreeRun(); bool freeRun = conf.getFreeRun();
if (m_traceSize != traceSize) if (m_traceSize != traceSize) {
{
setTraceSize(traceSize); setTraceSize(traceSize);
} }
if (m_nbStreams != nbStreams)
{
m_traceDiscreteMemory.setNbStreams(nbStreams);
m_nbStreams = nbStreams;
}
if (m_timeBase != timeBase) if (m_timeBase != timeBase)
{ {
m_timeBase = timeBase; m_timeBase = timeBase;
@ -760,21 +777,20 @@ bool ScopeVis::handleMessage(const Message& message)
} }
} }
if (m_preTriggerDelay != triggerPre) if (m_preTriggerDelay != triggerPre) {
{
setPreTriggerDelay(triggerPre); setPreTriggerDelay(triggerPre);
} }
if (freeRun != m_freeRun) if (freeRun != m_freeRun) {
{
m_freeRun = freeRun; m_freeRun = freeRun;
} }
qDebug() << "ScopeVis::handleMessage: MsgConfigureScopeVisNG:" qDebug() << "ScopeVis::handleMessage: MsgConfigureScopeVisNG:"
<< " m_traceSize: " << m_traceSize << " m_nbStreams: " << m_nbStreams
<< " m_timeOfsProMill: " << m_timeOfsProMill << " m_traceSize: " << m_traceSize
<< " m_preTriggerDelay: " << m_preTriggerDelay << " m_timeOfsProMill: " << m_timeOfsProMill
<< " m_freeRun: " << m_freeRun; << " m_preTriggerDelay: " << m_preTriggerDelay
<< " m_freeRun: " << m_freeRun;
if ((m_glScope) && (m_currentTraceMemoryIndex > 0)) { if ((m_glScope) && (m_currentTraceMemoryIndex > 0)) {
processMemoryTrace(); processMemoryTrace();

View File

@ -54,7 +54,7 @@ public:
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
void setLiveRate(int sampleRate); void setLiveRate(int sampleRate);
void configure(uint32_t traceSize, uint32_t timeBase, uint32_t timeOfsProMill, uint32_t triggerPre, bool freeRun); void configure(uint32_t nbStreams, uint32_t traceSize, uint32_t timeBase, uint32_t timeOfsProMill, uint32_t triggerPre, bool freeRun);
void addTrace(const GLScopeSettings::TraceData& traceData); void addTrace(const GLScopeSettings::TraceData& traceData);
void changeTrace(const GLScopeSettings::TraceData& traceData, uint32_t traceIndex); void changeTrace(const GLScopeSettings::TraceData& traceData, uint32_t traceIndex);
void removeTrace(uint32_t traceIndex); void removeTrace(uint32_t traceIndex);
@ -152,15 +152,17 @@ private:
public: public:
static MsgConfigureScopeVisNG* create( static MsgConfigureScopeVisNG* create(
uint32_t nbStreams,
uint32_t traceSize, uint32_t traceSize,
uint32_t timeBase, uint32_t timeBase,
uint32_t timeOfsProMill, uint32_t timeOfsProMill,
uint32_t triggerPre, uint32_t triggerPre,
bool freeRun) bool freeRun)
{ {
return new MsgConfigureScopeVisNG(traceSize, timeBase, timeOfsProMill, triggerPre, freeRun); return new MsgConfigureScopeVisNG(nbStreams, traceSize, timeBase, timeOfsProMill, triggerPre, freeRun);
} }
uint32_t getNbStreams() const { return m_nbStreams; }
uint32_t getTraceSize() const { return m_traceSize; } uint32_t getTraceSize() const { return m_traceSize; }
uint32_t getTimeBase() const { return m_timeBase; } uint32_t getTimeBase() const { return m_timeBase; }
uint32_t getTimeOfsProMill() const { return m_timeOfsProMill; } uint32_t getTimeOfsProMill() const { return m_timeOfsProMill; }
@ -168,17 +170,22 @@ private:
bool getFreeRun() const { return m_freeRun; } bool getFreeRun() const { return m_freeRun; }
private: private:
uint32_t m_nbStreams;
uint32_t m_traceSize; uint32_t m_traceSize;
uint32_t m_timeBase; uint32_t m_timeBase;
uint32_t m_timeOfsProMill; uint32_t m_timeOfsProMill;
uint32_t m_triggerPre; uint32_t m_triggerPre;
bool m_freeRun; bool m_freeRun;
MsgConfigureScopeVisNG(uint32_t traceSize, MsgConfigureScopeVisNG(
uint32_t timeBase, uint32_t nbStreams,
uint32_t timeOfsProMill, uint32_t traceSize,
uint32_t triggerPre, uint32_t timeBase,
bool freeRun) : uint32_t timeOfsProMill,
uint32_t triggerPre,
bool freeRun
) :
m_nbStreams(nbStreams),
m_traceSize(traceSize), m_traceSize(traceSize),
m_timeBase(timeBase), m_timeBase(timeBase),
m_timeOfsProMill(timeOfsProMill), m_timeOfsProMill(timeOfsProMill),
@ -628,6 +635,12 @@ private:
} }
} }
void setNbStreams(uint32_t nbStreams)
{
m_traceBackBuffersStreams.resize(nbStreams);
resize(m_traceSize);
}
/** /**
* Resize all trace buffers in memory * Resize all trace buffers in memory
*/ */
@ -1178,6 +1191,7 @@ private:
TriggerState m_triggerState; //!< Current trigger state TriggerState m_triggerState; //!< Current trigger state
Traces m_traces; //!< Displayable traces Traces m_traces; //!< Displayable traces
int m_focusedTraceIndex; //!< Index of the trace that has focus int m_focusedTraceIndex; //!< Index of the trace that has focus
uint32_t m_nbStreams;
uint32_t m_traceChunkSize; //!< Trace length unit size in number of samples uint32_t m_traceChunkSize; //!< Trace length unit size in number of samples
uint32_t m_traceSize; //!< Size of traces in number of samples uint32_t m_traceSize; //!< Size of traces in number of samples
uint32_t m_liveTraceSize; //!< Size of traces in number of samples in live mode uint32_t m_liveTraceSize; //!< Size of traces in number of samples in live mode
@ -1220,7 +1234,7 @@ 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(const SampleVector::const_iterator& begin, int length, bool traceBack = false); int processTraces(const std::vector<SampleVector::const_iterator>& vbegin, int length, bool traceBack = false);
/** /**
* Get maximum trace delay * Get maximum trace delay

View File

@ -114,17 +114,23 @@ void GLScopeGUI::setBuddies(MessageQueue* messageQueue, ScopeVis* scopeVis, GLSc
ui->trigMode->clear(); ui->trigMode->clear();
fillProjectionCombo(ui->trigMode); fillProjectionCombo(ui->trigMode);
m_scopeVis->configure(2*m_traceLenMult*m_scopeVis->getTraceChunkSize(), m_scopeVis->configure(
m_timeBase, 1,
m_timeOffset*10, 2*m_traceLenMult*m_scopeVis->getTraceChunkSize(),
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)), m_timeBase,
ui->freerun->isChecked()); m_timeOffset*10,
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)),
ui->freerun->isChecked()
);
m_scopeVis->configure(m_traceLenMult*m_scopeVis->getTraceChunkSize(), m_scopeVis->configure(
m_timeBase, 1,
m_timeOffset*10, m_traceLenMult*m_scopeVis->getTraceChunkSize(),
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)), m_timeBase,
ui->freerun->isChecked()); m_timeOffset*10,
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)),
ui->freerun->isChecked()
);
setTraceLenDisplay(); setTraceLenDisplay();
setTimeScaleDisplay(); setTimeScaleDisplay();
@ -568,11 +574,14 @@ void GLScopeGUI::on_time_valueChanged(int value)
m_timeBase = value; m_timeBase = value;
setTimeScaleDisplay(); setTimeScaleDisplay();
setTraceDelayDisplay(); setTraceDelayDisplay();
m_scopeVis->configure(m_traceLenMult*m_scopeVis->getTraceChunkSize(), m_scopeVis->configure(
m_timeBase, 1,
m_timeOffset*10, m_traceLenMult*m_scopeVis->getTraceChunkSize(),
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)), m_timeBase,
ui->freerun->isChecked()); m_timeOffset*10,
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)),
ui->freerun->isChecked()
);
} }
void GLScopeGUI::on_timeOfs_valueChanged(int value) void GLScopeGUI::on_timeOfs_valueChanged(int value)
@ -583,11 +592,14 @@ void GLScopeGUI::on_timeOfs_valueChanged(int value)
m_timeOffset = value; m_timeOffset = value;
setTimeOfsDisplay(); setTimeOfsDisplay();
m_scopeVis->configure(m_traceLenMult*m_scopeVis->getTraceChunkSize(), m_scopeVis->configure(
m_timeBase, 1,
m_timeOffset*10, m_traceLenMult*m_scopeVis->getTraceChunkSize(),
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)), m_timeBase,
ui->freerun->isChecked()); m_timeOffset*10,
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)),
ui->freerun->isChecked()
);
if (value > 0) if (value > 0)
{ {
@ -603,11 +615,14 @@ void GLScopeGUI::on_traceLen_valueChanged(int value)
} }
m_traceLenMult = value; m_traceLenMult = value;
m_scopeVis->configure(m_traceLenMult*m_scopeVis->getTraceChunkSize(), m_scopeVis->configure(
m_timeBase, 1,
m_timeOffset*10, m_traceLenMult*m_scopeVis->getTraceChunkSize(),
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)), m_timeBase,
ui->freerun->isChecked()); m_timeOffset*10,
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)),
ui->freerun->isChecked()
);
setTraceLenDisplay(); setTraceLenDisplay();
setTimeScaleDisplay(); setTimeScaleDisplay();
setTimeOfsDisplay(); setTimeOfsDisplay();
@ -972,11 +987,14 @@ void GLScopeGUI::on_trigPre_valueChanged(int value)
{ {
(void) value; (void) value;
setTrigPreDisplay(); setTrigPreDisplay();
m_scopeVis->configure(m_traceLenMult*m_scopeVis->getTraceChunkSize(), m_scopeVis->configure(
m_timeBase, 1,
m_timeOffset*10, m_traceLenMult*m_scopeVis->getTraceChunkSize(),
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)), m_timeBase,
ui->freerun->isChecked()); m_timeOffset*10,
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)),
ui->freerun->isChecked()
);
} }
void GLScopeGUI::on_trigColor_clicked() void GLScopeGUI::on_trigColor_clicked()
@ -1010,11 +1028,14 @@ void GLScopeGUI::on_freerun_toggled(bool checked)
ui->trigOneShot->setEnabled(true); ui->trigOneShot->setEnabled(true);
} }
m_scopeVis->configure(m_traceLenMult*m_scopeVis->getTraceChunkSize(), m_scopeVis->configure(
m_timeBase, 1,
m_timeOffset*10, m_traceLenMult*m_scopeVis->getTraceChunkSize(),
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)), m_timeBase,
ui->freerun->isChecked()); m_timeOffset*10,
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)),
ui->freerun->isChecked()
);
} }
void GLScopeGUI::setTraceIndexDisplay() void GLScopeGUI::setTraceIndexDisplay()