#include "gtl_hw_recorder.h" #include #include #include #include "core/gtl_logger.h" namespace gtl { namespace hw { recorder::recorder(const std::vector &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(it->root())) continue; } else _device = static_cast(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(); } } } }