forked from Ivasoft/DSView
fix: math trace crashed with multiply mode, and got an error unit
This commit is contained in:
@@ -65,14 +65,17 @@ const uint64_t MathStack::vDialValue[MathStack::vDialValueCount] = {
|
||||
const QString MathStack::vDialAddUnit[MathStack::vDialUnitCount] = {
|
||||
"mV",
|
||||
"V",
|
||||
"kV",
|
||||
};
|
||||
const QString MathStack::vDialMulUnit[MathStack::vDialUnitCount] = {
|
||||
"mV*V",
|
||||
"V*V",
|
||||
"kV*V",
|
||||
};
|
||||
const QString MathStack::vDialDivUnit[MathStack::vDialUnitCount] = {
|
||||
"mV/V",
|
||||
"V/V",
|
||||
"kV/V",
|
||||
};
|
||||
|
||||
MathStack::MathStack(pv::SigSession *session,
|
||||
@@ -161,14 +164,11 @@ void MathStack::enable_envelope(bool enable)
|
||||
|
||||
uint64_t MathStack::default_vDialValue()
|
||||
{
|
||||
uint64_t value = 0;
|
||||
view::dslDial *dial1 = _dsoSig1->get_vDial();
|
||||
view::dslDial *dial2 = _dsoSig2->get_vDial();
|
||||
const uint64_t dial1_value = dial1->get_value();
|
||||
const uint64_t dial2_value = dial2->get_value();
|
||||
|
||||
const uint64_t v1 = dial1_value * dial1->get_factor();
|
||||
const uint64_t v2 = dial2_value * dial2->get_factor();
|
||||
uint64_t value = 0;
|
||||
const uint64_t dial1_value = _dsoSig1->get_vDial()->get_value();
|
||||
const uint64_t dial2_value = _dsoSig2->get_vDial()->get_value();
|
||||
const uint64_t v1 = _dsoSig1->get_vDial()->get_factor() * dial1_value;
|
||||
const uint64_t v2 = _dsoSig2->get_vDial()->get_factor() * dial2_value;
|
||||
|
||||
switch(_type) {
|
||||
case MATH_ADD:
|
||||
@@ -203,18 +203,15 @@ uint64_t MathStack::default_vDialValue()
|
||||
uint64_t MathStack::default_factor()
|
||||
{
|
||||
uint64_t value = 0;
|
||||
view::dslDial *dial1 = _dsoSig1->get_vDial();
|
||||
view::dslDial *dial2 = _dsoSig2->get_vDial();
|
||||
uint64_t factor1 = dial1->get_factor();
|
||||
uint64_t factor2 = dial1->get_factor();
|
||||
|
||||
const uint64_t dial1_value = dial1->get_value() * factor1;
|
||||
const uint64_t dial2_value = dial2->get_value() * factor2;
|
||||
const uint64_t factor1 = _dsoSig1->get_vDial()->get_factor();
|
||||
const uint64_t factor2 = _dsoSig2->get_vDial()->get_factor();
|
||||
const uint64_t v1 = _dsoSig1->get_vDial()->get_value() * factor1;
|
||||
const uint64_t v2 = _dsoSig2->get_vDial()->get_value() * factor2;
|
||||
|
||||
switch(_type) {
|
||||
case MATH_ADD:
|
||||
case MATH_SUB:
|
||||
value = dial1_value > dial2_value ? factor1 : factor2;
|
||||
value = v1 > v2 ? factor1 : factor2;
|
||||
break;
|
||||
case MATH_MUL:
|
||||
value = factor1 * factor2;
|
||||
@@ -233,10 +230,10 @@ view::dslDial * MathStack::get_vDial()
|
||||
QVector<QString> vUnit;
|
||||
view::dslDial *dial1 = _dsoSig1->get_vDial();
|
||||
view::dslDial *dial2 = _dsoSig2->get_vDial();
|
||||
const uint64_t dial1_min = dial1->get_value(0) * dial1->get_factor();
|
||||
const uint64_t dial1_max = dial1->get_value(dial1->get_count() - 1) * dial1->get_factor();
|
||||
const uint64_t dial2_min = dial2->get_value(0) * dial2->get_factor();
|
||||
const uint64_t dial2_max = dial2->get_value(dial2->get_count() - 1) * dial2->get_factor();
|
||||
const uint64_t dial1_min = dial1->get_value(0);
|
||||
const uint64_t dial1_max = dial1->get_value(dial1->get_count() - 1);
|
||||
const uint64_t dial2_min = dial2->get_value(0);
|
||||
const uint64_t dial2_max = dial2->get_value(dial2->get_count() - 1);
|
||||
|
||||
switch(_type) {
|
||||
case MATH_ADD:
|
||||
@@ -275,14 +272,13 @@ view::dslDial * MathStack::get_vDial()
|
||||
break;
|
||||
}
|
||||
|
||||
view::dslDial *vDial = new view::dslDial(vValue.count(), vDialValueStep, vValue, vUnit);
|
||||
view::dslDial *vDial = new view::dslDial(vValue.count(), vDialValueStep, vValue, vUnit, true);
|
||||
return vDial;
|
||||
}
|
||||
|
||||
QString MathStack::get_unit(int level)
|
||||
{
|
||||
if (level >= vDialUnitCount)
|
||||
//tr
|
||||
return " ";
|
||||
|
||||
QString unit;
|
||||
@@ -356,8 +352,10 @@ void MathStack::get_math_envelope_section(EnvelopeSection &s,
|
||||
s.samples = _envelope_level[min_level].samples + start;
|
||||
}
|
||||
|
||||
void MathStack::calc_math()
|
||||
void MathStack::calc_math(uint64_t mathFactor)
|
||||
{
|
||||
assert(mathFactor > 0);
|
||||
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
_math_state = Running;
|
||||
@@ -373,12 +371,17 @@ void MathStack::calc_math()
|
||||
if (data->get_channel_num() < 2)
|
||||
return;
|
||||
|
||||
const double scale1 = _dsoSig1->get_vDialValue() / 1000.0 * _dsoSig1->get_factor() * DS_CONF_DSO_VDIVS *
|
||||
auto k1 = _dsoSig1->get_factor();
|
||||
auto k2 = _dsoSig2->get_factor();
|
||||
|
||||
const double scale1 = _dsoSig1->get_vDialValue() / 1000.0 * k1 * DS_CONF_DSO_VDIVS *
|
||||
_dsoSig1->get_scale() / _dsoSig1->get_view_rect().height();
|
||||
|
||||
const double delta1 = _dsoSig1->get_hw_offset() * scale1;
|
||||
|
||||
const double scale2 = _dsoSig2->get_vDialValue() / 1000.0 * _dsoSig2->get_factor() * DS_CONF_DSO_VDIVS *
|
||||
const double scale2 = _dsoSig2->get_vDialValue() / 1000.0 * k2 * DS_CONF_DSO_VDIVS *
|
||||
_dsoSig2->get_scale() / _dsoSig2->get_view_rect().height();
|
||||
|
||||
const double delta2 = _dsoSig2->get_hw_offset() * scale2;
|
||||
|
||||
_sample_num = data->get_sample_count();
|
||||
@@ -394,19 +397,20 @@ void MathStack::calc_math()
|
||||
value1 = *(value_buffer1 + sample);
|
||||
value2 = *(value_buffer2 + sample);
|
||||
|
||||
switch(_type) {
|
||||
case MATH_ADD:
|
||||
_math[sample] = (delta1 - scale1 * value1) + (delta2 - scale2 * value2);
|
||||
break;
|
||||
case MATH_SUB:
|
||||
_math[sample] = (delta1 - scale1 * value1) - (delta2 - scale2 * value2);
|
||||
break;
|
||||
case MATH_MUL:
|
||||
_math[sample] = (delta1 - scale1 * value1) * (delta2 - scale2 * value2);
|
||||
break;
|
||||
case MATH_DIV:
|
||||
_math[sample] = (delta1 - scale1 * value1) / (delta2 - scale2 * value2);
|
||||
break;
|
||||
switch(_type)
|
||||
{
|
||||
case MATH_ADD:
|
||||
_math[sample] = ((delta1 - scale1 * value1) + (delta2 - scale2 * value2)) / mathFactor;
|
||||
break;
|
||||
case MATH_SUB:
|
||||
_math[sample] = ((delta1 - scale1 * value1) - (delta2 - scale2 * value2)) / mathFactor;
|
||||
break;
|
||||
case MATH_MUL:
|
||||
_math[sample] = (delta1 - scale1 * value1) * (delta2 - scale2 * value2) / mathFactor;
|
||||
break;
|
||||
case MATH_DIV:
|
||||
_math[sample] = (delta1 - scale1 * value1) / (delta2 - scale2 * value2) / mathFactor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ private:
|
||||
static const uint64_t vDialValueStep = 1000;
|
||||
static const int vDialValueCount = 19;
|
||||
static const uint64_t vDialValue[vDialValueCount];
|
||||
static const int vDialUnitCount = 2;
|
||||
static const int vDialUnitCount = 3;
|
||||
static const QString vDialAddUnit[vDialUnitCount];
|
||||
static const QString vDialMulUnit[vDialUnitCount];
|
||||
static const QString vDialDivUnit[vDialUnitCount];
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
void get_math_envelope_section(EnvelopeSection &s,
|
||||
uint64_t start, uint64_t end, float min_length);
|
||||
|
||||
void calc_math();
|
||||
void calc_math(uint64_t mathFactor);
|
||||
void reallocate_envelope(Envelope &e);
|
||||
void append_to_envelope_level(bool header);
|
||||
|
||||
|
||||
@@ -1323,7 +1323,7 @@ namespace pv
|
||||
if (_math_trace && _math_trace->enabled())
|
||||
{
|
||||
_math_trace->get_math_stack()->realloc(_device_agent.get_sample_limit());
|
||||
_math_trace->get_math_stack()->calc_math();
|
||||
_math_trace->get_math_stack()->calc_math(_math_trace->get_vDialfactor());
|
||||
}
|
||||
|
||||
_trigger_flag = o.trig_flag;
|
||||
@@ -1763,7 +1763,7 @@ namespace pv
|
||||
if (rt > 0){
|
||||
_math_trace->get_math_stack()->set_samplerate(rt);
|
||||
_math_trace->get_math_stack()->realloc(_device_agent.get_sample_limit());
|
||||
_math_trace->get_math_stack()->calc_math();
|
||||
_math_trace->get_math_stack()->calc_math(_math_trace->get_vDialfactor());
|
||||
}
|
||||
}
|
||||
signals_changed();
|
||||
|
||||
@@ -23,17 +23,19 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include "../log.h"
|
||||
|
||||
namespace pv {
|
||||
namespace view {
|
||||
|
||||
dslDial::dslDial(const uint64_t div, const uint64_t step,
|
||||
const QVector<uint64_t> value, const QVector<QString> unit)
|
||||
const QVector<uint64_t> value, const QVector<QString> unit, bool isMath)
|
||||
{
|
||||
assert(div > 0);
|
||||
assert(step > 0);
|
||||
assert((uint64_t)value.count() == div);
|
||||
assert(unit.count() > 0);
|
||||
_is_math = isMath;
|
||||
|
||||
_div = div;
|
||||
_step = step;
|
||||
@@ -80,13 +82,25 @@ void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor, const QPoint
|
||||
}
|
||||
p.restore();
|
||||
// draw value
|
||||
uint64_t displayValue = _value[_sel];
|
||||
uint64_t displayIndex = 0;
|
||||
|
||||
if (_is_math)
|
||||
{
|
||||
int bbb = 0;
|
||||
bbb++;
|
||||
}
|
||||
|
||||
auto factor = get_factor();
|
||||
auto value = _value[_sel];
|
||||
uint64_t displayValue = value * factor;
|
||||
uint64_t displayIndex = 0;
|
||||
|
||||
while(displayValue / _step >= 1) {
|
||||
displayValue = displayValue / _step;
|
||||
displayValue = displayValue / _step;
|
||||
displayIndex++;
|
||||
}
|
||||
//tr
|
||||
|
||||
assert(displayIndex < _unit.count());
|
||||
|
||||
pText = QString::number(displayValue) + _unit[displayIndex] + "/div";
|
||||
|
||||
// draw +/-
|
||||
|
||||
@@ -37,7 +37,7 @@ class dslDial : public QObject
|
||||
|
||||
public:
|
||||
dslDial(const uint64_t div, const uint64_t step,
|
||||
const QVector<uint64_t> value, const QVector<QString> unit);
|
||||
const QVector<uint64_t> value, const QVector<QString> unit, bool isMath);
|
||||
virtual ~dslDial();
|
||||
|
||||
public:
|
||||
@@ -69,6 +69,10 @@ public:
|
||||
void set_factor(uint64_t factor);
|
||||
uint64_t get_factor();
|
||||
|
||||
inline bool is_math(){
|
||||
return _is_math;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t _div;
|
||||
uint64_t _step;
|
||||
@@ -76,6 +80,7 @@ private:
|
||||
QVector<QString> _unit;
|
||||
uint64_t _sel;
|
||||
uint64_t _factor;
|
||||
bool _is_math;
|
||||
};
|
||||
|
||||
} // namespace view
|
||||
|
||||
@@ -105,7 +105,7 @@ DsoSignal::DsoSignal(data::DsoSnapshot *data,
|
||||
g_variant_unref(gvar_list);
|
||||
}
|
||||
}
|
||||
_vDial = new dslDial(vValue.count(), vDialValueStep, vValue, vUnit);
|
||||
_vDial = new dslDial(vValue.count(), vDialValueStep, vValue, vUnit, false);
|
||||
_colour = SignalColours[probe->index % countof(SignalColours)];
|
||||
|
||||
load_settings();
|
||||
|
||||
@@ -97,9 +97,11 @@ int MathTrace::get_name_width()
|
||||
}
|
||||
|
||||
void MathTrace::update_vDial()
|
||||
{
|
||||
_vDial->set_value(_math_stack->default_vDialValue());
|
||||
_vDial->set_factor(_math_stack->default_factor());
|
||||
{
|
||||
auto v = _math_stack->default_vDialValue();
|
||||
auto k = _math_stack->default_factor();
|
||||
_vDial->set_value(v);
|
||||
_vDial->set_factor(k);
|
||||
}
|
||||
|
||||
void MathTrace::go_vDialPre()
|
||||
@@ -139,6 +141,11 @@ uint64_t MathTrace::get_vDialValue()
|
||||
return _vDial->get_value();
|
||||
}
|
||||
|
||||
uint64_t MathTrace::get_vDialfactor()
|
||||
{
|
||||
return _vDial->get_factor();
|
||||
}
|
||||
|
||||
uint16_t MathTrace::get_vDialSel()
|
||||
{
|
||||
return _vDial->get_sel();
|
||||
@@ -324,6 +331,7 @@ void MathTrace::paint_envelope(QPainter &p,
|
||||
QRectF *rect = rects;
|
||||
double top = get_view_rect().top();
|
||||
double bottom = get_view_rect().bottom();
|
||||
|
||||
for(uint64_t sample = 0; sample < e.length-1; sample++) {
|
||||
const float x = ((e.scale * sample + e.start) /
|
||||
samples_per_pixel - pixels_offset) + left + _view->trig_hoff()/samples_per_pixel;
|
||||
@@ -478,16 +486,26 @@ QPointF MathTrace::get_point(uint64_t index, float &value)
|
||||
const float zeroP = _zero_vrate * get_view_rect().height() + top;
|
||||
const float x = _view->index2pixel(index);
|
||||
|
||||
value = *_math_stack->get_math(index);
|
||||
float y = min(max(top, zeroP - (value * _scale)), bottom);
|
||||
float v = *_math_stack->get_math(index);
|
||||
value = v * get_vDialfactor();
|
||||
float y = min(max(top, zeroP - (v * _scale)), bottom);
|
||||
pt = QPointF(x, y);
|
||||
return pt;
|
||||
}
|
||||
|
||||
QString MathTrace::get_voltage(double v, int p)
|
||||
{
|
||||
return abs(v) >= 1 ? QString::number(v, 'f', p) + _math_stack->get_unit(1) :
|
||||
QString::number(v * 1000, 'f', p) + _math_stack->get_unit(0);
|
||||
if (abs(v) >= 1000){
|
||||
return QString::number(v / 1000, 'f', p) + _math_stack->get_unit(2);
|
||||
}
|
||||
else if (abs(v) >= 1){
|
||||
return QString::number(v, 'f', p) + _math_stack->get_unit(1);
|
||||
}
|
||||
else{
|
||||
return QString::number(v * 1000, 'f', p) + _math_stack->get_unit(0);
|
||||
}
|
||||
// return abs(v) >= 1 ? QString::number(v, 'f', p) + _math_stack->get_unit(1) :
|
||||
// QString::number(v * 1000, 'f', p) + _math_stack->get_unit(0);
|
||||
}
|
||||
|
||||
QString MathTrace::get_time(double t)
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
void go_vDialNext();
|
||||
uint64_t get_vDialValue();
|
||||
uint16_t get_vDialSel();
|
||||
uint64_t get_vDialfactor();
|
||||
|
||||
bool enabled();
|
||||
void set_enable(bool enable);
|
||||
|
||||
Reference in New Issue
Block a user