diff --git a/audiohandler.cpp b/audiohandler.cpp index a856e06..2c3809d 100644 --- a/audiohandler.cpp +++ b/audiohandler.cpp @@ -47,7 +47,7 @@ qint16 uLawDecode(qint8 number) } */ -qint16 uLawDecode(quint8 in) +qint16 uLawDecode(const quint8 in) { static const qint16 ulaw_decode[256] = { -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, @@ -82,8 +82,6 @@ qint16 uLawDecode(quint8 in) 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0 }; - if (in == 0x02) // MUZERO - in = 0; return ulaw_decode[in]; } @@ -183,8 +181,8 @@ void audioHandler::reinit() // Calculate the minimum required audio buffer // This may need work depending on how it performs on other platforms. - int audioBuffer = format.sampleRate() / 10; - audioBuffer = audioBuffer * (format.sampleSize() / 8); + //int audioBuffer = format.sampleRate() / 10; + //audioBuffer = audioBuffer * (format.sampleSize() / 8); if (this->isInput) { @@ -192,8 +190,8 @@ void audioHandler::reinit() if (audioInput != Q_NULLPTR) delete audioInput; audioInput = new QAudioInput(deviceInfo, format, this); - audioInput->setBufferSize(audioBuffer); - audioInput->setNotifyInterval(20); + //audioInput->setBufferSize(audioBuffer); + //audioInput->setNotifyInterval(20); connect(audioInput, SIGNAL(notify()), SLOT(notified())); connect(audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State))); @@ -205,7 +203,7 @@ void audioHandler::reinit() delete audioOutput; audioOutput = Q_NULLPTR; audioOutput = new QAudioOutput(deviceInfo, format, this); - audioOutput->setBufferSize(audioBuffer); + //audioOutput->setBufferSize(audioBuffer); connect(audioOutput, SIGNAL(notify()), SLOT(notified())); connect(audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State))); } @@ -213,8 +211,6 @@ void audioHandler::reinit() if (running) { this->start(); } - flush(); - } void audioHandler::start() @@ -250,8 +246,6 @@ void audioHandler::setVolume(float volume) void audioHandler::flush() { - // Flushing buffers is a bit tricky... - // Don't modify this unless you're sure qDebug() << this->metaObject()->className() << ": flush() running"; this->stop(); if (isInput) { @@ -287,40 +281,34 @@ qint64 audioHandler::readData(char* data, qint64 maxlen) { // Calculate output length, always full samples int outlen = 0; - QMutexLocker locker(&mutex); - if (isUlaw) + if (radioSampleBits == 8) { - // Need to process uLaw. // Input buffer is 8bit and output buffer is 16bit outlen = qMin(buffer.length(), (int)maxlen / 2); - for (int f = 0; f < outlen; f++) + for (quint16 f = 0; f < outlen; f++) { - qToLittleEndian(uLawDecode(buffer.at(f)),data + f * 2); + if (isUlaw) + qToLittleEndian(uLawDecode(buffer.at(f)), data + (f * 2)); + else + qToLittleEndian((qint16)(buffer[f] << 8) - 32640, data + (f * 2)); } + QMutexLocker locker(&mutex); buffer.remove(0, outlen); outlen = outlen * 2; } - else { - if (radioSampleBits == 8) - { - outlen = qMin(buffer.length(), (int)maxlen/2); - for (int f = 0; f < outlen; f++) - { - qToLittleEndian((qint16)(buffer[f]<<8) - 32640,data + f * 2); - } - buffer.remove(0, outlen); - outlen = outlen * 2; - } else { - // Just copy it. - outlen = qMin(buffer.length(), (int)maxlen); - if (outlen % 2 != 0) { - outlen += 1; - } - memcpy(data, buffer.data(), outlen); + else if (radioSampleBits == 16) { + // Just copy it + outlen = qMin(buffer.length(), (int)maxlen); + if (outlen % 2 != 0) { + outlen += 1; // Not sure if this is necessary as we should always have an even number! } + memcpy(data, buffer.data(), outlen); + QMutexLocker locker(&mutex); buffer.remove(0, outlen); } - + else { + qDebug() << "Sample bits MUST be 8 or 16 - got: " << radioSampleBits; // Should never happen? + } return outlen; } @@ -331,7 +319,7 @@ qint64 audioHandler::writeData(const char* data, qint64 len) if (buffer.length() > bufferSize * 4) { qWarning() << "writeData() Buffer overflow"; - buffer.clear(); + buffer.clear(); // Will cause a click! } if (isUlaw) { @@ -352,7 +340,9 @@ qint64 audioHandler::writeData(const char* data, qint64 len) else { qWarning() << "Unsupported number of bits! :" << radioSampleBits; } - + if (buffer.size() >= radioSampleBits * 120) { + chunkAvailable = true; + } return (len); // Always return the same number as we received } @@ -408,7 +398,6 @@ void audioHandler::changeBufferSize(const quint16 newSize) QMutexLocker locker(&mutex); qDebug() << this->metaObject()->className() << ": Changing buffer size to: " << newSize << " from " << bufferSize; bufferSize = newSize; - flush(); } void audioHandler::getBufferSize() @@ -416,17 +405,19 @@ void audioHandler::getBufferSize() emit sendBufferSize(audioOutput->bufferSize()); } -QByteArray audioHandler::getNextAudioChunk() +void audioHandler::getNextAudioChunk(QByteArray& ret) { - QMutexLocker locker(&mutex); quint16 numSamples = radioSampleBits * 120; - QByteArray ret; if (buffer.size() >= numSamples) { + QMutexLocker locker(&mutex); ret.append(buffer.mid(0, numSamples)); buffer.remove(0, numSamples); } - - return ret; + if (buffer.size() < numSamples) + { + chunkAvailable = false; + } + return; } diff --git a/audiohandler.h b/audiohandler.h index 6512194..c92b306 100644 --- a/audiohandler.h +++ b/audiohandler.h @@ -40,8 +40,9 @@ public: qint64 writeData(const char* data, qint64 len); qint64 bytesAvailable() const; bool isSequential() const; + volatile bool chunkAvailable; void incomingAudio(const QByteArray& data); - QByteArray getNextAudioChunk(void); + void getNextAudioChunk(QByteArray &data); public slots: bool init(const quint8 bits, const quint8 channels, const quint16 samplerate, const quint16 bufferSize, const bool isulaw, const bool isinput); diff --git a/udphandler.cpp b/udphandler.cpp index 6d46e4f..fa576a9 100644 --- a/udphandler.cpp +++ b/udphandler.cpp @@ -644,9 +644,11 @@ void udpAudio::sendTxAudio() //if (((txCodec == 0x01 || txCodec == 0x02) && audio.length() != 960) || (txCodec == 0x04 && audio.length() != 1920)) { // qDebug() << "Unsupported TX audio length :" << audio.length() << " With codec: " << txCodec; //} - QByteArray audio = txaudio->getNextAudioChunk(); + if (txaudio->chunkAvailable) { + QByteArray audio; + txaudio->getNextAudioChunk(audio); int counter = 0; - while (counter < audio.length() ) { + while (counter < audio.length()) { QByteArray tx = QByteArray::fromRawData((const char*)p, sizeof(p)); QByteArray partial = audio.mid(counter, 1364); tx.append(partial); @@ -660,8 +662,8 @@ void udpAudio::sendTxAudio() //qDebug() << "Sending audio packet length: " << tx.length(); SendTrackedPacket(tx); sendAudioSeq++; - QThread::msleep(5); } + } } void udpAudio::changeBufferSize(quint16 value) diff --git a/udphandler.h b/udphandler.h index 64f2294..c1e0829 100644 --- a/udphandler.h +++ b/udphandler.h @@ -153,13 +153,13 @@ private: bool sentPacketConnect2 = false; uint16_t sendAudioSeq = 0; - audioHandler* rxaudio; - QThread* rxAudioThread; + audioHandler* rxaudio=Q_NULLPTR; + QThread* rxAudioThread=Q_NULLPTR; - audioHandler* txaudio; - QThread* txAudioThread; + audioHandler* txaudio=Q_NULLPTR; + QThread* txAudioThread=Q_NULLPTR; - QTimer* txAudioTimer; + QTimer* txAudioTimer=Q_NULLPTR; };