From a95da5f6e144710579ed1cd17060feca62482048 Mon Sep 17 00:00:00 2001 From: Nils Brederlow <62596379+dingodoppelt@users.noreply.github.com> Date: Thu, 13 Aug 2026 12:09:11 +0200 Subject: [PATCH 1/2] [WIP] Use unused bytes in CNetworkTransportProps for raw audio (backwards compatible) --- src/channel.cpp | 3 ++- src/channel.h | 3 +++ src/client.cpp | 2 ++ src/server.cpp | 8 ++++++-- src/server.h | 1 + 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/channel.cpp b/src/channel.cpp index 7755b7ec92..a3ff66547b 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -444,6 +444,7 @@ void CChannel::OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTranspor iNetwFrameSizeFact = NetworkTransportProps.iBlockSizeFact; iNetwFrameSize = static_cast ( NetworkTransportProps.iBaseNetworkPacketSize ); bUseSequenceNumber = ( NetworkTransportProps.eFlags == NF_WITH_COUNTER ); + iAudioCodingArg = NetworkTransportProps.iAudioCodingArg; if ( bUseSequenceNumber ) { @@ -522,7 +523,7 @@ CNetworkTransportProps CChannel::GetNetworkTransportPropsFromCurrentSettings() SYSTEM_SAMPLE_RATE_HZ, eAudioCompressionType, eFlags, - 0 ); + iAudioCodingArg ); } void CChannel::Disconnect() diff --git a/src/channel.h b/src/channel.h index 946eae007a..d6a8027f96 100644 --- a/src/channel.h +++ b/src/channel.h @@ -162,6 +162,8 @@ class CChannel : public QObject EAudComprType GetAudioCompressionType() { return eAudioCompressionType; } int GetNumAudioChannels() const { return iNumAudioChannels; } + int GetAudioCodingArg() const { return iAudioCodingArg; } + void SetAudioCodingArg ( int iNAudioCodingArg ) { iAudioCodingArg = iNAudioCodingArg; } // network protocol interface void CreateJitBufMes ( const int iJitBufSize ) @@ -245,6 +247,7 @@ class CChannel : public QObject int iNetwFrameSize; int iCeltNumCodedBytes; int iAudioFrameSizeSamples; + int iAudioCodingArg; EAudComprType eAudioCompressionType; int iNumAudioChannels; diff --git a/src/client.cpp b/src/client.cpp index aa36cacb3f..f569e3313d 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1441,6 +1441,8 @@ void CClient::Init() } } + Channel.SetAudioCodingArg ( eAudioQuality ); + // calculate stereo (two channels) buffer size iStereoBlockSizeSam = 2 * iMonoBlockSizeSam; diff --git a/src/server.cpp b/src/server.cpp index a49eab776c..782c28e062 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -183,6 +183,7 @@ CServer::CServer ( const int iNewMaxNumChan, vecNumFrameSizeConvBlocks.Init ( iMaxNumChannels ); vecUseDoubleSysFraSizeConvBuf.Init ( iMaxNumChannels ); vecAudioComprType.Init ( iMaxNumChannels ); + vecAudioCodingArg.Init ( iMaxNumChannels ); for ( i = 0; i < iMaxNumChannels; i++ ) { @@ -844,6 +845,7 @@ void CServer::DecodeReceiveData ( const int iChanCnt, const int iNumClients ) // get and store number of audio channels and compression type vecNumAudioChannels[iChanCnt] = vecChannels[iCurChanID].GetNumAudioChannels(); vecAudioComprType[iChanCnt] = vecChannels[iCurChanID].GetAudioCompressionType(); + vecAudioCodingArg[iChanCnt] = vecChannels[iCurChanID].GetAudioCodingArg(); // get info about required frame size conversion properties vecUseDoubleSysFraSizeConvBuf[iChanCnt] = ( !bUseDoubleSystemFrameSize && ( vecAudioComprType[iChanCnt] == CT_OPUS ) ); @@ -974,7 +976,8 @@ void CServer::DecodeReceiveData ( const int iChanCnt, const int iNumClients ) // sizeof ( int16_t ) is the size in bytes for the raw pcm audio data = 2 // Sizes other than that are considered OPUS coded because those depend on hardcoded sizes in client.h const bool bIsRawAudio = - ( iCeltNumCodedBytes == static_cast ( sizeof ( int16_t ) * iClientFrameSizeSamples * vecNumAudioChannels[iChanCnt] ) ); + ( vecAudioCodingArg[iChanCnt] == AQ_RAW || + iCeltNumCodedBytes == static_cast ( sizeof ( int16_t ) * iClientFrameSizeSamples * vecNumAudioChannels[iChanCnt] ) ); const int iOffset = iB * SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt]; @@ -1263,7 +1266,8 @@ void CServer::MixEncodeTransmitData ( const int iChanCnt, const int iNumClients DoubleFrameSizeConvBufOut[iCurChanID].GetAll ( vecsSendData, DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt] ); } - if ( iCeltNumCodedBytes != static_cast ( sizeof ( int16_t ) * iClientFrameSizeSamples * vecNumAudioChannels[iChanCnt] ) ) + if ( vecAudioCodingArg[iChanCnt] != AQ_RAW && + iCeltNumCodedBytes != static_cast ( sizeof ( int16_t ) * iClientFrameSizeSamples * vecNumAudioChannels[iChanCnt] ) ) { // OPUS encoding if ( CurOpusEncoder != nullptr ) diff --git a/src/server.h b/src/server.h index c54c3083cd..e6c8d5a29b 100644 --- a/src/server.h +++ b/src/server.h @@ -285,6 +285,7 @@ class CServer : public QObject, public CServerSlots CVector vecNumFrameSizeConvBlocks; CVector vecUseDoubleSysFraSizeConvBuf; CVector vecAudioComprType; + CVector vecAudioCodingArg; CVector> vecvecsSendData; CVector> vecvecfIntermediateProcBuf; CVector> vecvecbyCodedData; From f7fbedd95493c0d1e1a63f26d800f362f512bbe3 Mon Sep 17 00:00:00 2001 From: Nils Brederlow <62596379+dingodoppelt@users.noreply.github.com> Date: Thu, 13 Aug 2026 19:07:36 +0200 Subject: [PATCH 2/2] Refactor, add comments --- src/server.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/server.cpp b/src/server.cpp index 782c28e062..e75f61f07a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -966,6 +966,7 @@ void CServer::DecodeReceiveData ( const int iChanCnt, const int iNumClients ) pCurCodedData = nullptr; } + //### DEPRECATED: BEGIN ###// // Recognise a raw audio packet by its size: // The client doesn't pass a value for the selected audio quality implicitly. // Rather the server is passed the length of the data sent by the client in iClientFrameSizeSamples. @@ -975,6 +976,9 @@ void CServer::DecodeReceiveData ( const int iChanCnt, const int iNumClients ) // iNumAudioChannels is either 1 for mono or 2 for stereo and mono-in/stereo-out // sizeof ( int16_t ) is the size in bytes for the raw pcm audio data = 2 // Sizes other than that are considered OPUS coded because those depend on hardcoded sizes in client.h + //### DEPRECATED: END ###// + // The client sent its audio quality setting. Check if raw audio was set + // for backwards compatibility the size check is left in, see above const bool bIsRawAudio = ( vecAudioCodingArg[iChanCnt] == AQ_RAW || iCeltNumCodedBytes == static_cast ( sizeof ( int16_t ) * iClientFrameSizeSamples * vecNumAudioChannels[iChanCnt] ) ); @@ -1252,6 +1256,9 @@ void CServer::MixEncodeTransmitData ( const int iChanCnt, const int iNumClients } } + // Check if the client wants raw audio rather than guessing by packet sizes + const bool bWantsRawAudio = vecAudioCodingArg[iChanCnt] == AQ_RAW; + // If the server frame size is smaller than the received OPUS frame size, we need a conversion // buffer which stores the large buffer. // Note that we have a shortcut here. If the conversion buffer is not needed, the boolean flag @@ -1266,7 +1273,7 @@ void CServer::MixEncodeTransmitData ( const int iChanCnt, const int iNumClients DoubleFrameSizeConvBufOut[iCurChanID].GetAll ( vecsSendData, DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES * vecNumAudioChannels[iChanCnt] ); } - if ( vecAudioCodingArg[iChanCnt] != AQ_RAW && + if ( !bWantsRawAudio && iCeltNumCodedBytes != static_cast ( sizeof ( int16_t ) * iClientFrameSizeSamples * vecNumAudioChannels[iChanCnt] ) ) { // OPUS encoding