test_sdk/hw/gtl_hw_recorder.cpp

225 lines
5.2 KiB
C++

#include "gtl_hw_recorder.h"
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include "core/gtl_logger.h"
namespace gtl
{
namespace hw
{
recorder::recorder(const std::vector<gtl::analog_data*> &ad, qreal time, QString comment, QString dir, QString file_name, QString extension, QObject *parent)
: QObject{parent}
, _samples(0)
, _size(0)
, _stream(nullptr)
, _file(nullptr)
, _device(nullptr)
{
QJsonArray channels;
for(auto it : ad)
{
if(_device)
{
if(_device != static_cast<gtl::device*>(it->root()))
continue;
}
else
_device = static_cast<gtl::device*>(it->root());
/*
QJsonArray ad_objects;
gtl::data_model_node* node = it;
while(node->parent_node())
{
QJsonObject node_object;
node->get_state(node_object);
ad_objects.append(node_object);
node = node->parent_node();
}
channels.append(ad_objects);
*/
QJsonObject ad_object;
get_state(ad_object, it);
channels.append(ad_object);
_ad.push_back(it);
}
if(_device == nullptr)
{
gtl::logger::warning("recorder", "nothing record");
return;
}
QJsonObject device_object;
device_object["name"] = _device->name();
device_object["rate"] = _device->rate();
device_object["channels"] = channels;
QDir dir_(dir);
dir_.mkpath(dir);
QString name = file_name + "." + extension;
int idx = 0;
while(dir_.exists(name))
{
idx++;
name = file_name + " (" + QString::number(idx) + ")." + extension;
}
QJsonDocument info;
QJsonObject root;
root["hw"] = device_object;
root["comment"] = comment;
info.setObject(root);
_path = dir_.absoluteFilePath(name);
_file = new QFile(_path);
if(!_file->open(QFile::WriteOnly))
{
delete _file;
_file = nullptr;
gtl::logger::error("recorder", "error creatig file: " + _path);
return;
}
QFile info_file(_path + ".info");
if(info_file.open(QFile::WriteOnly))
{
info_file.write(info.toJson());
info_file.close();
}
_stream = new QDataStream(_file);
_stream->setFloatingPointPrecision(QDataStream::SinglePrecision);
_stream->setByteOrder(QDataStream::LittleEndian);
_size = _device->rate()*time;
if(_size == 0)
_size -=1;
}
recorder::~recorder()
{
stop();
delete _stream;
if(_file)
delete _file;
}
void recorder::start()
{
if(_device)
connect(_device, &gtl::device::recieved_data, this, &recorder::device_recieved_data);
emit progress(0);
}
void recorder::stop()
{
if(_device)
disconnect(_device, &gtl::device::recieved_data, this, &recorder::device_recieved_data);
}
bool recorder::is_success() const
{
if(_device == nullptr)
return false;
if(_file == nullptr)
return false;
return true;
}
qreal recorder::time() const
{
return _samples/_device->rate();
}
QString recorder::path() const
{
return _path;
}
void recorder::get_state(QJsonObject &root, data_model_node *node)
{
if(node->parent_node())
{
node->get_state(root);
QJsonObject parent_object;
get_state(parent_object, node->parent_node());
if(!parent_object.isEmpty())
root.insert("parent", parent_object);
}
}
void recorder::write(qreal value)
{
*_stream << value;
}
void recorder::device_recieved_data()
{
if(_samples == _size)
return;
_device->lock_ai();
for(int i = 0; i < (int)_ad.front()->size(); i++)
{
for(auto it : _ad)
{
write(it->at(i));
}
_samples++;
if(_samples == _size)
break;
}
_device->unlock_ai();
emit progress((qreal)_samples/_size);
if(_samples == _size)
{
finish_writing();
_file->flush();
emit finished();
}
}
}
}