#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 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 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 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 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 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 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 &data) { if(!_measures) return; if(!_measures->count()) return; if(data.empty()) return; int meas_cnt = 0; std::vector::iterator l = data.begin() + axis_x()->min()*ad()->get_rate(); std::vector::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(&_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 x; std::vector 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(); } } } }