2017-01-29 13:51:45 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Copyright (C) 2017 F4EXB //
|
|
|
|
// written by Edouard Griffiths //
|
|
|
|
// //
|
|
|
|
// This program is free software; you can redistribute it and/or modify //
|
|
|
|
// it under the terms of the GNU General Public License as published by //
|
|
|
|
// the Free Software Foundation as version 3 of the License, or //
|
|
|
|
// //
|
|
|
|
// This program is distributed in the hope that it will be useful, //
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
|
|
|
// GNU General Public License V3 for more details. //
|
|
|
|
// //
|
|
|
|
// You should have received a copy of the GNU General Public License //
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include <QDebug>
|
2017-02-12 21:23:29 -05:00
|
|
|
#include <QMutexLocker>
|
|
|
|
|
2018-08-12 11:22:39 -04:00
|
|
|
#include "scopevis.h"
|
2017-01-31 02:26:13 -05:00
|
|
|
#include "dsp/dspcommands.h"
|
2018-08-12 11:06:55 -04:00
|
|
|
#include "gui/glscope.h"
|
2017-01-29 13:51:45 -05:00
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgConfigureScopeVisNG, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGAddTrigger, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGChangeTrigger, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGRemoveTrigger, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGMoveTrigger, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGFocusOnTrigger, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGAddTrace, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGChangeTrace, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGRemoveTrace, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGMoveTrace, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGFocusOnTrace, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGOneShot, Message)
|
|
|
|
MESSAGE_CLASS_DEFINITION(ScopeVis::MsgScopeVisNGMemoryTrace, Message)
|
|
|
|
|
|
|
|
const uint ScopeVis::m_traceChunkSize = 4800;
|
|
|
|
|
|
|
|
|
|
|
|
ScopeVis::ScopeVis(GLScope* glScope) :
|
2017-01-29 13:51:45 -05:00
|
|
|
m_glScope(glScope),
|
2017-02-09 12:45:06 -05:00
|
|
|
m_preTriggerDelay(0),
|
|
|
|
m_currentTriggerIndex(0),
|
2017-02-13 05:30:40 -05:00
|
|
|
m_focusedTriggerIndex(0),
|
2017-02-09 12:45:06 -05:00
|
|
|
m_triggerState(TriggerUntriggered),
|
2017-02-12 19:32:02 -05:00
|
|
|
m_focusedTraceIndex(0),
|
2017-02-09 12:45:06 -05:00
|
|
|
m_traceSize(m_traceChunkSize),
|
2018-10-15 23:10:35 -04:00
|
|
|
m_liveTraceSize(m_traceChunkSize),
|
2017-02-09 12:45:06 -05:00
|
|
|
m_nbSamples(0),
|
2017-05-25 14:13:34 -04:00
|
|
|
m_timeBase(1),
|
|
|
|
m_timeOfsProMill(0),
|
2017-02-09 12:45:06 -05:00
|
|
|
m_traceStart(true),
|
|
|
|
m_sampleRate(0),
|
2018-10-15 23:10:35 -04:00
|
|
|
m_liveSampleRate(0),
|
2017-02-23 02:18:03 -05:00
|
|
|
m_traceDiscreteMemory(m_nbTraceMemories),
|
2017-02-09 12:45:06 -05:00
|
|
|
m_freeRun(true),
|
2017-02-21 19:18:50 -05:00
|
|
|
m_maxTraceDelay(0),
|
|
|
|
m_triggerOneShot(false),
|
2017-02-24 02:31:25 -05:00
|
|
|
m_triggerWaitForReset(false),
|
|
|
|
m_currentTraceMemoryIndex(0)
|
2017-01-29 13:51:45 -05:00
|
|
|
{
|
2018-08-12 11:18:58 -04:00
|
|
|
setObjectName("ScopeVis");
|
2017-02-01 12:31:16 -05:00
|
|
|
m_traceDiscreteMemory.resize(m_traceChunkSize); // arbitrary
|
2017-02-05 20:40:31 -05:00
|
|
|
m_glScope->setTraces(&m_traces.m_tracesData, &m_traces.m_traces[0]);
|
2018-04-03 12:51:21 -04:00
|
|
|
for (int i = 0; i < (int) Projector::nbProjectionTypes; i++) {
|
2018-02-24 04:29:27 -05:00
|
|
|
m_projectorCache[i] = 0.0;
|
|
|
|
}
|
2017-01-29 13:51:45 -05:00
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
ScopeVis::~ScopeVis()
|
2017-01-29 13:51:45 -05:00
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
for (std::vector<TriggerCondition*>::iterator it = m_triggerConditions.begin(); it != m_triggerConditions.end(); ++ it) {
|
|
|
|
delete *it;
|
|
|
|
}
|
2017-01-29 13:51:45 -05:00
|
|
|
}
|
|
|
|
|
2018-10-15 18:31:45 -04:00
|
|
|
void ScopeVis::setLiveRate(int sampleRate)
|
|
|
|
{
|
2018-10-15 23:10:35 -04:00
|
|
|
m_liveSampleRate = sampleRate;
|
2018-10-15 18:31:45 -04:00
|
|
|
|
|
|
|
if (m_currentTraceMemoryIndex == 0) { // update only in live mode
|
2018-10-15 23:10:35 -04:00
|
|
|
setSampleRate(m_liveSampleRate);
|
2018-10-15 18:31:45 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::setSampleRate(int sampleRate)
|
2017-01-29 16:52:38 -05:00
|
|
|
{
|
2018-10-15 18:08:33 -04:00
|
|
|
m_sampleRate = sampleRate;
|
|
|
|
|
|
|
|
if (m_glScope) {
|
|
|
|
m_glScope->setSampleRate(m_sampleRate);
|
2017-01-29 16:52:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 23:10:35 -04:00
|
|
|
void ScopeVis::setTraceSize(uint32_t traceSize)
|
|
|
|
{
|
|
|
|
m_traceSize = traceSize;
|
|
|
|
m_traces.resize(m_traceSize);
|
|
|
|
m_traceDiscreteMemory.resize(m_traceSize);
|
|
|
|
initTraceBuffers();
|
|
|
|
|
|
|
|
if (m_glScope) {
|
|
|
|
m_glScope->setTraceSize(m_traceSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::configure(uint32_t traceSize, uint32_t timeBase, uint32_t timeOfsProMill, uint32_t triggerPre, bool freeRun)
|
2017-01-29 13:51:45 -05:00
|
|
|
{
|
2017-02-25 22:55:15 -05:00
|
|
|
Message* cmd = MsgConfigureScopeVisNG::create(traceSize, timeBase, timeOfsProMill, triggerPre, freeRun);
|
2017-01-29 18:36:27 -05:00
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::addTrace(const TraceData& traceData)
|
2017-01-29 18:36:27 -05:00
|
|
|
{
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::addTrace:"
|
2017-02-20 16:19:50 -05:00
|
|
|
<< " m_amp: " << traceData.m_amp
|
|
|
|
<< " m_ofs: " << traceData.m_ofs
|
|
|
|
<< " m_traceDelay: " << traceData.m_traceDelay;
|
2017-01-29 18:36:27 -05:00
|
|
|
Message* cmd = MsgScopeVisNGAddTrace::create(traceData);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::changeTrace(const TraceData& traceData, uint32_t traceIndex)
|
2017-01-29 18:36:27 -05:00
|
|
|
{
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::changeTrace:"
|
2017-02-07 20:13:53 -05:00
|
|
|
<< " trace: " << traceIndex
|
|
|
|
<< " m_amp: " << traceData.m_amp
|
2017-02-16 19:54:55 -05:00
|
|
|
<< " m_ofs: " << traceData.m_ofs
|
|
|
|
<< " m_traceDelay: " << traceData.m_traceDelay;
|
2017-01-29 18:36:27 -05:00
|
|
|
Message* cmd = MsgScopeVisNGChangeTrace::create(traceData, traceIndex);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::removeTrace(uint32_t traceIndex)
|
2017-01-29 18:36:27 -05:00
|
|
|
{
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::removeTrace:"
|
2017-02-20 16:19:50 -05:00
|
|
|
<< " trace: " << traceIndex;
|
2017-01-29 18:36:27 -05:00
|
|
|
Message* cmd = MsgScopeVisNGRemoveTrace::create(traceIndex);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::moveTrace(uint32_t traceIndex, bool upElseDown)
|
2017-02-26 05:26:23 -05:00
|
|
|
{
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::moveTrace:"
|
2017-02-26 05:26:23 -05:00
|
|
|
<< " trace: " << traceIndex
|
|
|
|
<< " up: " << upElseDown;
|
|
|
|
Message* cmd = MsgScopeVisNGMoveTrace::create(traceIndex, upElseDown);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::focusOnTrace(uint32_t traceIndex)
|
2017-02-12 19:32:02 -05:00
|
|
|
{
|
|
|
|
Message* cmd = MsgScopeVisNGFocusOnTrace::create(traceIndex);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::addTrigger(const TriggerData& triggerData)
|
2017-01-29 18:36:27 -05:00
|
|
|
{
|
|
|
|
Message* cmd = MsgScopeVisNGAddTrigger::create(triggerData);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::changeTrigger(const TriggerData& triggerData, uint32_t triggerIndex)
|
2017-01-29 18:36:27 -05:00
|
|
|
{
|
|
|
|
Message* cmd = MsgScopeVisNGChangeTrigger::create(triggerData, triggerIndex);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::removeTrigger(uint32_t triggerIndex)
|
2017-01-29 18:36:27 -05:00
|
|
|
{
|
|
|
|
Message* cmd = MsgScopeVisNGRemoveTrigger::create(triggerIndex);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
2017-01-29 13:51:45 -05:00
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::moveTrigger(uint32_t triggerIndex, bool upElseDown)
|
2017-02-26 05:26:23 -05:00
|
|
|
{
|
|
|
|
Message* cmd = MsgScopeVisNGMoveTrigger::create(triggerIndex, upElseDown);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::focusOnTrigger(uint32_t triggerIndex)
|
2017-02-11 04:36:10 -05:00
|
|
|
{
|
|
|
|
Message* cmd = MsgScopeVisNGFocusOnTrigger::create(triggerIndex);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::setOneShot(bool oneShot)
|
2017-02-21 19:18:50 -05:00
|
|
|
{
|
|
|
|
Message* cmd = MsgScopeVisNGOneShot::create(oneShot);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
2017-01-29 13:51:45 -05:00
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::setMemoryIndex(uint32_t memoryIndex)
|
2017-02-23 02:18:03 -05:00
|
|
|
{
|
|
|
|
Message* cmd = MsgScopeVisNGMemoryTrace::create(memoryIndex);
|
|
|
|
getInputMessageQueue()->push(cmd);
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::feed(const SampleVector::const_iterator& cbegin, const SampleVector::const_iterator& end, bool positiveOnly __attribute__((unused)))
|
2017-01-29 13:51:45 -05:00
|
|
|
{
|
2017-02-05 20:40:31 -05:00
|
|
|
if (m_freeRun) {
|
2017-01-29 13:51:45 -05:00
|
|
|
m_triggerPoint = cbegin;
|
|
|
|
}
|
|
|
|
else if (m_triggerState == TriggerTriggered) {
|
|
|
|
m_triggerPoint = cbegin;
|
|
|
|
}
|
|
|
|
else if (m_triggerState == TriggerUntriggered) {
|
|
|
|
m_triggerPoint = end;
|
|
|
|
}
|
2017-02-24 02:31:25 -05:00
|
|
|
else if ((m_triggerWaitForReset) || (m_currentTraceMemoryIndex > 0)) {
|
2017-01-29 13:51:45 -05:00
|
|
|
m_triggerPoint = end;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_triggerPoint = cbegin;
|
|
|
|
}
|
|
|
|
|
2017-02-24 02:31:25 -05:00
|
|
|
if ((m_triggerWaitForReset) || (m_currentTraceMemoryIndex > 0)) {
|
2017-02-09 12:45:06 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-02-13 05:30:40 -05:00
|
|
|
if(!m_mutex.tryLock(2)) // prevent conflicts with configuration process
|
2017-02-12 21:23:29 -05:00
|
|
|
return;
|
|
|
|
|
2017-02-09 12:45:06 -05:00
|
|
|
SampleVector::const_iterator begin(cbegin);
|
|
|
|
int triggerPointToEnd;
|
|
|
|
|
|
|
|
while (begin < end)
|
|
|
|
{
|
|
|
|
if (begin + m_traceSize > end)
|
|
|
|
{
|
|
|
|
triggerPointToEnd = -1;
|
|
|
|
processTrace(begin, end, triggerPointToEnd);
|
|
|
|
if (triggerPointToEnd >= 0) {
|
|
|
|
m_triggerPoint = end - triggerPointToEnd;
|
|
|
|
}
|
|
|
|
begin = end;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-02-08 20:16:43 -05:00
|
|
|
triggerPointToEnd = -1;
|
2017-02-09 12:45:06 -05:00
|
|
|
processTrace(begin, begin + m_traceSize, triggerPointToEnd);
|
2017-02-08 20:16:43 -05:00
|
|
|
if (triggerPointToEnd >= 0) {
|
|
|
|
m_triggerPoint = begin + m_traceSize -triggerPointToEnd;
|
2017-02-08 19:58:54 -05:00
|
|
|
}
|
2017-02-09 12:45:06 -05:00
|
|
|
begin += m_traceSize;
|
|
|
|
}
|
|
|
|
}
|
2017-02-12 21:23:29 -05:00
|
|
|
|
|
|
|
m_mutex.unlock();
|
2017-02-08 16:22:27 -05:00
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::processMemoryTrace()
|
2017-02-24 02:31:25 -05:00
|
|
|
{
|
|
|
|
if ((m_currentTraceMemoryIndex > 0) && (m_currentTraceMemoryIndex < m_nbTraceMemories))
|
|
|
|
{
|
2018-10-01 23:18:34 -04:00
|
|
|
int traceMemoryIndex = m_traceDiscreteMemory.currentIndex() - m_currentTraceMemoryIndex; // actual index in memory bank
|
|
|
|
|
|
|
|
if (traceMemoryIndex < 0) {
|
|
|
|
traceMemoryIndex += m_nbTraceMemories;
|
|
|
|
}
|
|
|
|
|
|
|
|
SampleVector::const_iterator mend = m_traceDiscreteMemory.at(traceMemoryIndex).m_endPoint;
|
2017-02-24 02:31:25 -05:00
|
|
|
SampleVector::const_iterator mbegin = mend - m_traceSize;
|
|
|
|
SampleVector::const_iterator mbegin_tb = mbegin - m_maxTraceDelay;
|
2017-02-24 17:24:47 -05:00
|
|
|
m_nbSamples = m_traceSize + m_maxTraceDelay;
|
2017-02-24 02:31:25 -05:00
|
|
|
|
|
|
|
processTraces(mbegin_tb, mbegin, true); // traceback
|
|
|
|
processTraces(mbegin, mend, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::processTrace(const SampleVector::const_iterator& cbegin, const SampleVector::const_iterator& end, int& triggerPointToEnd)
|
2017-02-08 16:22:27 -05:00
|
|
|
{
|
2017-02-09 12:45:06 -05:00
|
|
|
SampleVector::const_iterator begin(cbegin);
|
2017-02-08 16:22:27 -05:00
|
|
|
|
2017-02-09 12:45:06 -05:00
|
|
|
// memory storage
|
2017-02-01 12:31:16 -05:00
|
|
|
|
2017-02-02 02:27:49 -05:00
|
|
|
m_traceDiscreteMemory.current().write(cbegin, end);
|
2017-02-01 12:31:16 -05:00
|
|
|
|
2017-02-02 02:27:49 -05:00
|
|
|
if (m_traceDiscreteMemory.current().absoluteFill() < m_traceSize)
|
|
|
|
{
|
|
|
|
return; // not enough samples in memory
|
|
|
|
}
|
2017-01-29 13:51:45 -05:00
|
|
|
|
2017-02-05 20:40:31 -05:00
|
|
|
// trigger process
|
2017-02-01 12:31:16 -05:00
|
|
|
|
2017-02-08 18:00:21 -05:00
|
|
|
if ((m_freeRun) || (m_triggerConditions.size() == 0)) // immediate re-trigger
|
|
|
|
{
|
2017-02-08 19:58:54 -05:00
|
|
|
if (m_triggerState == TriggerUntriggered)
|
|
|
|
{
|
|
|
|
m_traceStart = true; // start trace processing
|
|
|
|
m_nbSamples = m_traceSize + m_maxTraceDelay;
|
|
|
|
m_triggerState = TriggerTriggered;
|
|
|
|
}
|
2017-02-08 18:00:21 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((m_triggerState == TriggerUntriggered) || (m_triggerState == TriggerDelay))
|
2017-01-29 13:51:45 -05:00
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
TriggerCondition* triggerCondition = m_triggerConditions[m_currentTriggerIndex]; // current trigger condition
|
2017-02-08 18:00:21 -05:00
|
|
|
|
|
|
|
while (begin < end)
|
2017-02-07 20:13:53 -05:00
|
|
|
{
|
2017-02-09 12:45:06 -05:00
|
|
|
if (m_triggerState == TriggerDelay)
|
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
if (triggerCondition->m_triggerDelayCount > 0) // skip samples during delay period
|
2017-02-09 12:45:06 -05:00
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
triggerCondition->m_triggerDelayCount--;
|
2017-02-09 12:45:06 -05:00
|
|
|
++begin;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else // process trigger
|
|
|
|
{
|
|
|
|
if (nextTrigger()) // move to next trigger and keep going
|
|
|
|
{
|
|
|
|
m_triggerComparator.reset();
|
|
|
|
m_triggerState = TriggerUntriggered;
|
|
|
|
++begin;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else // this was the last trigger then start trace
|
|
|
|
{
|
|
|
|
m_traceStart = true; // start trace processing
|
|
|
|
m_nbSamples = m_traceSize + m_maxTraceDelay;
|
|
|
|
m_triggerComparator.reset();
|
|
|
|
m_triggerState = TriggerTriggered;
|
|
|
|
triggerPointToEnd = end - begin;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-08 18:00:21 -05:00
|
|
|
// look for trigger
|
2018-04-03 17:19:35 -04:00
|
|
|
if (m_triggerComparator.triggered(*begin, *triggerCondition))
|
2017-02-08 18:00:21 -05:00
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
if (triggerCondition->m_triggerData.m_triggerDelay > 0)
|
2017-02-09 12:45:06 -05:00
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
triggerCondition->m_triggerDelayCount = triggerCondition->m_triggerData.m_triggerDelay; // initialize delayed samples counter
|
2017-02-09 12:45:06 -05:00
|
|
|
m_triggerState = TriggerDelay;
|
|
|
|
++begin;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nextTrigger()) // move to next trigger and keep going
|
|
|
|
{
|
|
|
|
m_triggerComparator.reset();
|
|
|
|
m_triggerState = TriggerUntriggered;
|
|
|
|
}
|
|
|
|
else // this was the last trigger then start trace
|
|
|
|
{
|
|
|
|
m_traceStart = true; // start trace processing
|
|
|
|
m_nbSamples = m_traceSize + m_maxTraceDelay;
|
|
|
|
m_triggerComparator.reset();
|
|
|
|
m_triggerState = TriggerTriggered;
|
|
|
|
triggerPointToEnd = end - begin;
|
|
|
|
break;
|
|
|
|
}
|
2017-02-08 18:00:21 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
++begin;
|
2017-02-07 20:13:53 -05:00
|
|
|
}
|
|
|
|
}
|
2017-02-08 18:00:21 -05:00
|
|
|
}
|
2017-01-29 13:51:45 -05:00
|
|
|
|
2017-02-09 12:45:06 -05:00
|
|
|
// trace process
|
2017-02-12 18:17:59 -05:00
|
|
|
if (m_glScope->getDataChanged()) // optimization: process trace only if required by glScope
|
|
|
|
{
|
|
|
|
m_triggerState = TriggerUntriggered;
|
|
|
|
}
|
|
|
|
|
2017-02-09 12:45:06 -05:00
|
|
|
if (m_triggerState == TriggerTriggered)
|
|
|
|
{
|
|
|
|
int remainder = -1;
|
|
|
|
int count = end - begin; // number of samples in traceback buffer past the current point
|
|
|
|
SampleVector::iterator mend = m_traceDiscreteMemory.current().current();
|
|
|
|
SampleVector::iterator mbegin = mend - count;
|
|
|
|
|
|
|
|
if (m_traceStart)
|
|
|
|
{
|
|
|
|
// trace back
|
|
|
|
if (m_maxTraceDelay > 0)
|
|
|
|
{
|
|
|
|
processTraces(mbegin - m_preTriggerDelay - m_maxTraceDelay, mbegin - m_preTriggerDelay, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// pre-trigger
|
|
|
|
if (m_preTriggerDelay > 0)
|
|
|
|
{
|
|
|
|
remainder = processTraces(mbegin - m_preTriggerDelay, mbegin);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_traceStart = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (remainder < 0)
|
2017-02-02 02:27:49 -05:00
|
|
|
{
|
2017-02-09 12:45:06 -05:00
|
|
|
// live trace
|
2017-02-08 18:11:10 -05:00
|
|
|
remainder = processTraces(mbegin, mend);
|
2017-02-02 02:27:49 -05:00
|
|
|
}
|
2017-02-01 12:31:16 -05:00
|
|
|
|
2017-02-09 12:45:06 -05:00
|
|
|
if (remainder >= 0) // finished
|
|
|
|
{
|
|
|
|
mbegin = mend - remainder;
|
|
|
|
m_traceDiscreteMemory.current().m_endPoint = mbegin;
|
|
|
|
m_traceDiscreteMemory.store(); // next memory trace
|
2017-02-07 01:45:42 -05:00
|
|
|
m_triggerState = TriggerUntriggered;
|
2017-02-21 19:18:50 -05:00
|
|
|
m_triggerWaitForReset = m_triggerOneShot;
|
|
|
|
|
2017-02-12 18:17:59 -05:00
|
|
|
//if (m_glScope) m_glScope->incrementTraceCounter();
|
2017-01-29 13:51:45 -05:00
|
|
|
|
2017-02-08 18:04:19 -05:00
|
|
|
// process remainder recursively
|
|
|
|
if (remainder != 0)
|
|
|
|
{
|
2017-02-08 20:16:43 -05:00
|
|
|
int mTriggerPointToEnd = -1;
|
2017-02-08 19:58:54 -05:00
|
|
|
|
2017-02-08 20:16:43 -05:00
|
|
|
processTrace(mbegin, mend, mTriggerPointToEnd);
|
2017-02-08 19:58:54 -05:00
|
|
|
|
2017-02-08 20:16:43 -05:00
|
|
|
if (mTriggerPointToEnd >= 0) {
|
|
|
|
triggerPointToEnd = mTriggerPointToEnd;
|
2017-02-08 19:58:54 -05:00
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
//qDebug("ScopeVis::processTrace: process remainder recursively (%d %d)", mpoint, mTriggerPoint);
|
2017-02-08 18:04:19 -05:00
|
|
|
}
|
2017-02-09 12:45:06 -05:00
|
|
|
}
|
|
|
|
}
|
2017-01-29 13:51:45 -05:00
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
bool ScopeVis::nextTrigger()
|
2017-02-01 12:31:16 -05:00
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
TriggerCondition *triggerCondition = m_triggerConditions[m_currentTriggerIndex]; // current trigger condition
|
2017-02-09 12:45:06 -05:00
|
|
|
|
2018-04-03 17:19:35 -04:00
|
|
|
if (triggerCondition->m_triggerData.m_triggerRepeat > 0)
|
2017-02-09 12:45:06 -05:00
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
if (triggerCondition->m_triggerCounter < triggerCondition->m_triggerData.m_triggerRepeat)
|
2017-02-09 12:45:06 -05:00
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
triggerCondition->m_triggerCounter++;
|
2017-02-09 12:45:06 -05:00
|
|
|
return true; // not final keep going
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
triggerCondition->m_triggerCounter = 0; // reset for next time
|
2017-02-09 12:45:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-25 14:13:34 -04:00
|
|
|
if (m_triggerConditions.size() == 0)
|
|
|
|
{
|
|
|
|
m_currentTriggerIndex = 0;
|
|
|
|
return false; // final
|
|
|
|
}
|
|
|
|
else if (m_currentTriggerIndex < m_triggerConditions.size() - 1) // check if next trigger is available
|
2017-02-09 12:45:06 -05:00
|
|
|
{
|
|
|
|
m_currentTriggerIndex++;
|
|
|
|
return true; // not final keep going
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// now this is really finished
|
|
|
|
m_currentTriggerIndex = 0;
|
|
|
|
return false; // final
|
|
|
|
}
|
2017-02-01 12:31:16 -05:00
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
int ScopeVis::processTraces(const SampleVector::const_iterator& cbegin, const SampleVector::const_iterator& end, bool traceBack)
|
2017-01-29 13:51:45 -05:00
|
|
|
{
|
2017-02-08 18:11:10 -05:00
|
|
|
SampleVector::const_iterator begin(cbegin);
|
2017-05-25 14:13:34 -04:00
|
|
|
uint32_t shift = (m_timeOfsProMill / 1000.0) * m_traceSize;
|
|
|
|
uint32_t length = m_traceSize / m_timeBase;
|
2017-01-29 13:51:45 -05:00
|
|
|
|
2017-02-08 19:58:54 -05:00
|
|
|
while ((begin < end) && (m_nbSamples > 0))
|
2017-01-29 13:51:45 -05:00
|
|
|
{
|
2018-04-03 16:29:09 -04:00
|
|
|
std::vector<TraceControl*>::iterator itCtl = m_traces.m_tracesControl.begin();
|
2017-02-05 20:40:31 -05:00
|
|
|
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)
|
2017-02-02 02:27:49 -05:00
|
|
|
{
|
2017-02-08 19:58:54 -05:00
|
|
|
if (traceBack && ((end - begin) > itData->m_traceDelay)) { // before start of trace
|
2017-02-02 02:27:49 -05:00
|
|
|
continue;
|
|
|
|
}
|
2017-01-29 13:51:45 -05:00
|
|
|
|
2018-04-03 12:51:21 -04:00
|
|
|
Projector::ProjectionType projectionType = itData->m_projectionType;
|
2017-02-25 22:46:02 -05:00
|
|
|
|
2018-04-03 16:29:09 -04:00
|
|
|
if ((*itCtl)->m_traceCount[m_traces.currentBufferIndex()] < m_traceSize)
|
2017-02-02 02:27:49 -05:00
|
|
|
{
|
2018-04-03 16:29:09 -04:00
|
|
|
uint32_t& traceCount = (*itCtl)->m_traceCount[m_traces.currentBufferIndex()]; // reference for code clarity
|
2017-02-06 18:25:40 -05:00
|
|
|
float v;
|
|
|
|
|
2018-04-03 12:51:21 -04:00
|
|
|
if (projectionType == Projector::ProjectionMagLin)
|
2017-02-25 22:46:02 -05:00
|
|
|
{
|
2018-04-03 16:29:09 -04:00
|
|
|
v = ((*itCtl)->m_projector.run(*begin) - itData->m_ofs)*itData->m_amp - 1.0f;
|
2017-02-25 22:46:02 -05:00
|
|
|
}
|
2018-06-25 18:43:19 -04:00
|
|
|
else if (projectionType == Projector::ProjectionMagSq)
|
|
|
|
{
|
2018-06-25 19:06:45 -04:00
|
|
|
Real magsq = (*itCtl)->m_projector.run(*begin);
|
|
|
|
v = (magsq - itData->m_ofs)*itData->m_amp - 1.0f;
|
|
|
|
|
|
|
|
if ((traceCount >= shift) && (traceCount < shift+length)) // power display overlay values construction
|
|
|
|
{
|
|
|
|
if (traceCount == shift)
|
|
|
|
{
|
|
|
|
(*itCtl)->m_maxPow = 0.0f;
|
|
|
|
(*itCtl)->m_sumPow = 0.0f;
|
|
|
|
(*itCtl)->m_nbPow = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (magsq > 0.0f)
|
|
|
|
{
|
|
|
|
if (magsq > (*itCtl)->m_maxPow)
|
|
|
|
{
|
|
|
|
(*itCtl)->m_maxPow = magsq;
|
|
|
|
}
|
|
|
|
|
|
|
|
(*itCtl)->m_sumPow += magsq;
|
|
|
|
(*itCtl)->m_nbPow++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((m_nbSamples == 1) && ((*itCtl)->m_nbPow > 0)) // on last sample create power display overlay
|
|
|
|
{
|
|
|
|
double avgPow = (*itCtl)->m_sumPow / (*itCtl)->m_nbPow;
|
|
|
|
itData->m_textOverlay = QString("%1 %2").arg((*itCtl)->m_maxPow, 0, 'e', 2).arg(avgPow, 0, 'e', 2);
|
|
|
|
(*itCtl)->m_nbPow = 0;
|
|
|
|
}
|
2018-06-25 18:43:19 -04:00
|
|
|
}
|
2018-04-03 12:51:21 -04:00
|
|
|
else if (projectionType == Projector::ProjectionMagDB)
|
2017-02-25 22:46:02 -05:00
|
|
|
{
|
2018-06-25 17:44:11 -04:00
|
|
|
Real re = begin->m_real / SDR_RX_SCALEF;
|
|
|
|
Real im = begin->m_imag / SDR_RX_SCALEF;
|
|
|
|
double magsq = re*re + im*im;
|
|
|
|
float pdB = log10f(magsq) * 10.0f;
|
2017-02-25 22:46:02 -05:00
|
|
|
float p = pdB - (100.0f * itData->m_ofs);
|
2017-02-07 20:13:53 -05:00
|
|
|
v = ((p/50.0f) + 2.0f)*itData->m_amp - 1.0f;
|
2017-02-25 22:46:02 -05:00
|
|
|
|
2017-02-25 23:26:42 -05:00
|
|
|
if ((traceCount >= shift) && (traceCount < shift+length)) // power display overlay values construction
|
2017-02-25 22:46:02 -05:00
|
|
|
{
|
2017-02-25 23:26:42 -05:00
|
|
|
if (traceCount == shift)
|
2017-02-25 22:46:02 -05:00
|
|
|
{
|
2018-06-25 17:44:11 -04:00
|
|
|
(*itCtl)->m_maxPow = 0.0f;
|
2018-04-03 16:29:09 -04:00
|
|
|
(*itCtl)->m_sumPow = 0.0f;
|
|
|
|
(*itCtl)->m_nbPow = 1;
|
2017-02-25 22:46:02 -05:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:44:11 -04:00
|
|
|
if (magsq > 0.0f)
|
2017-02-25 23:26:42 -05:00
|
|
|
{
|
2018-06-25 17:44:11 -04:00
|
|
|
if (magsq > (*itCtl)->m_maxPow)
|
2017-02-25 23:26:42 -05:00
|
|
|
{
|
2018-06-25 17:44:11 -04:00
|
|
|
(*itCtl)->m_maxPow = magsq;
|
2017-02-25 23:26:42 -05:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:44:11 -04:00
|
|
|
(*itCtl)->m_sumPow += magsq;
|
2018-04-03 16:29:09 -04:00
|
|
|
(*itCtl)->m_nbPow++;
|
2017-02-25 23:26:42 -05:00
|
|
|
}
|
2017-02-25 22:46:02 -05:00
|
|
|
}
|
|
|
|
|
2018-04-03 16:29:09 -04:00
|
|
|
if ((m_nbSamples == 1) && ((*itCtl)->m_nbPow > 0)) // on last sample create power display overlay
|
2017-02-25 22:46:02 -05:00
|
|
|
{
|
2018-06-25 17:44:11 -04:00
|
|
|
double avgPow = log10f((*itCtl)->m_sumPow / (*itCtl)->m_nbPow)*10.0;
|
|
|
|
double peakPow = log10f((*itCtl)->m_maxPow)*10.0;
|
|
|
|
double peakToAvgPow = peakPow - avgPow;
|
|
|
|
itData->m_textOverlay = QString("%1 %2 %3").arg(peakPow, 0, 'f', 1).arg(avgPow, 0, 'f', 1).arg(peakToAvgPow, 4, 'f', 1, ' ');
|
2018-04-03 16:29:09 -04:00
|
|
|
(*itCtl)->m_nbPow = 0;
|
2017-02-25 22:46:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-03 16:29:09 -04:00
|
|
|
v = ((*itCtl)->m_projector.run(*begin) - itData->m_ofs) * itData->m_amp;
|
2017-02-06 18:25:40 -05:00
|
|
|
}
|
2017-02-02 02:27:49 -05:00
|
|
|
|
2017-02-07 20:13:53 -05:00
|
|
|
if(v > 1.0f) {
|
|
|
|
v = 1.0f;
|
|
|
|
} else if (v < -1.0f) {
|
|
|
|
v = -1.0f;
|
2017-02-02 02:27:49 -05:00
|
|
|
}
|
|
|
|
|
2017-02-25 23:13:21 -05:00
|
|
|
(*itTrace)[2*traceCount]
|
|
|
|
= traceCount - shift; // display x
|
|
|
|
(*itTrace)[2*traceCount + 1] = v; // display y
|
|
|
|
traceCount++;
|
2017-02-02 02:27:49 -05:00
|
|
|
}
|
|
|
|
}
|
2017-01-29 13:51:45 -05:00
|
|
|
|
2017-02-05 20:40:31 -05:00
|
|
|
++begin;
|
2017-02-08 19:58:54 -05:00
|
|
|
m_nbSamples--;
|
2017-01-29 13:51:45 -05:00
|
|
|
}
|
2017-02-02 02:27:49 -05:00
|
|
|
|
2017-02-08 19:58:54 -05:00
|
|
|
if (m_nbSamples == 0) // finished
|
2017-02-02 02:27:49 -05:00
|
|
|
{
|
2018-08-12 11:18:58 -04:00
|
|
|
//sqDebug("ScopeVis::processTraces: m_traceCount: %d", m_traces.m_tracesControl.begin()->m_traceCount[m_traces.currentBufferIndex()]);
|
2017-02-05 20:40:31 -05:00
|
|
|
m_glScope->newTraces(&m_traces.m_traces[m_traces.currentBufferIndex()]);
|
|
|
|
m_traces.switchBuffer();
|
2017-02-02 02:27:49 -05:00
|
|
|
return end - begin; // return remainder count
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return -1; // mark not finished
|
|
|
|
}
|
2017-02-04 22:41:32 -05:00
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::start()
|
2017-01-29 13:51:45 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::stop()
|
2017-01-29 13:51:45 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
bool ScopeVis::handleMessage(const Message& message)
|
2017-01-29 13:51:45 -05:00
|
|
|
{
|
2017-01-31 02:26:13 -05:00
|
|
|
if (DSPSignalNotification::match(message))
|
|
|
|
{
|
|
|
|
DSPSignalNotification& notif = (DSPSignalNotification&) message;
|
2018-10-15 18:31:45 -04:00
|
|
|
setLiveRate(notif.getSampleRate());
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: DSPSignalNotification: m_sampleRate: " << m_sampleRate;
|
2017-01-31 02:26:13 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (MsgConfigureScopeVisNG::match(message))
|
|
|
|
{
|
2017-02-12 21:23:29 -05:00
|
|
|
QMutexLocker configLocker(&m_mutex);
|
2017-01-31 02:26:13 -05:00
|
|
|
MsgConfigureScopeVisNG& conf = (MsgConfigureScopeVisNG&) message;
|
|
|
|
|
2017-02-04 22:41:32 -05:00
|
|
|
uint32_t traceSize = conf.getTraceSize();
|
2017-02-25 22:55:15 -05:00
|
|
|
uint32_t timeBase = conf.getTimeBase();
|
2017-02-04 22:41:32 -05:00
|
|
|
uint32_t timeOfsProMill = conf.getTimeOfsProMill();
|
2017-02-07 12:50:08 -05:00
|
|
|
uint32_t triggerPre = conf.getTriggerPre();
|
2017-02-05 20:40:31 -05:00
|
|
|
bool freeRun = conf.getFreeRun();
|
2017-02-04 22:41:32 -05:00
|
|
|
|
|
|
|
if (m_traceSize != traceSize)
|
|
|
|
{
|
2018-10-15 23:10:35 -04:00
|
|
|
setTraceSize(traceSize);
|
2017-02-04 22:41:32 -05:00
|
|
|
}
|
|
|
|
|
2017-02-25 22:55:15 -05:00
|
|
|
if (m_timeBase != timeBase)
|
|
|
|
{
|
|
|
|
m_timeBase = timeBase;
|
|
|
|
|
|
|
|
if (m_glScope) {
|
|
|
|
m_glScope->setTimeBase(m_timeBase);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-04 22:41:32 -05:00
|
|
|
if (m_timeOfsProMill != timeOfsProMill)
|
|
|
|
{
|
|
|
|
m_timeOfsProMill = timeOfsProMill;
|
|
|
|
|
|
|
|
if (m_glScope) {
|
|
|
|
m_glScope->setTimeOfsProMill(m_timeOfsProMill);
|
|
|
|
}
|
2017-02-03 02:27:03 -05:00
|
|
|
}
|
|
|
|
|
2017-02-07 12:50:08 -05:00
|
|
|
if (m_preTriggerDelay != triggerPre)
|
|
|
|
{
|
2017-02-09 12:45:06 -05:00
|
|
|
m_preTriggerDelay = triggerPre;
|
2018-02-21 12:54:59 -05:00
|
|
|
|
|
|
|
if (m_glScope) {
|
|
|
|
m_glScope->setTriggerPre(m_preTriggerDelay);
|
|
|
|
}
|
2017-02-07 12:50:08 -05:00
|
|
|
}
|
|
|
|
|
2017-02-05 20:40:31 -05:00
|
|
|
if (freeRun != m_freeRun)
|
|
|
|
{
|
|
|
|
m_freeRun = freeRun;
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgConfigureScopeVisNG:"
|
2017-02-04 22:41:32 -05:00
|
|
|
<< " m_traceSize: " << m_traceSize
|
2017-02-05 20:40:31 -05:00
|
|
|
<< " m_timeOfsProMill: " << m_timeOfsProMill
|
2017-02-07 12:50:08 -05:00
|
|
|
<< " m_preTriggerDelay: " << m_preTriggerDelay
|
2017-02-05 20:40:31 -05:00
|
|
|
<< " m_freeRun: " << m_freeRun;
|
2017-02-03 02:27:03 -05:00
|
|
|
|
2017-02-24 22:35:06 -05:00
|
|
|
if ((m_glScope) && (m_currentTraceMemoryIndex > 0)) {
|
|
|
|
processMemoryTrace();
|
|
|
|
}
|
|
|
|
|
2017-02-03 02:27:03 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (MsgScopeVisNGAddTrigger::match(message))
|
|
|
|
{
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGAddTrigger";
|
2017-02-13 05:30:40 -05:00
|
|
|
QMutexLocker configLocker(&m_mutex);
|
2017-02-03 02:27:03 -05:00
|
|
|
MsgScopeVisNGAddTrigger& conf = (MsgScopeVisNGAddTrigger&) message;
|
2018-04-03 17:19:35 -04:00
|
|
|
m_triggerConditions.push_back(new TriggerCondition(conf.getTriggerData()));
|
|
|
|
m_triggerConditions.back()->initProjector();
|
2017-02-03 02:27:03 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (MsgScopeVisNGChangeTrigger::match(message))
|
|
|
|
{
|
2017-02-13 05:30:40 -05:00
|
|
|
QMutexLocker configLocker(&m_mutex);
|
2017-02-03 02:27:03 -05:00
|
|
|
MsgScopeVisNGChangeTrigger& conf = (MsgScopeVisNGChangeTrigger&) message;
|
2017-05-25 14:13:34 -04:00
|
|
|
uint32_t triggerIndex = conf.getTriggerIndex();
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGChangeTrigger: " << triggerIndex;
|
2017-02-03 02:27:03 -05:00
|
|
|
|
2017-02-10 12:28:19 -05:00
|
|
|
if (triggerIndex < m_triggerConditions.size())
|
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
m_triggerConditions[triggerIndex]->setData(conf.getTriggerData());
|
2017-02-11 02:35:33 -05:00
|
|
|
|
|
|
|
if (triggerIndex == m_focusedTriggerIndex)
|
|
|
|
{
|
|
|
|
computeDisplayTriggerLevels();
|
2018-04-03 17:19:35 -04:00
|
|
|
m_glScope->setFocusedTriggerData(m_triggerConditions[m_focusedTriggerIndex]->m_triggerData);
|
2017-02-24 22:35:06 -05:00
|
|
|
updateGLScopeDisplay();
|
2017-02-11 02:35:33 -05:00
|
|
|
}
|
2017-02-03 02:27:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (MsgScopeVisNGRemoveTrigger::match(message))
|
|
|
|
{
|
2017-02-13 05:30:40 -05:00
|
|
|
QMutexLocker configLocker(&m_mutex);
|
2017-02-03 02:27:03 -05:00
|
|
|
MsgScopeVisNGRemoveTrigger& conf = (MsgScopeVisNGRemoveTrigger&) message;
|
2017-05-25 14:13:34 -04:00
|
|
|
uint32_t triggerIndex = conf.getTriggerIndex();
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGRemoveTrigger: " << triggerIndex;
|
2017-02-03 02:27:03 -05:00
|
|
|
|
2018-04-03 17:19:35 -04:00
|
|
|
if (triggerIndex < m_triggerConditions.size())
|
|
|
|
{
|
|
|
|
TriggerCondition *triggerCondition = m_triggerConditions[triggerIndex];
|
2017-02-03 02:27:03 -05:00
|
|
|
m_triggerConditions.erase(m_triggerConditions.begin() + triggerIndex);
|
2018-04-03 17:19:35 -04:00
|
|
|
delete triggerCondition;
|
2017-02-03 02:27:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2017-02-26 13:14:27 -05:00
|
|
|
else if (MsgScopeVisNGMoveTrigger::match(message))
|
|
|
|
{
|
|
|
|
QMutexLocker configLocker(&m_mutex);
|
|
|
|
MsgScopeVisNGMoveTrigger& conf = (MsgScopeVisNGMoveTrigger&) message;
|
|
|
|
int triggerIndex = conf.getTriggerIndex();
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGMoveTrigger: " << triggerIndex;
|
2017-02-26 13:14:27 -05:00
|
|
|
|
|
|
|
if (!conf.getMoveUp() && (triggerIndex == 0)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int nextTriggerIndex = (triggerIndex + (conf.getMoveUp() ? 1 : -1)) % m_triggerConditions.size();
|
|
|
|
|
2018-04-03 17:19:35 -04:00
|
|
|
TriggerCondition *nextTrigger = m_triggerConditions[nextTriggerIndex];
|
2017-02-26 13:14:27 -05:00
|
|
|
m_triggerConditions[nextTriggerIndex] = m_triggerConditions[triggerIndex];
|
|
|
|
m_triggerConditions[triggerIndex] = nextTrigger;
|
|
|
|
|
|
|
|
computeDisplayTriggerLevels();
|
2018-04-03 17:19:35 -04:00
|
|
|
m_glScope->setFocusedTriggerData(m_triggerConditions[m_focusedTriggerIndex]->m_triggerData);
|
2017-02-26 13:14:27 -05:00
|
|
|
updateGLScopeDisplay();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2017-02-11 04:36:10 -05:00
|
|
|
else if (MsgScopeVisNGFocusOnTrigger::match(message))
|
|
|
|
{
|
|
|
|
MsgScopeVisNGFocusOnTrigger& conf = (MsgScopeVisNGFocusOnTrigger&) message;
|
2017-05-25 14:13:34 -04:00
|
|
|
uint32_t triggerIndex = conf.getTriggerIndex();
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGFocusOnTrigger: " << triggerIndex;
|
2017-02-11 04:36:10 -05:00
|
|
|
|
|
|
|
if (triggerIndex < m_triggerConditions.size())
|
|
|
|
{
|
|
|
|
m_focusedTriggerIndex = triggerIndex;
|
|
|
|
computeDisplayTriggerLevels();
|
2018-04-03 17:19:35 -04:00
|
|
|
m_glScope->setFocusedTriggerData(m_triggerConditions[m_focusedTriggerIndex]->m_triggerData);
|
2017-02-24 22:35:06 -05:00
|
|
|
updateGLScopeDisplay();
|
2017-02-11 04:36:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2017-02-03 02:27:03 -05:00
|
|
|
else if (MsgScopeVisNGAddTrace::match(message))
|
|
|
|
{
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGAddTrace";
|
2017-02-12 21:23:29 -05:00
|
|
|
QMutexLocker configLocker(&m_mutex);
|
2017-02-03 02:27:03 -05:00
|
|
|
MsgScopeVisNGAddTrace& conf = (MsgScopeVisNGAddTrace&) message;
|
2017-02-05 20:40:31 -05:00
|
|
|
m_traces.addTrace(conf.getTraceData(), m_traceSize);
|
|
|
|
initTraceBuffers();
|
|
|
|
updateMaxTraceDelay();
|
2017-02-11 04:36:10 -05:00
|
|
|
computeDisplayTriggerLevels();
|
2017-02-24 22:35:06 -05:00
|
|
|
updateGLScopeDisplay();
|
2017-02-03 02:27:03 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (MsgScopeVisNGChangeTrace::match(message))
|
|
|
|
{
|
2017-02-12 21:23:29 -05:00
|
|
|
QMutexLocker configLocker(&m_mutex);
|
2017-02-03 02:27:03 -05:00
|
|
|
MsgScopeVisNGChangeTrace& conf = (MsgScopeVisNGChangeTrace&) message;
|
2017-02-10 12:28:19 -05:00
|
|
|
bool doComputeTriggerLevelsOnDisplay = m_traces.isVerticalDisplayChange(conf.getTraceData(), conf.getTraceIndex());
|
2018-05-21 12:00:10 -04:00
|
|
|
uint32_t traceIndex = conf.getTraceIndex();
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGChangeTrace: " << traceIndex;
|
2018-05-21 12:00:10 -04:00
|
|
|
m_traces.changeTrace(conf.getTraceData(), traceIndex);
|
2017-02-05 20:40:31 -05:00
|
|
|
updateMaxTraceDelay();
|
2017-02-11 04:36:10 -05:00
|
|
|
if (doComputeTriggerLevelsOnDisplay) computeDisplayTriggerLevels();
|
2017-02-24 22:35:06 -05:00
|
|
|
updateGLScopeDisplay();
|
2017-02-03 02:27:03 -05:00
|
|
|
return true;
|
2017-01-31 02:26:13 -05:00
|
|
|
}
|
2017-02-03 02:27:03 -05:00
|
|
|
else if (MsgScopeVisNGRemoveTrace::match(message))
|
|
|
|
{
|
2017-02-12 21:23:29 -05:00
|
|
|
QMutexLocker configLocker(&m_mutex);
|
2017-02-03 02:27:03 -05:00
|
|
|
MsgScopeVisNGRemoveTrace& conf = (MsgScopeVisNGRemoveTrace&) message;
|
2018-05-21 12:00:10 -04:00
|
|
|
uint32_t traceIndex = conf.getTraceIndex();
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGRemoveTrace: " << traceIndex;
|
2018-05-21 12:00:10 -04:00
|
|
|
m_traces.removeTrace(traceIndex);
|
2017-02-05 20:40:31 -05:00
|
|
|
updateMaxTraceDelay();
|
2017-02-11 04:36:10 -05:00
|
|
|
computeDisplayTriggerLevels();
|
2017-02-24 22:35:06 -05:00
|
|
|
updateGLScopeDisplay();
|
2017-02-03 02:27:03 -05:00
|
|
|
return true;
|
|
|
|
}
|
2017-02-26 05:26:23 -05:00
|
|
|
else if (MsgScopeVisNGMoveTrace::match(message))
|
|
|
|
{
|
|
|
|
QMutexLocker configLocker(&m_mutex);
|
|
|
|
MsgScopeVisNGMoveTrace& conf = (MsgScopeVisNGMoveTrace&) message;
|
2018-05-21 12:00:10 -04:00
|
|
|
uint32_t traceIndex = conf.getTraceIndex();
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGMoveTrace: " << traceIndex;
|
2018-05-21 12:00:10 -04:00
|
|
|
m_traces.moveTrace(traceIndex, conf.getMoveUp());
|
2017-02-26 05:26:23 -05:00
|
|
|
//updateMaxTraceDelay();
|
|
|
|
computeDisplayTriggerLevels();
|
|
|
|
updateGLScopeDisplay();
|
|
|
|
return true;
|
|
|
|
}
|
2017-02-12 19:32:02 -05:00
|
|
|
else if (MsgScopeVisNGFocusOnTrace::match(message))
|
|
|
|
{
|
|
|
|
MsgScopeVisNGFocusOnTrace& conf = (MsgScopeVisNGFocusOnTrace&) message;
|
2017-05-25 14:13:34 -04:00
|
|
|
uint32_t traceIndex = conf.getTraceIndex();
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGFocusOnTrace: " << traceIndex;
|
2017-02-12 19:32:02 -05:00
|
|
|
|
|
|
|
if (traceIndex < m_traces.m_tracesData.size())
|
|
|
|
{
|
|
|
|
m_focusedTraceIndex = traceIndex;
|
|
|
|
computeDisplayTriggerLevels();
|
|
|
|
m_glScope->setFocusedTraceIndex(m_focusedTraceIndex);
|
2017-02-24 22:35:06 -05:00
|
|
|
updateGLScopeDisplay();
|
2017-02-12 19:32:02 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2017-02-21 19:18:50 -05:00
|
|
|
else if (MsgScopeVisNGOneShot::match(message))
|
|
|
|
{
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGOneShot";
|
2017-02-21 19:18:50 -05:00
|
|
|
MsgScopeVisNGOneShot& conf = (MsgScopeVisNGOneShot&) message;
|
|
|
|
bool oneShot = conf.getOneShot();
|
|
|
|
m_triggerOneShot = oneShot;
|
|
|
|
if (m_triggerWaitForReset && !oneShot) m_triggerWaitForReset = false;
|
2017-02-26 00:06:59 -05:00
|
|
|
return true;
|
2017-02-21 19:18:50 -05:00
|
|
|
}
|
2017-02-23 02:18:03 -05:00
|
|
|
else if (MsgScopeVisNGMemoryTrace::match(message))
|
|
|
|
{
|
|
|
|
MsgScopeVisNGMemoryTrace& conf = (MsgScopeVisNGMemoryTrace&) message;
|
|
|
|
uint32_t memoryIndex = conf.getMemoryIndex();
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage: MsgScopeVisNGMemoryTrace: " << memoryIndex;
|
2017-02-24 02:31:25 -05:00
|
|
|
|
|
|
|
if (memoryIndex != m_currentTraceMemoryIndex)
|
|
|
|
{
|
2018-10-15 23:10:35 -04:00
|
|
|
// transition from live mode
|
2018-10-15 18:31:45 -04:00
|
|
|
if (memoryIndex == 0) {
|
2018-10-15 23:10:35 -04:00
|
|
|
m_liveTraceSize = m_traceSize;
|
2018-10-15 18:31:45 -04:00
|
|
|
}
|
|
|
|
|
2017-02-24 02:31:25 -05:00
|
|
|
m_currentTraceMemoryIndex = memoryIndex;
|
|
|
|
|
2018-10-15 23:10:35 -04:00
|
|
|
if (m_currentTraceMemoryIndex == 0) // transition to live mode
|
|
|
|
{
|
|
|
|
setSampleRate(m_liveSampleRate); // reset to live rate
|
|
|
|
setTraceSize(m_liveTraceSize); // reset to live trace size
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-02-24 17:24:47 -05:00
|
|
|
processMemoryTrace();
|
2017-02-24 02:31:25 -05:00
|
|
|
}
|
|
|
|
}
|
2017-02-26 00:06:59 -05:00
|
|
|
return true;
|
2017-02-23 02:18:03 -05:00
|
|
|
}
|
2017-02-03 02:27:03 -05:00
|
|
|
else
|
|
|
|
{
|
2018-08-12 11:18:58 -04:00
|
|
|
qDebug() << "ScopeVis::handleMessage" << message.getIdentifier() << " not handled";
|
2017-02-03 02:27:03 -05:00
|
|
|
return false;
|
|
|
|
}
|
2017-01-29 13:51:45 -05:00
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::updateMaxTraceDelay()
|
2017-02-05 20:40:31 -05:00
|
|
|
{
|
|
|
|
int maxTraceDelay = 0;
|
2017-02-18 22:46:15 -05:00
|
|
|
bool allocateCache = false;
|
2018-04-03 12:51:21 -04:00
|
|
|
uint32_t projectorCounts[(int) Projector::nbProjectionTypes];
|
|
|
|
memset(projectorCounts, 0, ((int) Projector::nbProjectionTypes)*sizeof(uint32_t));
|
2017-02-18 22:46:15 -05:00
|
|
|
std::vector<TraceData>::iterator itData = m_traces.m_tracesData.begin();
|
2018-04-03 16:29:09 -04:00
|
|
|
std::vector<TraceControl*>::iterator itCtrl = m_traces.m_tracesControl.begin();
|
2017-02-05 20:40:31 -05:00
|
|
|
|
2017-02-18 22:46:15 -05:00
|
|
|
for (; itData != m_traces.m_tracesData.end(); ++itData, ++itCtrl)
|
2017-02-05 20:40:31 -05:00
|
|
|
{
|
|
|
|
if (itData->m_traceDelay > maxTraceDelay)
|
|
|
|
{
|
|
|
|
maxTraceDelay = itData->m_traceDelay;
|
|
|
|
}
|
2017-02-18 22:46:15 -05:00
|
|
|
|
2018-02-15 12:48:31 -05:00
|
|
|
if (itData->m_projectionType < 0) {
|
2018-04-03 12:51:21 -04:00
|
|
|
itData->m_projectionType = Projector::ProjectionReal;
|
2018-02-15 12:48:31 -05:00
|
|
|
}
|
|
|
|
|
2017-02-18 22:46:15 -05:00
|
|
|
if (projectorCounts[(int) itData->m_projectionType] > 0)
|
|
|
|
{
|
|
|
|
allocateCache = true;
|
2018-04-03 16:29:09 -04:00
|
|
|
(*itCtrl)->m_projector.setCacheMaster(false);
|
2017-02-18 22:46:15 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-03 16:29:09 -04:00
|
|
|
(*itCtrl)->m_projector.setCacheMaster(true);
|
2017-02-18 22:46:15 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
projectorCounts[(int) itData->m_projectionType]++;
|
|
|
|
}
|
|
|
|
|
|
|
|
itCtrl = m_traces.m_tracesControl.begin();
|
|
|
|
|
|
|
|
for (; itCtrl != m_traces.m_tracesControl.end(); ++itCtrl)
|
|
|
|
{
|
|
|
|
if (allocateCache) {
|
2018-04-03 16:29:09 -04:00
|
|
|
(*itCtrl)->m_projector.setCache(m_projectorCache);
|
2017-02-18 22:46:15 -05:00
|
|
|
} else {
|
2018-04-03 16:29:09 -04:00
|
|
|
(*itCtrl)->m_projector.setCache(0);
|
2017-02-18 22:46:15 -05:00
|
|
|
}
|
2017-02-05 20:40:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
m_maxTraceDelay = maxTraceDelay;
|
|
|
|
}
|
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::initTraceBuffers()
|
2017-02-05 20:40:31 -05:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2017-05-25 14:13:34 -04:00
|
|
|
for (unsigned int i = 0; i < m_traceSize; i++)
|
2017-02-05 20:40:31 -05:00
|
|
|
{
|
|
|
|
(*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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-02-11 02:35:33 -05:00
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::computeDisplayTriggerLevels()
|
2017-02-11 02:35:33 -05:00
|
|
|
{
|
|
|
|
std::vector<TraceData>::iterator itData = m_traces.m_tracesData.begin();
|
|
|
|
|
|
|
|
for (; itData != m_traces.m_tracesData.end(); ++itData)
|
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
if ((m_focusedTriggerIndex < m_triggerConditions.size()) && (m_triggerConditions[m_focusedTriggerIndex]->m_projector.getProjectionType() == itData->m_projectionType))
|
2017-02-11 02:35:33 -05:00
|
|
|
{
|
2018-04-03 17:19:35 -04:00
|
|
|
float level = m_triggerConditions[m_focusedTriggerIndex]->m_triggerData.m_triggerLevel;
|
2017-02-11 02:35:33 -05:00
|
|
|
float levelPowerLin = level + 1.0f;
|
|
|
|
float levelPowerdB = (100.0f * (level - 1.0f));
|
|
|
|
float v;
|
|
|
|
|
2018-06-25 19:39:23 -04:00
|
|
|
if ((itData->m_projectionType == Projector::ProjectionMagLin) || (itData->m_projectionType == Projector::ProjectionMagSq))
|
2017-02-11 02:35:33 -05:00
|
|
|
{
|
|
|
|
v = (levelPowerLin - itData->m_ofs)*itData->m_amp - 1.0f;
|
|
|
|
}
|
2018-04-03 12:51:21 -04:00
|
|
|
else if (itData->m_projectionType == Projector::ProjectionMagDB)
|
2017-02-11 02:35:33 -05:00
|
|
|
{
|
|
|
|
float ofsdB = itData->m_ofs * 100.0f;
|
|
|
|
v = ((levelPowerdB + 100.0f - ofsdB)*itData->m_amp)/50.0f - 1.0f;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
v = (level - itData->m_ofs) * itData->m_amp;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(v > 1.0f) {
|
|
|
|
v = 1.0f;
|
|
|
|
} else if (v < -1.0f) {
|
|
|
|
v = -1.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
itData->m_triggerDisplayLevel = v;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
itData->m_triggerDisplayLevel = 2.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-02-24 22:35:06 -05:00
|
|
|
|
2018-08-12 11:18:58 -04:00
|
|
|
void ScopeVis::updateGLScopeDisplay()
|
2017-02-24 22:35:06 -05:00
|
|
|
{
|
|
|
|
if (m_currentTraceMemoryIndex > 0) {
|
|
|
|
m_glScope->setConfigChanged();
|
|
|
|
processMemoryTrace();
|
|
|
|
} else {
|
|
|
|
m_glScope->updateDisplay();
|
|
|
|
}
|
|
|
|
}
|