335 lines
9.2 KiB
C++
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, >l::device::recieved_data, this, >l::math::cross_spec::device_recieved_data);
|
|
connect(_data, >l::math::fft::initialized, this, &cross_spec::init);
|
|
connect(_data, >l::math::fft::frequency_changed, this, &cross_spec::frequency_changed);
|
|
connect(_data, >l::math::fft::resolution_changed, this, &cross_spec::resolution_changed);
|
|
connect(_data, >l::math::fft::window_changed, this, &cross_spec::window_changed);
|
|
connect(_data, >l::math::fft::lines_changed, this, &cross_spec::lines_changed);
|
|
connect(_data, >l::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, >l::device::recieved_data, this, >l::math::cross_spec::device_recieved_data);
|
|
disconnect(_data, >l::math::fft::initialized, this, &cross_spec::init);
|
|
disconnect(_data, >l::math::fft::frequency_changed, this, &cross_spec::frequency_changed);
|
|
disconnect(_data, >l::math::fft::resolution_changed, this, &cross_spec::resolution_changed);
|
|
disconnect(_data, >l::math::fft::window_changed, this, &cross_spec::window_changed);
|
|
disconnect(_data, >l::math::fft::lines_changed, this, &cross_spec::lines_changed);
|
|
disconnect(_data, >l::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, >l::device::recieved_data, this, >l::math::cross_spec::device_recieved_data);
|
|
connect(_data, >l::math::fft::initialized, this, >l::math::cross_spec::init);
|
|
connect(_data, >l::math::fft::frequency_changed, this, >l::math::cross_spec::frequency_changed);
|
|
connect(_data, >l::math::fft::resolution_changed, this, >l::math::cross_spec::resolution_changed);
|
|
connect(_data, >l::math::fft::window_changed, this, >l::math::cross_spec::window_changed);
|
|
connect(_data, >l::math::fft::lines_changed, this, >l::math::cross_spec::lines_changed);
|
|
connect(_data, >l::math::fft::overlap_changed, this, >l::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
|
|
|