diff --git a/audiohandler.cpp b/audiohandler.cpp index 10a7d61..2e4aa39 100644 --- a/audiohandler.cpp +++ b/audiohandler.cpp @@ -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"; } diff --git a/audiohandler.h b/audiohandler.h index cf173ae..395b126 100644 --- a/audiohandler.h +++ b/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 VectorXuint8; typedef Eigen::Matrix VectorXint8; typedef Eigen::Matrix VectorXint16; typedef Eigen::Matrix 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 samples_float = Eigen::Map(reinterpret_cast(input.data()), input.size() / int(sizeof(float))); - - Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits::max()); - - VectorXuint8 samples_int = samples_int_tmp.cast(); - - QByteArray raw = QByteArray(reinterpret_cast(samples_int.data()), int(samples_int.size()) * int(sizeof(quint8))); - - return raw; - } - case QAudioFormat::SignedInt: - { - Eigen::Ref samples_float = Eigen::Map(reinterpret_cast(input.data()), input.size() / int(sizeof(float))); - - Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits::max()); - - VectorXint8 samples_int = samples_int_tmp.cast(); - - QByteArray raw = QByteArray(reinterpret_cast(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 samples_float = Eigen::Map(reinterpret_cast(input.data()), input.size() / int(sizeof(float))); - - Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits::max()); - - VectorXint16 samples_int = samples_int_tmp.cast(); - - QByteArray raw = QByteArray(reinterpret_cast(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 samples_float = Eigen::Map(reinterpret_cast(input.data()), input.size() / int(sizeof(float))); - - Eigen::VectorXf samples_int_tmp = samples_float * float(std::numeric_limits::max()); - - VectorXint32 samples_int = samples_int_tmp.cast(); - - QByteArray raw = QByteArray(reinterpret_cast(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 samples_int = Eigen::Map(reinterpret_cast(raw.data()), raw.size() / int(sizeof(quint8))); - - Eigen::VectorXf samples_float = samples_int.cast() / float(std::numeric_limits::max()); - - return QByteArray(reinterpret_cast(samples_float.data()), int(samples_float.size()) * int(sizeof(float))); - } - case QAudioFormat::SignedInt: - { - QByteArray raw = input; - - Eigen::Ref samples_int = Eigen::Map(reinterpret_cast(raw.data()), raw.size() / int(sizeof(qint8))); - - Eigen::VectorXf samples_float = samples_int.cast() / float(std::numeric_limits::max()); - - return QByteArray(reinterpret_cast(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 samples_int = Eigen::Map(reinterpret_cast(raw.data()), raw.size() / int(sizeof(qint16))); - - Eigen::VectorXf samples_float = samples_int.cast() / float(std::numeric_limits::max()); - - return QByteArray(reinterpret_cast(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 samples_int = Eigen::Map(reinterpret_cast(raw.data()), raw.size() / int(sizeof(qint32))); - - Eigen::VectorXf samples_float = samples_int.cast() / float(std::numeric_limits::max()); - - return QByteArray(reinterpret_cast(samples_float.data()), int(samples_float.size()) * int(sizeof(float))); - } - default: - break; - } - - break; - } - default: - break; - } - - return QByteArray(); -} #endif // AUDIOHANDLER_H