From 42675ae770ad79920f7914265c33cdf279b12ff6 Mon Sep 17 00:00:00 2001 From: Phil Taylor Date: Mon, 15 Nov 2021 19:28:44 +0000 Subject: [PATCH] Add mutex for incoming audio on udp and server --- udphandler.cpp | 58 ++++++++++++++++++++++++++++---------------------- udphandler.h | 3 +++ udpserver.cpp | 26 ++++++++++++++-------- udpserver.h | 1 + 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/udphandler.cpp b/udphandler.cpp index c0c93e9..6ae6333 100644 --- a/udphandler.cpp +++ b/udphandler.cpp @@ -856,36 +856,44 @@ void udpAudio::sendTxAudio() return; } QByteArray audio; - txaudio->getNextAudioChunk(audio); + if (audioMutex.try_lock_for(std::chrono::milliseconds(LOCK_PERIOD))) + { + txaudio->getNextAudioChunk(audio); + // Now we have the next audio chunk, we can release the mutex. + audioMutex.unlock(); - if (audio.length() > 0) { - int counter = 1; - int len = 0; + if (audio.length() > 0) { + int counter = 1; + int len = 0; - while (len < audio.length()) { - QByteArray partial = audio.mid(len, 1364); - audio_packet p; - memset(p.packet, 0x0, sizeof(p)); // We can't be sure it is initialized with 0x00! - p.len = sizeof(p) + partial.length(); - p.sentid = myId; - p.rcvdid = remoteId; - if (partial.length() == 0xa0) { - p.ident = 0x9781; + while (len < audio.length()) { + QByteArray partial = audio.mid(len, 1364); + audio_packet p; + memset(p.packet, 0x0, sizeof(p)); // We can't be sure it is initialized with 0x00! + p.len = sizeof(p) + partial.length(); + p.sentid = myId; + p.rcvdid = remoteId; + if (partial.length() == 0xa0) { + p.ident = 0x9781; + } + else { + p.ident = 0x0080; // TX audio is always this? + } + p.datalen = (quint16)qToBigEndian((quint16)partial.length()); + p.sendseq = (quint16)qToBigEndian((quint16)sendAudioSeq); // THIS IS BIG ENDIAN! + QByteArray tx = QByteArray::fromRawData((const char*)p.packet, sizeof(p)); + tx.append(partial); + len = len + partial.length(); + //qInfo(logUdp()) << "Sending audio packet length: " << tx.length(); + sendTrackedPacket(tx); + sendAudioSeq++; + counter++; } - else { - p.ident = 0x0080; // TX audio is always this? - } - p.datalen = (quint16)qToBigEndian((quint16)partial.length()); - p.sendseq = (quint16)qToBigEndian((quint16)sendAudioSeq); // THIS IS BIG ENDIAN! - QByteArray tx = QByteArray::fromRawData((const char*)p.packet, sizeof(p)); - tx.append(partial); - len = len + partial.length(); - //qInfo(logUdp()) << "Sending audio packet length: " << tx.length(); - sendTrackedPacket(tx); - sendAudioSeq++; - counter++; } } + else { + qInfo(logUdpServer()) << "Unable to lock mutex for rxaudio"; + } } void udpAudio::changeLatency(quint16 value) diff --git a/udphandler.h b/udphandler.h index c16bc4a..1a8e975 100644 --- a/udphandler.h +++ b/udphandler.h @@ -32,6 +32,7 @@ #define AREYOUTHERE_PERIOD 500 #define WATCHDOG_PERIOD 500 #define RETRANSMIT_PERIOD 100 +#define LOCK_PERIOD 100 struct udpPreferences { QString ipAddress; @@ -197,6 +198,8 @@ private: QTimer* txAudioTimer=Q_NULLPTR; bool enableTx = true; + QMutex audioMutex; + }; diff --git a/udpserver.cpp b/udpserver.cpp index 30208eb..9f6527c 100644 --- a/udpserver.cpp +++ b/udpserver.cpp @@ -159,7 +159,7 @@ void udpServer::controlReceived() current->commonCap = 0x8010; qInfo(logUdpServer()) << current->ipAddress.toString() << ": New Control connection created"; - if (connMutex.try_lock_for(std::chrono::milliseconds(LOCK_PERIOD))) + if (connMutex.try_lock_for(std::chrono::milliseconds(LOCK_PERIOD))) { controlClients.append(current); connMutex.unlock(); @@ -1469,14 +1469,22 @@ void udpServer::sendRxAudio() { QByteArray audio; if (rxaudio) { - audio.clear(); - rxaudio->getNextAudioChunk(audio); - int len = 0; - while (len < audio.length()) { - audioPacket partial; - partial.data = audio.mid(len, 1364); - receiveAudioData(partial); - len = len + partial.data.length(); + if (audioMutex.try_lock_for(std::chrono::milliseconds(LOCK_PERIOD))) + { + audio.clear(); + rxaudio->getNextAudioChunk(audio); + // Now we have the next audio chunk, we can release the mutex. + audioMutex.unlock(); + int len = 0; + while (len < audio.length()) { + audioPacket partial; + partial.data = audio.mid(len, 1364); + receiveAudioData(partial); + len = len + partial.data.length(); + } + } + else { + qInfo(logUdpServer()) << "Unable to lock mutex for rxaudio"; } } } diff --git a/udpserver.h b/udpserver.h index 90bfcda..1bfbacd 100644 --- a/udpserver.h +++ b/udpserver.h @@ -154,6 +154,7 @@ private: QMutex udpMutex; // Used for critical operations. QMutex connMutex; + QMutex audioMutex; QList controlClients = QList(); QList civClients = QList();