kopia lustrzana https://gitlab.com/eliggett/wfview
Use notify instead of timer for audio input
rodzic
fb0d662b40
commit
7bf2f54255
|
@ -145,10 +145,13 @@ bool audioHandler::init(audioSetup setupIn)
|
|||
|
||||
if (setup.isinput) {
|
||||
audioInput = new QAudioInput(setup.port, format, this);
|
||||
audioInput->setNotifyInterval(setup.blockSize);
|
||||
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Starting audio timer";
|
||||
audioTimer = new QTimer();
|
||||
audioTimer->setTimerType(Qt::PreciseTimer);
|
||||
connect(audioTimer, &QTimer::timeout, this, &audioHandler::getNextAudioChunk);
|
||||
|
||||
//audioTimer = new QTimer();
|
||||
//audioTimer->setTimerType(Qt::PreciseTimer);
|
||||
//connect(audioTimer, &QTimer::timeout, this, &audioHandler::getNextAudioChunk);
|
||||
connect(audioInput, SIGNAL(notify()), this, SLOT(getNextAudioChunk()),Qt::DirectConnection);
|
||||
|
||||
connect(audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
|
||||
}
|
||||
|
@ -209,11 +212,16 @@ void audioHandler::start()
|
|||
audioDevice = audioInput->start();
|
||||
connect(audioInput, &QAudioInput::destroyed, audioDevice, &QIODevice::deleteLater, Qt::UniqueConnection);
|
||||
//connect(audioDevice, &QIODevice::readyRead, this, &audioHandler::getNextAudioChunk);
|
||||
audioTimer->start(setup.blockSize);
|
||||
//audioTimer->start(setup.blockSize);
|
||||
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Notify interval set to" << audioInput->notifyInterval() << "requested" << setup.blockSize;
|
||||
}
|
||||
else {
|
||||
// Buffer size must be set before audio is started.
|
||||
audioOutput->setBufferSize(getAudioSize(setup.latency, format));
|
||||
#ifdef Q_OS_WIN
|
||||
audioOutput->setBufferSize(format.bytesForDuration(setup.latency * 100));
|
||||
#else
|
||||
audioOutput->setBufferSize(format.bytesForDuration(setup.latency * 1000));
|
||||
#endif
|
||||
audioDevice = audioOutput->start();
|
||||
connect(audioOutput, &QAudioOutput::destroyed, audioDevice, &QIODevice::deleteLater, Qt::UniqueConnection);
|
||||
}
|
||||
|
@ -236,7 +244,7 @@ void audioHandler::stop()
|
|||
|
||||
if (audioInput != Q_NULLPTR && audioInput->state() != QAudio::StoppedState) {
|
||||
// Stop audio output
|
||||
audioTimer->stop();
|
||||
//audioTimer->stop();
|
||||
audioInput->stop();
|
||||
}
|
||||
audioDevice = Q_NULLPTR;
|
||||
|
@ -428,7 +436,7 @@ void audioHandler::incomingAudio(audioPacket inPacket)
|
|||
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Unsupported Sample Type:" << format.sampleType();
|
||||
}
|
||||
|
||||
currentLatency = livePacket.time.msecsTo(QTime::currentTime()) + getAudioDuration(audioOutput->bufferSize()-audioOutput->bytesFree(),format);
|
||||
currentLatency = livePacket.time.msecsTo(QTime::currentTime()) + (format.durationForBytes(audioOutput->bufferSize()-audioOutput->bytesFree())/1000);
|
||||
if (audioDevice != Q_NULLPTR) {
|
||||
audioDevice->write(livePacket.data);
|
||||
if (lastReceived.msecsTo(QTime::currentTime()) > 50) {
|
||||
|
@ -648,7 +656,7 @@ void audioHandler::changeLatency(const quint16 newSize)
|
|||
stop();
|
||||
start();
|
||||
}
|
||||
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Configured latency: " << setup.latency << "Buffer Duration:" << getAudioDuration(audioOutput->bufferSize(), format) << "ms";
|
||||
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Configured latency: " << setup.latency << "Buffer Duration:" << format.durationForBytes(audioOutput->bufferSize())/1000 << "ms";
|
||||
|
||||
}
|
||||
|
||||
|
|
193
audiohandler.h
193
audiohandler.h
|
@ -149,202 +149,9 @@ private:
|
|||
|
||||
// Various audio handling functions declared inline
|
||||
|
||||
static inline qint64 getAudioSize(qint64 timeInMs, const QAudioFormat& format)
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
qint64 value = qint64(qCeil(format.channelCount() * (format.sampleSize() / 8) * format.sampleRate() / qreal(1000) * timeInMs));
|
||||
#else
|
||||
qint64 value = qint64(qCeil(format.channelCount() * (format.sampleSize() / 8) * format.sampleRate() / qreal(10000) * timeInMs));
|
||||
#endif
|
||||
|
||||
|
||||
if (value % (format.channelCount() * (format.sampleSize() / 8)) != 0)
|
||||
value += (format.channelCount() * (format.sampleSize() / 8) - value % (format.channelCount() * (format.sampleSize() / 8)));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline qint64 getAudioDuration(qint64 bytes, const QAudioFormat& format)
|
||||
{
|
||||
return qint64(qFloor(bytes / (format.channelCount() * (format.sampleSize() / 8) * format.sampleRate() / qreal(1000))));
|
||||
}
|
||||
|
||||
typedef Eigen::Matrix<quint8, Eigen::Dynamic, 1> VectorXuint8;
|
||||
typedef Eigen::Matrix<qint8, Eigen::Dynamic, 1> VectorXint8;
|
||||
typedef Eigen::Matrix<qint16, Eigen::Dynamic, 1> VectorXint16;
|
||||
typedef Eigen::Matrix<qint32, Eigen::Dynamic, 1> VectorXint32;
|
||||
|
||||
static inline QByteArray samplesToInt(const QByteArray& data, const QAudioFormat& supported_format)
|
||||
{
|
||||
QByteArray input = data;
|
||||
|
||||
switch (supported_format.sampleSize())
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
switch (supported_format.sampleType())
|
||||
{
|
||||
case QAudioFormat::UnSignedInt:
|
||||
{
|
||||
Eigen::Ref<Eigen::VectorXf> samples_float = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(input.data()), input.size() / int(sizeof(float)));
|
||||
|
||||
Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits<quint8>::max());
|
||||
|
||||
VectorXuint8 samples_int = samples_int_tmp.cast<quint8>();
|
||||
|
||||
QByteArray raw = QByteArray(reinterpret_cast<char*>(samples_int.data()), int(samples_int.size()) * int(sizeof(quint8)));
|
||||
|
||||
return raw;
|
||||
}
|
||||
case QAudioFormat::SignedInt:
|
||||
{
|
||||
Eigen::Ref<Eigen::VectorXf> samples_float = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(input.data()), input.size() / int(sizeof(float)));
|
||||
|
||||
Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits<qint8>::max());
|
||||
|
||||
VectorXint8 samples_int = samples_int_tmp.cast<qint8>();
|
||||
|
||||
QByteArray raw = QByteArray(reinterpret_cast<char*>(samples_int.data()), int(samples_int.size()) * int(sizeof(qint8)));
|
||||
|
||||
return raw;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
{
|
||||
switch (supported_format.sampleType())
|
||||
{
|
||||
case QAudioFormat::SignedInt:
|
||||
{
|
||||
Eigen::Ref<Eigen::VectorXf> samples_float = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(input.data()), input.size() / int(sizeof(float)));
|
||||
|
||||
Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits<qint16>::max());
|
||||
|
||||
VectorXint16 samples_int = samples_int_tmp.cast<qint16>();
|
||||
|
||||
QByteArray raw = QByteArray(reinterpret_cast<char*>(samples_int.data()), int(samples_int.size()) * int(sizeof(qint16)));
|
||||
|
||||
return raw;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 32:
|
||||
{
|
||||
switch (supported_format.sampleType())
|
||||
{
|
||||
case QAudioFormat::SignedInt:
|
||||
{
|
||||
Eigen::Ref<Eigen::VectorXf> samples_float = Eigen::Map<Eigen::VectorXf>(reinterpret_cast<float*>(input.data()), input.size() / int(sizeof(float)));
|
||||
|
||||
Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits<qint32>::max());
|
||||
|
||||
VectorXint32 samples_int = samples_int_tmp.cast<qint32>();
|
||||
|
||||
QByteArray raw = QByteArray(reinterpret_cast<char*>(samples_int.data()), int(samples_int.size()) * int(sizeof(qint32)));
|
||||
|
||||
return raw;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
static inline QByteArray samplesToFloat(const QByteArray& data, const QAudioFormat& supported_format)
|
||||
{
|
||||
QByteArray input = data;
|
||||
|
||||
switch (supported_format.sampleSize())
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
switch (supported_format.sampleType())
|
||||
{
|
||||
case QAudioFormat::UnSignedInt:
|
||||
{
|
||||
QByteArray raw = input;
|
||||
|
||||
Eigen::Ref<VectorXuint8> samples_int = Eigen::Map<VectorXuint8>(reinterpret_cast<quint8*>(raw.data()), raw.size() / int(sizeof(quint8)));
|
||||
|
||||
Eigen::VectorXf samples_float = samples_int.cast<float>() / float(std::numeric_limits<quint8>::max());
|
||||
|
||||
return QByteArray(reinterpret_cast<char*>(samples_float.data()), int(samples_float.size()) * int(sizeof(float)));
|
||||
}
|
||||
case QAudioFormat::SignedInt:
|
||||
{
|
||||
QByteArray raw = input;
|
||||
|
||||
Eigen::Ref<VectorXint8> samples_int = Eigen::Map<VectorXint8>(reinterpret_cast<qint8*>(raw.data()), raw.size() / int(sizeof(qint8)));
|
||||
|
||||
Eigen::VectorXf samples_float = samples_int.cast<float>() / float(std::numeric_limits<qint8>::max());
|
||||
|
||||
return QByteArray(reinterpret_cast<char*>(samples_float.data()), int(samples_float.size()) * int(sizeof(float)));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
{
|
||||
switch (supported_format.sampleType())
|
||||
{
|
||||
case QAudioFormat::SignedInt:
|
||||
{
|
||||
QByteArray raw = input;
|
||||
|
||||
Eigen::Ref<VectorXint16> samples_int = Eigen::Map<VectorXint16>(reinterpret_cast<qint16*>(raw.data()), raw.size() / int(sizeof(qint16)));
|
||||
|
||||
Eigen::VectorXf samples_float = samples_int.cast<float>() / float(std::numeric_limits<qint16>::max());
|
||||
|
||||
return QByteArray(reinterpret_cast<char*>(samples_float.data()), int(samples_float.size()) * int(sizeof(float)));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 32:
|
||||
{
|
||||
switch (supported_format.sampleType())
|
||||
{
|
||||
case QAudioFormat::SignedInt:
|
||||
{
|
||||
QByteArray raw = input;
|
||||
|
||||
Eigen::Ref<VectorXint32> samples_int = Eigen::Map<VectorXint32>(reinterpret_cast<qint32*>(raw.data()), raw.size() / int(sizeof(qint32)));
|
||||
|
||||
Eigen::VectorXf samples_float = samples_int.cast<float>() / float(std::numeric_limits<qint32>::max());
|
||||
|
||||
return QByteArray(reinterpret_cast<char*>(samples_float.data()), int(samples_float.size()) * int(sizeof(float)));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QByteArray();
|
||||
}
|
||||
#endif // AUDIOHANDLER_H
|
||||
|
|
Ładowanie…
Reference in New Issue