142 lines
3.5 KiB
C++
142 lines
3.5 KiB
C++
|
#include "gtl_hw_audio.h"
|
||
|
|
||
|
namespace gtl
|
||
|
{
|
||
|
namespace hw
|
||
|
{
|
||
|
audio::audio(int channels, QAudioFormat::SampleFormat sample_format, QObject *parent)
|
||
|
: device{parent}
|
||
|
, _sample_format(sample_format)
|
||
|
, _audio_input(NULL)
|
||
|
{
|
||
|
_count_ai = channels;
|
||
|
|
||
|
_audio_device = new audio_input_device(this);
|
||
|
_audio_device->open(QIODevice::WriteOnly);
|
||
|
|
||
|
}
|
||
|
|
||
|
audio::~audio()
|
||
|
{
|
||
|
stop();
|
||
|
}
|
||
|
|
||
|
QString audio::type() const
|
||
|
{
|
||
|
return "audio";
|
||
|
}
|
||
|
|
||
|
bool audio::start(QString id, qreal rate)
|
||
|
{
|
||
|
_rate = rate;
|
||
|
_id = id;
|
||
|
|
||
|
const auto audio_inputs = QMediaDevices::audioInputs();
|
||
|
|
||
|
auto iter = std::find_if(audio_inputs.begin(), audio_inputs.end(), [=](const QAudioDevice &device){return QString(device.id()) == id;});
|
||
|
|
||
|
QString name;
|
||
|
|
||
|
if(iter == audio_inputs.end())
|
||
|
name = tr("unknown device");
|
||
|
else
|
||
|
{
|
||
|
name = iter->description();
|
||
|
|
||
|
|
||
|
_format.setSampleRate(_rate);
|
||
|
_format.setChannelCount(_count_ai);
|
||
|
_format.setSampleFormat(_sample_format);
|
||
|
|
||
|
if(_audio_input != NULL)
|
||
|
delete _audio_input;
|
||
|
|
||
|
_audio_input = new QAudioSource(_format);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
set_ai();
|
||
|
|
||
|
_device->set_name(tr("audio") + "[" + name + "]");
|
||
|
_device->set_id(id);
|
||
|
_device->set_rate(rate);
|
||
|
|
||
|
_is_continue = true;
|
||
|
|
||
|
|
||
|
|
||
|
// _buffer->seek(0);
|
||
|
_audio_device->set_buffer(_rate, _format.bytesPerFrame());
|
||
|
_audio_input->start(_audio_device);
|
||
|
|
||
|
QThread::start(QThread::HighestPriority);
|
||
|
|
||
|
emit status_changed(OK);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool audio::stop()
|
||
|
{
|
||
|
_is_continue = false;
|
||
|
wait();
|
||
|
if(_audio_input)
|
||
|
{
|
||
|
delete _audio_input;
|
||
|
_audio_input = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void audio::run()
|
||
|
{
|
||
|
std::vector<char> buffer;
|
||
|
std::vector<qreal> buffer_recv;
|
||
|
int sample_bytes = _format.bytesPerSample();
|
||
|
|
||
|
while(_is_continue)
|
||
|
{
|
||
|
buffer.clear();
|
||
|
_audio_device->get_data(std::back_inserter(buffer));
|
||
|
|
||
|
|
||
|
if(!buffer.empty())
|
||
|
{
|
||
|
buffer_recv.clear();
|
||
|
for(int i = 0; i < buffer.size(); i += sample_bytes)
|
||
|
{
|
||
|
float value = _format.normalizedSampleValue(&buffer[i]);
|
||
|
buffer_recv.push_back(value);
|
||
|
}
|
||
|
|
||
|
set_ai_data(&buffer_recv[0], (int)buffer_recv.size());
|
||
|
|
||
|
emit received_data();
|
||
|
|
||
|
// _buffer->seek(0);
|
||
|
|
||
|
// qDebug() << "recieved data";
|
||
|
}
|
||
|
|
||
|
msleep(100);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void audio::save(QDomElement &root_element)
|
||
|
{
|
||
|
device::save(root_element);
|
||
|
root_element.setAttribute("sample_format", _sample_format);
|
||
|
}
|
||
|
|
||
|
void audio::load(const QDomElement &root_element)
|
||
|
{
|
||
|
device::load(root_element);
|
||
|
_sample_format = (QAudioFormat::SampleFormat)root_element.attribute("sample_format", QString::number(_sample_format)).toInt();
|
||
|
}
|
||
|
}
|
||
|
}
|