#include "gtl_hw_player_file_gtr.h" #include "qjsonarray.h" #include namespace gtl { namespace hw { player_file_gtr::player_file_gtr(QObject *parent, QString path) : player_file(parent, path) { if (_stream == NULL) return; _stream->setFloatingPointPrecision(QDataStream::SinglePrecision); QByteArray header; QDomDocument doc; *_stream >> header; QTextCodec *codec = QTextCodec::codecForName("Windows-1251"); header = header.replace("windows-1251", "UTF-8"); QString error_msg; int error_line, error_column; if (doc.setContent(/*QString(header).toUtf8()*/codec->toUnicode(header), false, &error_msg, &error_line, &error_column)) { QDomElement root = doc.firstChildElement("gtr_header"); if (!root.isNull()) { _device = root.attribute("device", ""); _rate = root.attribute("rate", "0").toDouble(); _time = root.attribute("time", 0).toDouble(); _comment = root.attribute("comment", ""); _freq = root.attribute("freq", "0"); _data["comment"] = _comment; QJsonObject hw_object; hw_object["name"] = _device; hw_object["rate"] = _rate; _element_device = root.firstChildElement("recorder"); if (!_element_device.isNull()) { QDomElement element_child_input = _element_device.firstChildElement("input"); QJsonArray channels_array; while (!element_child_input.isNull()) { QJsonObject channel_object; channel_object["color"] = element_child_input.attribute("color", "0").toInt(); channel_object["gain"] = element_child_input.attribute("gain", "1").toDouble(); channel_object["is_coupling"] = element_child_input.attribute("coupling", "0").toInt() == 1; channel_object["is_iepe"] = element_child_input.attribute("iepe", "0").toInt() == 1; channel_object["is_inverting"] = false; channel_object["name"] = element_child_input.attribute("name", "input_" + QString::number(channels_array.size())); channel_object["node"] = "gtl::analog_input"; channel_object["offset"] = element_child_input.attribute("offset", "0").toDouble(); channel_object["reference"] = element_child_input.attribute("reference", "1").toDouble(); channel_object["sensitivity"] = element_child_input.attribute("sensitivity", "1").toDouble(); channel_object["unit"] = element_child_input.attribute("unit", ""); channels_array.append(channel_object); element_child_input = element_child_input.nextSiblingElement("input"); } hw_object.insert("channels", channels_array); _data.insert("hw", hw_object); _channels = channels_array.size(); _time = 1.0 / _rate * (_file->size() - _file->pos()) / sizeof(float) / channels(); _pos_data = _file->pos(); _info += tr("device:") + " " + _device + ";\r\n"; _info += tr("rate:") + " " + QString::number(_rate, 'f', 0) + tr(" hz") + ";\r\n"; _info += tr("time:") + " " + QString::number(_time) + tr(" sec") + ";\r\n"; _info += "\r\n" + _comment; _time = 1.0 / _rate * (_file->size() - _file->pos()) / sizeof(float) / channels(); if (channels() == 0) _time = 0; _pos_data = _file->pos(); _is_ok = true; return; } } } else qDebug() << error_line; _is_ok = false; } player_file_gtr::~player_file_gtr() { } bool player_file_gtr::get_data(qreal *data, int &samples, bool is_cyclic, bool &is_continued) { int smps = 0; std::vector buffer(samples * channels()); while (smps < samples) { int smps_to_end = (_file->size() - _file->pos()) / sizeof(float) / channels(); if (smps_to_end < (samples - smps)) { int bytes = _stream->readRawData((char*)&buffer[smps*channels()], smps_to_end*channels()*sizeof(float)); if (bytes <= 0) { samples = smps; _mutex.unlock(); return false; } smps += bytes / channels() / sizeof(float); _file->seek(_pos_data); if (!is_cyclic) { samples = smps; is_continued = false; break; } } else { int bytes = _stream->readRawData((char*)&buffer[smps*channels()], (samples - smps)*channels()*sizeof(float)); if (bytes <= 0) { samples = smps; _mutex.unlock(); return false; } smps += bytes / channels() / sizeof(float); } } std::copy(buffer.begin(), buffer.end(), &data[0]); return true; } bool player_file_gtr::get_data(qreal *data, int& idx, int &samples, bool is_cyclic /*= false*/) { _mutex.lock(); int smps = 0; _file->seek(_pos_data + idx*channels()*sizeof(float)); std::vector buffer(samples * channels()); while (smps < samples) { int smps_to_end = (_file->size() - _file->pos()) / sizeof(float) / channels(); if (smps_to_end < (samples - smps)) { int bytes = _stream->readRawData((char*)&buffer[smps*channels()], smps_to_end*channels()*sizeof(float)); if (bytes < 0) return false; smps += bytes / channels() / sizeof(float); if (!is_cyclic) { samples = smps; break; } else _file->seek(_pos_data); } else { int bytes = _stream->readRawData((char*)&buffer[smps*channels()], (samples - smps)*channels()*sizeof(float)); if (bytes < 0) return false; smps += bytes / channels() / sizeof(float); } } std::copy(buffer.begin(), buffer.end(), &data[0]); bool is_compete = _file->pos() == _file->size(); if (is_compete) seek_to_start(); idx = (_file->pos() - _pos_data) / sizeof(float) / channels(); _mutex.unlock(); return is_compete && !is_cyclic; } QString player_file_gtr::comment() const { return _comment; } QString player_file_gtr::getFreq() const { return _freq; } } }