New scope: fixed trace display and triggers

pull/27/head
f4exb 2017-02-08 02:13:53 +01:00
rodzic 199e915c62
commit 897a181028
4 zmienionych plików z 126 dodań i 86 usunięć

Wyświetl plik

@ -81,7 +81,10 @@ void ScopeVisNG::addTrace(const TraceData& traceData)
void ScopeVisNG::changeTrace(const TraceData& traceData, uint32_t traceIndex)
{
qDebug("ScopeVisNG::changeTrace: trace #%d", traceIndex);
qDebug() << "ScopeVisNG::changeTrace:"
<< " trace: " << traceIndex
<< " m_amp: " << traceData.m_amp
<< " m_ofs: " << traceData.m_ofs;
Message* cmd = MsgScopeVisNGChangeTrace::create(traceData, traceIndex);
getInputMessageQueue()->push(cmd);
}
@ -158,56 +161,18 @@ void ScopeVisNG::feed(const SampleVector::const_iterator& cbegin, const SampleVe
while (begin < end)
{
if (m_triggerState == TriggerDelay)
{
if (triggerCondition.m_triggerDelayCount > 0)
{
triggerCondition.m_triggerDelayCount--; // pass
}
else // delay expired => fire this trigger
{
if (!nextTrigger()) // finished
{
m_traceStart = true; // start trace processing
m_triggerPoint = begin;
break;
}
}
}
else // look for trigger
{
bool condition = compareTrigger(*begin, triggerCondition); // triggerCondition.m_projector->run(*begin) > triggerCondition.m_triggerData.m_triggerLevel;
bool trigger;
if (triggerCondition.m_triggerData.m_triggerBothEdges) {
trigger = triggerCondition.m_prevCondition ^ condition;
} else {
trigger = (triggerCondition.m_prevCondition ^ condition) && (condition ^ !triggerCondition.m_triggerData.m_triggerPositiveEdge);
}
triggerCondition.m_prevCondition = condition;
if (trigger) // trigger condition
{
if (triggerCondition.m_triggerData.m_triggerDelay > 0) // there is a delay => initialize the delay
{
triggerCondition.m_triggerDelayCount = triggerCondition.m_triggerData.m_triggerDelay;
m_triggerState = TriggerDelay;
}
else
{
if (!nextTrigger()) // finished
{
m_traceStart = true; // start trace processing
m_triggerPoint = begin;
break;
}
}
}
}
// look for trigger
if (m_triggerComparator.triggered(*begin, triggerCondition))
{
m_traceStart = true; // start trace processing
m_triggerPoint = begin;
m_triggerComparator.reset();
m_triggerState = TriggerTriggered;
break;
}
++begin;
} // begin < end
}
}
else
{
@ -307,24 +272,22 @@ int ScopeVisNG::processTraces(int beginPointDelta, int endPointDelta, TraceBackB
if (itCtl->m_traceCount[m_traces.currentBufferIndex()] < m_traceSize)
{
float posLimit = 1.0 / itData->m_amp;
float negLimit = -1.0 / itData->m_amp;
ProjectionType projectionType = itData->m_projectionType;
float v;
if (projectionType == ProjectionMagLin) {
v = itCtl->m_projector->run(*begin)*itData->m_amp - itData->m_ofs - 1.0/itData->m_amp;
} else if (projectionType == ProjectionMagDB) { // TODO: optimize computation using a specialized projector (2 projectors: value and trace)
v = 1.0f + 2.0f*(((itCtl->m_projector->run(*begin))/100.0f) - itData->m_ofs) + 1.0f - 1.0f/itData->m_amp;
//v = itCtl->m_projector->run(*begin) * itData->m_amp - itData->m_ofs;
v = (itCtl->m_projector->run(*begin) - itData->m_ofs)*itData->m_amp - 1.0f;
} else if (projectionType == ProjectionMagDB) {
float p = itCtl->m_projector->run(*begin) - (100.0f * itData->m_ofs);
v = ((p/50.0f) + 2.0f)*itData->m_amp - 1.0f;
} else {
v = itCtl->m_projector->run(*begin) * itData->m_amp - itData->m_ofs;
v = (itCtl->m_projector->run(*begin) - itData->m_ofs) * itData->m_amp;
}
if(v > posLimit) {
v = posLimit;
} else if (v < negLimit) {
v = negLimit;
if(v > 1.0f) {
v = 1.0f;
} else if (v < -1.0f) {
v = -1.0f;
}
(*itTrace)[2*(itCtl->m_traceCount[m_traces.currentBufferIndex()])]

Wyświetl plik

@ -350,16 +350,27 @@ private:
virtual Real run(const Sample& s)
{
Real curArg = std::atan2((float) s.m_imag, (float) s.m_real);
Real dPhi = curArg - m_prevArg;
Real dPhi = (curArg - m_prevArg) / M_PI;
m_prevArg = curArg;
if (dPhi < -M_PI) {
dPhi += 2.0 * M_PI;
} else if (dPhi > M_PI) {
dPhi -= 2.0 * M_PI;
if (dPhi < -1.0f) {
dPhi += 2.0f;
} else if (dPhi > 1.0f) {
dPhi -= 2.0f;
}
return dPhi/M_PI;
return dPhi;
// Real dPhi = curArg - m_prevArg;
// m_prevArg = curArg;
//
// if (dPhi < -M_PI) {
// dPhi += 2.0 * M_PI;
// } else if (dPhi > M_PI) {
// dPhi -= 2.0 * M_PI;
// }
//
// return dPhi/M_PI;
}
private:
@ -668,6 +679,77 @@ private:
}
};
class TriggerComparator
{
public:
TriggerComparator() : m_level(0), m_reset(true)
{
computeLevels();
}
bool triggered(const Sample& s, TriggerCondition& triggerCondition)
{
if (triggerCondition.m_triggerData.m_triggerLevel != m_level)
{
m_level = triggerCondition.m_triggerData.m_triggerLevel;
computeLevels();
}
bool condition, trigger;
if (triggerCondition.m_projector->getProjectionType() == ProjectionMagDB) {
condition = triggerCondition.m_projector->run(s) > m_levelPwoerDB;
} else if (triggerCondition.m_projector->getProjectionType() == ProjectionMagLin) {
condition = triggerCondition.m_projector->run(s) > m_levelPowerLin;
} else {
condition = triggerCondition.m_projector->run(s) > m_level;
}
if (m_reset)
{
triggerCondition.m_prevCondition = condition;
m_reset = false;
return false;
}
if (triggerCondition.m_triggerData.m_triggerBothEdges) {
trigger = triggerCondition.m_prevCondition ? !condition : condition; // This is a XOR between bools
} else if (triggerCondition.m_triggerData.m_triggerPositiveEdge) {
trigger = !triggerCondition.m_prevCondition && condition;
} else {
trigger = triggerCondition.m_prevCondition && !condition;
}
// if (trigger) {
// qDebug("ScopeVisNG::triggered: %s/%s %f/%f",
// triggerCondition.m_prevCondition ? "T" : "F",
// condition ? "T" : "F",
// triggerCondition.m_projector->run(s),
// triggerCondition.m_triggerData.m_triggerLevel);
// }
triggerCondition.m_prevCondition = condition;
return trigger;
}
void reset()
{
m_reset = true;
}
private:
void computeLevels()
{
m_levelPowerLin = m_level + 1.0f;
m_levelPwoerDB = (100.0f * (m_level - 1.0f));
}
Real m_level;
Real m_levelPwoerDB;
Real m_levelPowerLin;
bool m_reset;
};
GLScopeNG* m_glScope;
uint32_t m_preTriggerDelay; //!< Pre-trigger delay in number of samples
std::vector<TriggerCondition> m_triggerConditions; //!< Chain of triggers
@ -686,21 +768,7 @@ private:
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
/**
* Test sample against trigger level. Returns true if sample is above level.
* TODO: optimize power level computation by storing value when it changes
*/
bool compareTrigger(const Sample& s, TriggerCondition& triggerCondition)
{
if (triggerCondition.m_projector->getProjectionType() == ProjectionMagDB) {
return triggerCondition.m_projector->run(s) > (100.0f * (triggerCondition.m_triggerData.m_triggerLevel - 1.0f));
} else if (triggerCondition.m_projector->getProjectionType() == ProjectionMagLin) {
return triggerCondition.m_projector->run(s) > triggerCondition.m_triggerData.m_triggerLevel + 1.0f;
} else {
return triggerCondition.m_projector->run(s) > triggerCondition.m_triggerData.m_triggerLevel;
}
}
TriggerComparator m_triggerComparator; //!< Compares sample level to trigger level
/**
* Moves on to the next trigger if any or increments trigger count if in repeat mode

Wyświetl plik

@ -305,7 +305,8 @@ void GLScopeNG::paintGL()
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) * traceData.m_amp;
//float rectH = -(m_glScopeRect1.height() / 2.0f) * traceData.m_amp;
float rectH = -m_glScopeRect1.height() / 2.0f;
QVector4D color(1.0f, 1.0f, 0.25f, m_displayTraceIntensity / 100.0f);
QMatrix4x4 mat;
@ -994,9 +995,9 @@ void GLScopeNG::setYScale(ScaleEngine& scale, uint32_t highlightedTraceIndex)
break;
case ScopeVisNG::ProjectionMagLin:
if (amp_range < 2.0) {
scale.setRange(Unit::None, amp_ofs * 500.0, amp_range * 1000.0 + amp_ofs * 500.0);
scale.setRange(Unit::None, amp_ofs * 1000.0, amp_range * 1000.0 + amp_ofs * 1000.0);
} else {
scale.setRange(Unit::None, amp_ofs/2.0, amp_range + amp_ofs/2.0);
scale.setRange(Unit::None, amp_ofs, amp_range + amp_ofs);
}
break;
case ScopeVisNG::ProjectionPhase: // Phase or frequency

Wyświetl plik

@ -352,7 +352,10 @@ void GLScopeNGGUI::on_trigDelay_valueChanged(int value)
void GLScopeNGGUI::on_trigPre_valueChanged(int value)
{
setTrigPreDisplay();
changeCurrentTrigger();
m_scopeVis->configure(m_traceLenMult*ScopeVisNG::m_traceChunkSize,
m_timeOffset*10,
(uint32_t) (m_glScope->getTraceSize() * (ui->trigPre->value()/100.0f)),
ui->freerun->isChecked()); // TODO: implement one shot feature
}
void GLScopeNGGUI::on_trigOneShot_toggled(bool checked)
@ -615,8 +618,13 @@ void GLScopeNGGUI::fillTraceData(ScopeVisNG::TraceData& traceData)
traceData.m_projectionType = (ScopeVisNG::ProjectionType) ui->traceMode->currentIndex();
traceData.m_inputIndex = 0;
traceData.m_amp = 0.2 / amps[ui->amp->value()];
traceData.m_ofs = ((10.0 * ui->ofsCoarse->value()) + (ui->ofsFine->value() / 20.0)) / 1000.0f;
traceData.m_traceDelay = 0;
if (traceData.m_projectionType == ScopeVisNG::ProjectionMagLin) {
traceData.m_ofs = ((10.0 * ui->ofsCoarse->value()) + (ui->ofsFine->value() / 20.0)) / 2000.0f;
} else {
traceData.m_ofs = ((10.0 * ui->ofsCoarse->value()) + (ui->ofsFine->value() / 20.0)) / 1000.0f;
}
}
void GLScopeNGGUI::fillTriggerData(ScopeVisNG::TriggerData& triggerData)