Add some more debugging when audio is delayed

merge-requests/9/merge
Phil Taylor 2022-05-02 11:22:05 +01:00
rodzic 2525641e76
commit bb6c615b4c
3 zmienionych plików z 64 dodań i 20 usunięć

Wyświetl plik

@ -212,9 +212,18 @@ void audioHandler::start()
audioTimer->start(setup.blockSize);
}
else {
// Buffer size must be set before audio is started.
audioOutput->setBufferSize(getAudioSize(setup.latency, format));
/* OK I don't understand what is happening here?
On Windows, I set the buffer size and when the stream is started, the buffer size is multiplied by 10?
this doesn't happen on Linux/
We want the buffer sizes to be slightly more than the setup.latency value
*/
#ifdef Q_OS_WIN
audioOutput->setBufferSize(format.bytesForDuration(setup.latency * 100));
#else
audioOutput->setBufferSize(format.bytesForDuration(setup.latency * 1000));
#endif
audioDevice = audioOutput->start();
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "bufferSize needed" << format.bytesForDuration((quint32)setup.latency * 1000) << "got" << audioOutput->bufferSize();
connect(audioOutput, &QAudioOutput::destroyed, audioDevice, &QIODevice::deleteLater, Qt::UniqueConnection);
}
if (!audioDevice) {
@ -244,6 +253,13 @@ void audioHandler::stop()
void audioHandler::setVolume(unsigned char volume)
{
/*float volumeLevelLinear = float(0.5); //cut amplitude in half
float volumeLevelDb = float(10 * (qLn(double(volumeLevelLinear)) / qLn(10)));
float volumeLinear = (volume / float(100));
this->volume = volumeLinear * float(qPow(10, (qreal(volumeLevelDb)) / 20));
this->volume = qMin(this->volume, float(1));
*/
this->volume = audiopot[volume];
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "setVolume: " << volume << "(" << this->volume << ")";
}
@ -251,7 +267,12 @@ void audioHandler::setVolume(unsigned char volume)
void audioHandler::incomingAudio(audioPacket inPacket)
{
if (lastReceived.msecsTo(QTime::currentTime()) > 30) {
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Time since last audio packet" << lastReceived.msecsTo(QTime::currentTime()) << "Expected around" << setup.blockSize;
}
lastReceived = QTime::currentTime();
audioPacket livePacket = inPacket;
// Process uLaw.
if (setup.ulaw)
@ -427,7 +448,6 @@ 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);
if (audioDevice != Q_NULLPTR) {
audioDevice->write(livePacket.data);
}
@ -437,8 +457,12 @@ void audioHandler::incomingAudio(audioPacket inPacket)
incomingAudio(inPacket); // Call myself again to run the packet a second time (FEC)
}
currentLatency = livePacket.time.msecsTo(QTime::currentTime()) + (format.durationForBytes(audioOutput->bufferSize() - audioOutput->bytesFree()) / 1000);
lastSentSeq = inPacket.seq;
}
else {
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Received audio packet is empty?";
}
emit haveLevels(getAmplitude(), setup.latency, currentLatency,isUnderrun);
@ -454,14 +478,18 @@ void audioHandler::getNextAudioChunk()
return;
}
audioPacket livePacket;
livePacket.time= QTime::currentTime();
livePacket.sent = 0;
memcpy(&livePacket.guid, setup.guid, GUIDLEN);
while (tempBuf.data.length() > format.bytesForDuration(setup.blockSize * 1000)) {
QTime startProcessing = QTime::currentTime();
livePacket.data.clear();
livePacket.data = tempBuf.data.mid(0, format.bytesForDuration(setup.blockSize * 1000));
tempBuf.data.remove(0, format.bytesForDuration(setup.blockSize * 1000));
//qDebug(logAudio()) << "Got bytes " << format.bytesForDuration(setup.blockSize * 1000);
if (livePacket.data.length() > 0)
{
Eigen::VectorXf samplesF;
@ -618,6 +646,11 @@ void audioHandler::getNextAudioChunk()
livePacket.data = outPacket; // Copy output packet back to input buffer.
}
emit haveAudioData(livePacket);
if (lastReceived.msecsTo(QTime::currentTime()) > 30) {
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Time since last audio packet" << lastReceived.msecsTo(QTime::currentTime()) << "Expected around" << setup.blockSize << "Processing time" <<startProcessing.msecsTo(QTime::currentTime());
}
lastReceived = QTime::currentTime();
//ret = livePacket.data;
}
}
@ -637,7 +670,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";
}
@ -662,18 +695,22 @@ void audioHandler::stateChanged(QAudio::State state)
{
case QAudio::IdleState:
{
isUnderrun = true;
if (underTimer->isActive()) {
underTimer->stop();
if (!setup.isinput)
{
qDebug(logAudio()) << "Output Underrun detected" << "Buffer size" << audioOutput->bufferSize() << "Bytes free" << audioOutput->bytesFree();
if (isUnderrun && audioOutput->bytesFree() > audioOutput->bufferSize()/2) {
audioOutput->suspend();
}
}
isUnderrun = true;
if (!underTimer->isActive()) {
underTimer->start(setup.latency/2);
}
break;
}
case QAudio::ActiveState:
{
//qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio started!";
if (!underTimer->isActive()) {
underTimer->start(500);
}
break;
}
case QAudio::SuspendedState:
@ -694,4 +731,8 @@ void audioHandler::clearUnderrun()
{
isUnderrun = false;
underTimer->stop();
if (!setup.isinput) {
qDebug(logAudio()) << "clearUnderrun() " << "Buffer size" << audioOutput->bufferSize() << "Bytes free" << audioOutput->bytesFree();
audioOutput->resume();
}
}

Wyświetl plik

@ -12,6 +12,7 @@
#include <QTime>
#include <QMap>
#include <QDebug>
#include <QDateTime>
/* QT Audio Headers */
#include <QAudioOutput>
@ -111,7 +112,7 @@ private:
bool isInitialized=false;
bool isReady = false;
bool audioBuffered = false;
QTime lastReceived;
QAudioOutput* audioOutput=Q_NULLPTR;
QAudioInput* audioInput=Q_NULLPTR;
QIODevice* audioDevice=Q_NULLPTR;
@ -137,7 +138,7 @@ private:
audioPacket tempBuf;
quint16 currentLatency;
float amplitude;
qreal volume=1.0;
float volume=1.0;
audioSetup setup;
@ -149,6 +150,12 @@ private:
// Various audio handling functions declared inline
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 qint64 getAudioSize(qint64 timeInMs, const QAudioFormat& format)
{
#ifdef Q_OS_LINUX
@ -169,11 +176,6 @@ 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;
@ -347,4 +349,5 @@ static inline QByteArray samplesToFloat(const QByteArray& data, const QAudioForm
return QByteArray();
}
*/
#endif // AUDIOHANDLER_H

Wyświetl plik

@ -202,7 +202,7 @@ void udpHandler::dataReceived()
}
QString tempLatency;
if (status.rxLatency > status.rxCurrentLatency && !status.rxUnderrun)
if (status.rxLatency * 1.3 > (status.rxCurrentLatency) && !status.rxUnderrun)
{
tempLatency = QString("%1 ms").arg(status.rxCurrentLatency,3);
}