337 lines
12 KiB
C++
337 lines
12 KiB
C++
|
#include "gtl_gui_osc_series.h"
|
||
|
|
||
|
namespace gtl
|
||
|
{
|
||
|
namespace gui
|
||
|
{
|
||
|
namespace osc
|
||
|
{
|
||
|
series::series(qreal time, bool is_updating, gtl::analog_data* ai, chart::axis_horz* axis_x, chart::axis_vert* axis_y)
|
||
|
: chart_series(ai, axis_x, axis_y)
|
||
|
, _buffer(time * ai->get_rate())
|
||
|
, _ptr(0)
|
||
|
, _time(time)
|
||
|
, _prehistory(0)
|
||
|
, _scale(1)
|
||
|
{
|
||
|
|
||
|
_is_updating = is_updating;
|
||
|
|
||
|
_measures = OscMeasParamsListPtr(new QListOscMeasParams);
|
||
|
|
||
|
connect(ai, >l::analog_data::rate_changed, this, &series::rate_changed);
|
||
|
connect(chart_series::axis_x(), &chart::axis::signal_range_changed, this, >l::gui::osc::series::handle_measure);
|
||
|
|
||
|
init();
|
||
|
|
||
|
// data_recieved();
|
||
|
}
|
||
|
|
||
|
series::~series()
|
||
|
{
|
||
|
disconnect(ad(), >l::analog_data::rate_changed, this, &series::rate_changed);
|
||
|
}
|
||
|
|
||
|
void series::set_time(qreal time)
|
||
|
{
|
||
|
if(time != _time)
|
||
|
{
|
||
|
_time = time;
|
||
|
init();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool series::update(qreal threshold, bool is_front, qreal prehistory, int& analog_data_idx)
|
||
|
{
|
||
|
_prehistory = prehistory;
|
||
|
bool is_complete = false;
|
||
|
for(int i = 0; i < (int)_ad->size(); i++)
|
||
|
{
|
||
|
_buffer[_ptr] = _ad->at(i);
|
||
|
|
||
|
if(_begin_ptr == -1)
|
||
|
{
|
||
|
|
||
|
if(
|
||
|
(is_front && _buffer[_ptr] >= threshold && _buffer[(_ptr + _buffer.size() - 1) % _buffer.size()] < threshold) ||
|
||
|
(!is_front && _buffer[_ptr] <= threshold && _buffer[(_ptr + _buffer.size() - 1) % _buffer.size()] > threshold)
|
||
|
)
|
||
|
{
|
||
|
_begin_ptr = (_ptr + qRound(_buffer.size() * (1.0 - prehistory))) % _buffer.size();
|
||
|
analog_data_idx = i;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
_ptr = (_ptr + 1) % _buffer.size();
|
||
|
|
||
|
if(_ptr == _begin_ptr)
|
||
|
{
|
||
|
if(/*!_updater.isRunning() && */_is_updating)
|
||
|
{
|
||
|
std::vector<qreal> data_buffer;
|
||
|
|
||
|
std::copy(_buffer.begin() + _begin_ptr, _buffer.end(), std::back_inserter(data_buffer));
|
||
|
std::copy(_buffer.begin(), _buffer.begin() + _begin_ptr, std::back_inserter(data_buffer));
|
||
|
measure(data_buffer);
|
||
|
_updater.set_data(data_buffer);
|
||
|
|
||
|
// _updater.start();
|
||
|
|
||
|
is_complete = true;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
_begin_ptr = -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(_is_updating&& !is_complete && _begin_ptr != -1)
|
||
|
{
|
||
|
std::vector<qreal> data_buffer(_buffer.size(), 0);
|
||
|
|
||
|
if(_ptr > _begin_ptr)
|
||
|
{
|
||
|
std::copy(_buffer.begin() + _begin_ptr, _buffer.begin() + _ptr, data_buffer.begin());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
std::copy(_buffer.begin() + _begin_ptr, _buffer.end(), data_buffer.begin());
|
||
|
std::copy(_buffer.begin(), _buffer.begin() + _ptr, data_buffer.begin() + std::distance(_buffer.begin() + _begin_ptr, _buffer.end()));
|
||
|
}
|
||
|
|
||
|
measure(data_buffer);
|
||
|
_updater.set_data(data_buffer);
|
||
|
}
|
||
|
|
||
|
return is_complete;
|
||
|
}
|
||
|
|
||
|
void series::update(int ad_idx, qreal prehistory)
|
||
|
{
|
||
|
bool is_complete = false;
|
||
|
_prehistory = prehistory;
|
||
|
for(int i = 0; i < (int)_ad->size(); i++)
|
||
|
{
|
||
|
_buffer[_ptr] = _ad->at(i);
|
||
|
|
||
|
if(_begin_ptr == -1)
|
||
|
{
|
||
|
|
||
|
if(ad_idx == i)
|
||
|
{
|
||
|
_begin_ptr = (_ptr + qRound(_buffer.size() * (1.0 - prehistory))) % _buffer.size();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
_ptr = (_ptr + 1) % _buffer.size();
|
||
|
|
||
|
if(_ptr == _begin_ptr)
|
||
|
{
|
||
|
if(/*!_updater.isRunning() && */_is_updating)
|
||
|
{
|
||
|
std::vector<qreal> data_buffer;
|
||
|
|
||
|
std::copy(_buffer.begin() + _begin_ptr, _buffer.end(), std::back_inserter(data_buffer));
|
||
|
std::copy(_buffer.begin(), _buffer.begin() + _begin_ptr, std::back_inserter(data_buffer));
|
||
|
measure(data_buffer);
|
||
|
_updater.set_data(data_buffer);
|
||
|
|
||
|
}
|
||
|
|
||
|
_begin_ptr = -1;
|
||
|
is_complete = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(_is_updating&& !is_complete && _begin_ptr != -1)
|
||
|
{
|
||
|
std::vector<qreal> data_buffer(_buffer.size(), 0);
|
||
|
|
||
|
if(_ptr > _begin_ptr)
|
||
|
{
|
||
|
std::copy(_buffer.begin() + _begin_ptr, _buffer.begin() + _ptr, data_buffer.begin());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
std::copy(_buffer.begin() + _begin_ptr, _buffer.end(), data_buffer.begin());
|
||
|
std::copy(_buffer.begin(), _buffer.begin() + _ptr, data_buffer.begin() + std::distance(_buffer.begin() + _begin_ptr, _buffer.end()));
|
||
|
}
|
||
|
|
||
|
measure(data_buffer);
|
||
|
_updater.set_data(data_buffer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool series::update_()
|
||
|
{
|
||
|
_prehistory = 0;
|
||
|
|
||
|
if(_begin_ptr == -1)
|
||
|
_begin_ptr = _ptr;
|
||
|
|
||
|
bool is_complete = false;
|
||
|
|
||
|
if(_ad->empty())
|
||
|
return false;
|
||
|
|
||
|
for(int i = 0; i < (int)_ad->size(); i++)
|
||
|
{
|
||
|
_buffer[_ptr] = _ad->at(i);
|
||
|
|
||
|
|
||
|
_ptr = (_ptr + 1) % _buffer.size();
|
||
|
|
||
|
if(_ptr == _begin_ptr)
|
||
|
{
|
||
|
if(_is_updating)
|
||
|
{
|
||
|
std::vector<qreal> data_buffer;
|
||
|
|
||
|
std::copy(_buffer.begin() + _begin_ptr, _buffer.end(), std::back_inserter(data_buffer));
|
||
|
std::copy(_buffer.begin(), _buffer.begin() + _begin_ptr, std::back_inserter(data_buffer));
|
||
|
measure(data_buffer);
|
||
|
_updater.set_data(data_buffer);
|
||
|
|
||
|
}
|
||
|
|
||
|
_begin_ptr = -1;
|
||
|
is_complete = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(_is_updating && !is_complete)
|
||
|
{
|
||
|
std::vector<qreal> data_buffer;
|
||
|
|
||
|
std::copy(_buffer.begin() + _ptr, _buffer.end(), std::back_inserter(data_buffer));
|
||
|
std::copy(_buffer.begin(), _buffer.begin() + _ptr, std::back_inserter(data_buffer));
|
||
|
measure(data_buffer);
|
||
|
_updater.set_data(data_buffer);
|
||
|
|
||
|
}
|
||
|
|
||
|
return is_complete;
|
||
|
}
|
||
|
|
||
|
void series::set_measures(meas_model *model)
|
||
|
{
|
||
|
if(!model)
|
||
|
return;
|
||
|
_measures->clear();
|
||
|
for(int i = 0; i < model->measures()->count(); i++)
|
||
|
if(model->measures()->at(i).ad == _ad)
|
||
|
_measures->append(model->measures()->at(i));
|
||
|
// qDebug() << "osc_series: set_measure";
|
||
|
measure();
|
||
|
}
|
||
|
|
||
|
void series::measure(std::vector<qreal> &data)
|
||
|
{
|
||
|
if(!_measures)
|
||
|
return;
|
||
|
|
||
|
if(!_measures->count())
|
||
|
return;
|
||
|
|
||
|
if(data.empty())
|
||
|
return;
|
||
|
|
||
|
int meas_cnt = 0;
|
||
|
std::vector<qreal>::iterator l = data.begin() + axis_x()->min()*ad()->get_rate();
|
||
|
std::vector<qreal>::iterator r = data.begin() + axis_x()->max()*ad()->get_rate();
|
||
|
for(int i = 0; i < _measures->count(); i++)
|
||
|
{
|
||
|
if(_measures->at(i).ad == _ad)
|
||
|
{
|
||
|
meas_cnt++;
|
||
|
math::osc_meas::params *p = const_cast<math::osc_meas::params *>(&_measures->at(i));
|
||
|
switch (p->type)
|
||
|
{
|
||
|
case math::osc_meas::types::min:
|
||
|
p->value = math::osc_meas::min(l, r);
|
||
|
break;
|
||
|
case math::osc_meas::types::max:
|
||
|
p->value = math::osc_meas::max(l, r);
|
||
|
break;
|
||
|
case math::osc_meas::types::offset:
|
||
|
p->value = math::osc_meas::offset(l, r);
|
||
|
break;
|
||
|
case math::osc_meas::types::peak:
|
||
|
p->value = math::osc_meas::peak(l, r);
|
||
|
break;
|
||
|
case math::osc_meas::types::peak_to_peak:
|
||
|
p->value = math::osc_meas::peak_to_peak(l, r);
|
||
|
break;
|
||
|
case math::osc_meas::types::rms:
|
||
|
p->value = math::osc_meas::rms(l, r);
|
||
|
break;
|
||
|
case math::osc_meas::types::freq:
|
||
|
p->value = math::osc_meas::freq(l, r, ad()->get_rate());
|
||
|
break;
|
||
|
case math::osc_meas::types::period:
|
||
|
p->value = math::osc_meas::period(l, r, ad()->get_rate());
|
||
|
break;
|
||
|
case math::osc_meas::types::kurt:
|
||
|
p->value = math::osc_meas::kurt(l, r);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(meas_cnt)
|
||
|
emit measures_changed(_measures);
|
||
|
}
|
||
|
|
||
|
void series::measure()
|
||
|
{
|
||
|
if(!_measures)
|
||
|
return;
|
||
|
|
||
|
if(!_measures->count())
|
||
|
return;
|
||
|
|
||
|
std::vector<qreal> x;
|
||
|
std::vector<qreal> y;
|
||
|
xy::get_values_arrays(std::back_inserter(x), std::back_inserter(y));
|
||
|
measure(y);
|
||
|
}
|
||
|
|
||
|
void series::init()
|
||
|
{
|
||
|
_updater.stop();
|
||
|
|
||
|
|
||
|
_ad->lock_device();
|
||
|
|
||
|
_buffer.resize(_time * _ad->get_rate());
|
||
|
std::fill(_buffer.begin(), _buffer.end(), 0);
|
||
|
_ptr = 0;
|
||
|
_begin_ptr = -1;
|
||
|
set_y(&_buffer[0], (int)_buffer.size(), 1/_ad->get_rate()*_scale);
|
||
|
|
||
|
_ad->unlock_device();
|
||
|
}
|
||
|
|
||
|
void series::data_recieved()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
void series::rate_changed()
|
||
|
{
|
||
|
init();
|
||
|
}
|
||
|
|
||
|
void series::handle_measure()
|
||
|
{
|
||
|
measure();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|