225 lines
5.2 KiB
C++
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, >l::device::recieved_data, this, &recorder::device_recieved_data);
|
||
|
|
||
|
emit progress(0);
|
||
|
|
||
|
}
|
||
|
|
||
|
void recorder::stop()
|
||
|
{
|
||
|
if(_device)
|
||
|
disconnect(_device, >l::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();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|