From 3ac1c004e36d62c27d2172d11e18da90bc9d56d1 Mon Sep 17 00:00:00 2001 From: Phil Taylor Date: Sat, 13 Feb 2021 00:45:59 +0000 Subject: [PATCH] More TX audio fixes... --- audiohandler.cpp | 71 ++++++++++++++++++++++++++++-------------------- audiohandler.h | 2 +- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/audiohandler.cpp b/audiohandler.cpp index 6ffa93d..a856e06 100644 --- a/audiohandler.cpp +++ b/audiohandler.cpp @@ -4,14 +4,15 @@ */ #include "audiohandler.h" -static int8_t uLawEncode(int16_t number) +#define MULAW_BIAS 33 +#define MULAW_MAX 0x1fff + +qint8 uLawEncode(qint16 number) { - const uint16_t MULAW_MAX = 0x1FFF; - const uint16_t MULAW_BIAS = 33; - uint16_t mask = 0x1000; - uint8_t sign = 0; - uint8_t position = 12; - uint8_t lsb = 0; + quint16 mask = 0x1000; + quint8 sign = 0; + quint8 position = 12; + quint8 lsb = 0; if (number < 0) { number = -number; @@ -28,8 +29,25 @@ static int8_t uLawEncode(int16_t number) return (~(sign | ((position - 5) << 4) | lsb)); } +/* +qint16 uLawDecode(qint8 number) +{ + quint8 sign = 0, position = 0; + qint16 decoded = 0; + number = ~number; + if (number & 0x80) + { + number &= ~(1 << 7); + sign = -1; + } + position = ((number & 0xF0) >> 4) + 5; + decoded = ((1 << position) | ((number & 0x0F) << (position - 4)) + | (1 << (position - 5))) - MULAW_BIAS; + return (sign == 0) ? (decoded) : (-(decoded)); +} +*/ -static qint16 uLawDecode(quint8 in) +qint16 uLawDecode(quint8 in) { static const qint16 ulaw_decode[256] = { -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, @@ -69,7 +87,6 @@ static qint16 uLawDecode(quint8 in) return ulaw_decode[in]; } - audioHandler::audioHandler(QObject* parent) : QIODevice(parent), isInitialized(false), @@ -172,8 +189,8 @@ void audioHandler::reinit() if (this->isInput) { // (Re)initialize audio input - delete audioInput; - audioInput = Q_NULLPTR; + if (audioInput != Q_NULLPTR) + delete audioInput; audioInput = new QAudioInput(deviceInfo, format, this); audioInput->setBufferSize(audioBuffer); audioInput->setNotifyInterval(20); @@ -184,7 +201,8 @@ void audioHandler::reinit() } else { // (Re)initialize audio output - delete audioOutput; + if (audioOutput != Q_NULLPTR) + delete audioOutput; audioOutput = Q_NULLPTR; audioOutput = new QAudioOutput(deviceInfo, format, this); audioOutput->setBufferSize(audioBuffer); @@ -214,7 +232,6 @@ void audioHandler::start() else { this->open(QIODevice::ReadOnly); } - buffer.clear(); // No buffer used on audioinput. if (isInput) { @@ -248,9 +265,12 @@ void audioHandler::flush() void audioHandler::stop() { + QMutexLocker locker(&mutex); if (audioOutput && audioOutput->state() != QAudio::StoppedState) { // Stop audio output audioOutput->stop(); + QByteArray ret; + buffer.clear(); this->close(); } @@ -267,6 +287,7 @@ qint64 audioHandler::readData(char* data, qint64 maxlen) { // Calculate output length, always full samples int outlen = 0; + QMutexLocker locker(&mutex); if (isUlaw) { // Need to process uLaw. @@ -274,7 +295,7 @@ qint64 audioHandler::readData(char* data, qint64 maxlen) outlen = qMin(buffer.length(), (int)maxlen / 2); for (int f = 0; f < outlen; f++) { - qToLittleEndian(uLawDecode(buffer.at(f)), data + f * 2); + qToLittleEndian(uLawDecode(buffer.at(f)),data + f * 2); } buffer.remove(0, outlen); outlen = outlen * 2; @@ -285,7 +306,7 @@ qint64 audioHandler::readData(char* data, qint64 maxlen) outlen = qMin(buffer.length(), (int)maxlen/2); for (int f = 0; f < outlen; f++) { - qToLittleEndian((qint16)(buffer[f]<<8) - 32640, data + f * 2); + qToLittleEndian((qint16)(buffer[f]<<8) - 32640,data + f * 2); } buffer.remove(0, outlen); outlen = outlen * 2; @@ -305,19 +326,18 @@ qint64 audioHandler::readData(char* data, qint64 maxlen) qint64 audioHandler::writeData(const char* data, qint64 len) { - QMutexLocker locker(&mutex); + QMutexLocker locker(&mutex); if (buffer.length() > bufferSize * 4) { qWarning() << "writeData() Buffer overflow"; buffer.clear(); } - //int chunkSize = 960; // Assume 8bit or uLaw. if (isUlaw) { for (int f = 0; f < len / 2; f++) { - buffer.append(uLawEncode(qFromLittleEndian(data + f * 2))); + buffer.append((quint8)uLawEncode(qFromLittleEndian(data + f * 2))); } } else if (radioSampleBits == 8) { @@ -328,7 +348,6 @@ qint64 audioHandler::writeData(const char* data, qint64 len) } else if (radioSampleBits == 16) { buffer.append(QByteArray::fromRawData(data, len)); - //chunkSize = 1920; } else { qWarning() << "Unsupported number of bits! :" << radioSampleBits; @@ -370,21 +389,13 @@ void audioHandler::stateChanged(QAudio::State state) void audioHandler::incomingAudio(const QByteArray& data) { //qDebug() << "Got " << data.length() << " samples"; - QMutexLocker locker(&mutex); if (audioOutput != Q_NULLPTR && audioOutput->state() != QAudio::StoppedState) { - // Append input data to the end of buffer + QMutexLocker locker(&mutex); buffer.append(data); - //if (buffer.length() > bufferSize*2) { - // this->flush(); - //} - - // If audio is suspended and buffer is full, resume if (audioOutput->state() == QAudio::SuspendedState) { - if (buffer.length() >= bufferSize) { - qDebug() << this->metaObject()->className() << ": Resuming..."; - audioOutput->resume(); - } + qDebug() << "RX Audio Suspended, Resuming..."; + audioOutput->resume(); } } else { diff --git a/audiohandler.h b/audiohandler.h index 16a0eb0..6512194 100644 --- a/audiohandler.h +++ b/audiohandler.h @@ -40,11 +40,11 @@ public: qint64 writeData(const char* data, qint64 len); qint64 bytesAvailable() const; bool isSequential() const; + void incomingAudio(const QByteArray& data); QByteArray getNextAudioChunk(void); public slots: bool init(const quint8 bits, const quint8 channels, const quint16 samplerate, const quint16 bufferSize, const bool isulaw, const bool isinput); - void incomingAudio(const QByteArray& data); void changeBufferSize(const quint16 newSize); private slots: