test_sdk/math/gtl_math_cross_spec.cpp

335 lines
9.2 KiB
C++

#include "gtl_math_cross_spec.h"
namespace gtl {
namespace math {
cross_spec::cross_spec(gtl::analog_data *ref, gtl::analog_data *data) :
_is_acq(true),
_av(1),
_av_cnt(0),
_av_filled(false),
_threshold(50),
_ref(nullptr),
_data(nullptr)
{
_device = static_cast<gtl::device*>(data->root());
if(_device)
_device->lock_ai();
_ref = new gtl::math::fft(ref);
_data = new gtl::math::fft(data);
connect(_device, &gtl::device::recieved_data, this, &gtl::math::cross_spec::device_recieved_data);
connect(_data, &gtl::math::fft::initialized, this, &cross_spec::init);
connect(_data, &gtl::math::fft::frequency_changed, this, &cross_spec::frequency_changed);
connect(_data, &gtl::math::fft::resolution_changed, this, &cross_spec::resolution_changed);
connect(_data, &gtl::math::fft::window_changed, this, &cross_spec::window_changed);
connect(_data, &gtl::math::fft::lines_changed, this, &cross_spec::lines_changed);
connect(_data, &gtl::math::fft::overlap_changed, this, &cross_spec::overlap_changed);
init();
if(_device)
_device->unlock_ai();
}
cross_spec::~cross_spec()
{
emit deleting();
cleanup();
if(_ref)
delete _ref;
if(_data)
delete _data;
}
void cross_spec::set_ref(analog_data *ref)
{
if(_device)
_device->lock_ai();
if(_ref)
delete _ref;
_ref = new gtl::math::fft(ref);
_ref->set_frequency(_data->frequency());
_ref->set_resolution(_data->resolution());
_ref->set_overlap(_data->overlap());
_ref->set_window(_data->window());
init();
if(_device)
_device->unlock_ai();
}
void cross_spec::set_data(analog_data *data)
{
_device = static_cast<gtl::device*>(data->root());
if(_device)
_device->lock_ai();
disconnect(_device, &gtl::device::recieved_data, this, &gtl::math::cross_spec::device_recieved_data);
disconnect(_data, &gtl::math::fft::initialized, this, &cross_spec::init);
disconnect(_data, &gtl::math::fft::frequency_changed, this, &cross_spec::frequency_changed);
disconnect(_data, &gtl::math::fft::resolution_changed, this, &cross_spec::resolution_changed);
disconnect(_data, &gtl::math::fft::window_changed, this, &cross_spec::window_changed);
disconnect(_data, &gtl::math::fft::lines_changed, this, &cross_spec::lines_changed);
disconnect(_data, &gtl::math::fft::overlap_changed, this, &cross_spec::overlap_changed);
if(_data)
delete _data;
_data = new gtl::math::fft(data);
_data->set_frequency(_ref->frequency());
_data->set_resolution(_ref->resolution());
_data->set_overlap(_ref->overlap());
_data->set_window(_ref->window());
connect(_device, &gtl::device::recieved_data, this, &gtl::math::cross_spec::device_recieved_data);
connect(_data, &gtl::math::fft::initialized, this, &gtl::math::cross_spec::init);
connect(_data, &gtl::math::fft::frequency_changed, this, &gtl::math::cross_spec::frequency_changed);
connect(_data, &gtl::math::fft::resolution_changed, this, &gtl::math::cross_spec::resolution_changed);
connect(_data, &gtl::math::fft::window_changed, this, &gtl::math::cross_spec::window_changed);
connect(_data, &gtl::math::fft::lines_changed, this, &gtl::math::cross_spec::lines_changed);
connect(_data, &gtl::math::fft::overlap_changed, this, &gtl::math::cross_spec::overlap_changed);
init();
if(_device)
_device->unlock_ai();
}
qreal cross_spec::frequency() const
{
return _data->frequency();
}
void cross_spec::set_frequency(qreal value)
{
_ref->set_frequency(value);
_data->set_frequency(value);
init();
}
qreal cross_spec::resolution() const
{
return _data->resolution();
}
void cross_spec::set_resolution(qreal value)
{
_ref->set_resolution(value);
_data->set_resolution(value);
init();
}
cross_spec::windows cross_spec::window() const
{
return (cross_spec::windows) _data->window();
}
void cross_spec::set_window(windows value)
{
_ref->set_window((fft::windows) value);
_data->set_window((fft::windows) value);
}
int cross_spec::lines() const
{
return _data->lines();
}
void cross_spec::set_lines(int value)
{
_ref->set_lines(value);
_data->set_lines(value);
init();
}
uint cross_spec::average() const
{
return _av;
}
void cross_spec::set_average(int value)
{
if( value != _av && value > 0)
{
_av = value;
init();
emit average_changed();
}
}
qreal cross_spec::overlap() const
{
return _data->overlap();
}
void cross_spec::set_overlap(int value)
{
_ref->set_overlap(value);
_data->set_overlap(value);
}
// units cross_spec::unit() const
// {
// return _un;
// }
// void cross_spec::set_unit(units value)
// {
// if( value != _un )
// {
// _un = value;
// emit unit_changed();
// }
// }
analog_data *cross_spec::ad() const
{
return _data->ad();
}
qreal cross_spec::acq_time() const
{
int nl = _data->lines();
qreal f = _data->frequency();
qreal ol = _data->overlap();
return (nl + 1)/f * ((_av - 1)* (1.0 - ol/100.0) + 1);
}
void cross_spec::calculate()
{
for(int i = 0; i < _size_fft_out; i++)
*(_calculated_it + i) = abs(_ref->at(i)*std::conj(_data->at(i)))/_size_fft_calc/_size_fft_calc;
}
void cross_spec::before_updating()
{
}
void cross_spec::after_updating()
{
}
void cross_spec::device_recieved_data()
{
if(_ref->samples() != _data->samples())
return;
if(_device)
_device->lock_ai();
before_updating();
// Вычисление , усреднение
int avdiv = _av_filled ? _av : _av_cnt + 1;
if( _av > 1 )
_calculated_it = _buffer_out[_av_cnt]->begin();
else
_calculated_it = begin();
calculate();
if( _av > 1 )
{
for(int i = 0; i < _size_fft_out; i++)
{
qreal value = 0;
for(int j = 0; j < avdiv; j++)
value += _buffer_out[j]->at(i)/avdiv;
at(i) = value;
}
}
_av_cnt++;
_ac = 100. * ( (qreal) _av_cnt )/_av;
emit acquired(_ac);
if(_av_cnt == _av)
{
_av_cnt = 0;
_av_filled = true;
}
after_updating();
if(_device)
_device->unlock_ai();
emit changed();
}
void cross_spec::cleanup()
{
if(_device)
_device->lock_ai();
for(std::vector<qreal>* ptr:_buffer_out)
{
if( ptr )
{
ptr->clear();
ptr->shrink_to_fit();
delete ptr;
}
}
_buffer_out.clear();
_buffer_out.shrink_to_fit();
clear();
shrink_to_fit();
if(_device)
_device->unlock_ai();
}
void cross_spec::init()
{
if(_device)
_device->lock_ai();
cleanup();
_size_fft_out = std::min(_data->size_fft_out(), _ref->size_fft_out());
_size_fft_calc = std::min(_data->size_fft_calc(), _ref->size_fft_calc());
_av_cnt = 0;
_av_filled = false;
for(int i = 0; i < _av; i++)
_buffer_out.push_back(new std::vector<qreal>(_size_fft_out));
_calculated_it = _buffer_out[0]->begin();
resize(_size_fft_out);
if(_device)
_device->unlock_ai();
emit initialized();
emit acq_time_changed();
}
void cross_spec::stop_acq()
{
_is_acq = false;
}
} // namespace math
} // namespace gtl