227 lines
7.8 KiB
C++
227 lines
7.8 KiB
C++
|
#include "gtl_hw_player_file_gtr.h"
|
||
|
#include "qjsonarray.h"
|
||
|
|
||
|
#include <QTextCodec>
|
||
|
|
||
|
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<float> 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<float> 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;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|