@@ -71,8 +71,7 @@ CClient::CClient ( const quint16 iPortNumber,
7171 bEnableIPv6 ( bNEnableIPv6 ),
7272 bMuteMeInPersonalMix ( bNMuteMeInPersonalMix ),
7373 iServerSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL ),
74- bRawAudioIsSupported ( false ),
75- bUseRawAudio ( false )
74+ bRawAudioIsSupported ( false )
7675{
7776 int iOpusError;
7877
@@ -133,11 +132,13 @@ CClient::CClient ( const quint16 iPortNumber,
133132
134133 QObject::connect ( &Channel, &CChannel::ClientIDReceived, this , &CClient::OnClientIDReceived );
135134
135+ QObject::connect ( &Channel, &CChannel::RawAudioSupported, this , &CClient::OnRawAudioSupported );
136+
136137 QObject::connect ( &Channel, &CChannel::MuteStateHasChangedReceived, this , &CClient::OnMuteStateHasChangedReceived );
137138
138139 QObject::connect ( &Channel, &CChannel::LicenceRequired, this , &CClient::LicenceRequired );
139140
140- QObject::connect ( &Channel, &CChannel::VersionAndOSReceived, this , &CClient::OnVersionAndOSReceived );
141+ QObject::connect ( &Channel, &CChannel::VersionAndOSReceived, this , &CClient::VersionAndOSReceived );
141142
142143 QObject::connect ( &Channel, &CChannel::RecorderStateReceived, this , &CClient::RecorderStateReceived );
143144
@@ -397,32 +398,6 @@ void CClient::OnConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo )
397398 emit ConClientListMesReceived ( vecChanInfo );
398399}
399400
400- void CClient::OnVersionAndOSReceived ( COSUtil::EOpSystemType eOSType, QString strVersion )
401- {
402- #if QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 )
403- const bool bWasRunning = Sound.IsRunning ();
404- if ( bWasRunning )
405- {
406- Sound.Stop ();
407- }
408- if ( QVersionNumber::compare ( QVersionNumber::fromString ( strVersion ), QVersionNumber ( 3 , 11 , 1 ) ) == 0 )
409- {
410- bRawAudioIsSupported = true ;
411- Init ();
412- }
413- else
414- {
415- bRawAudioIsSupported = false ;
416- Init ();
417- }
418- if ( bWasRunning )
419- {
420- Sound.Start ();
421- }
422- #endif
423- emit VersionAndOSReceived ( eOSType, strVersion );
424- }
425-
426401void CClient::CreateServerJitterBufferMessage ()
427402{
428403 // per definition in the client: if auto jitter buffer is enabled, both,
@@ -1017,6 +992,27 @@ void CClient::OnClientIDReceived ( int iServerChanID )
1017992 emit ClientIDReceived ( iChanID );
1018993}
1019994
995+ void CClient::OnRawAudioSupported ()
996+ {
997+ if ( !bRawAudioIsSupported )
998+ {
999+ const bool bWasRunning = Sound.IsRunning ();
1000+
1001+ if ( bWasRunning )
1002+ {
1003+ Sound.Stop ();
1004+ }
1005+
1006+ bRawAudioIsSupported = true ;
1007+ Init ();
1008+
1009+ if ( bWasRunning )
1010+ {
1011+ Sound.Start ();
1012+ }
1013+ }
1014+ }
1015+
10201016void CClient::Start ()
10211017{
10221018 // init object
@@ -1047,7 +1043,6 @@ void CClient::Stop()
10471043
10481044 // Fall back to opus in case raw was used
10491045 bRawAudioIsSupported = false ;
1050- bUseRawAudio = false ;
10511046 Init ();
10521047
10531048 // wait for approx. 100 ms to make sure no audio packet is still in the
@@ -1190,12 +1185,17 @@ void CClient::Init()
11901185 iCeltNumCodedBytes = OPUS_NUM_BYTES_MONO_HIGH_QUALITY_DBLE_FRAMESIZE ;
11911186 break ;
11921187 case AQ_RAW :
1193- if ( bRawAudioIsSupported && Channel. IsEnabled () )
1188+ if ( bRawAudioIsSupported )
11941189 {
1190+ // no OPUS encoding or decoding
1191+ CurOpusEncoder = nullptr ;
1192+ CurOpusDecoder = nullptr ;
1193+
11951194 iCeltNumCodedBytes = sizeof ( int16_t ) * iNumAudioChannels * iOPUSFrameSizeSamples;
11961195 }
11971196 else
11981197 {
1198+ // fall back to highest OPUS quality
11991199 iCeltNumCodedBytes = OPUS_NUM_BYTES_MONO_HIGH_QUALITY_DBLE_FRAMESIZE ;
12001200 }
12011201 break ;
@@ -1219,12 +1219,17 @@ void CClient::Init()
12191219 iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_HIGH_QUALITY_DBLE_FRAMESIZE ;
12201220 break ;
12211221 case AQ_RAW :
1222- if ( bRawAudioIsSupported && Channel. IsEnabled () )
1222+ if ( bRawAudioIsSupported )
12231223 {
1224+ // no OPUS encoding or decoding
1225+ CurOpusEncoder = nullptr ;
1226+ CurOpusDecoder = nullptr ;
1227+
12241228 iCeltNumCodedBytes = sizeof ( int16_t ) * iNumAudioChannels * iOPUSFrameSizeSamples;
12251229 }
12261230 else
12271231 {
1232+ // fall back to highest OPUS quality
12281233 iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_HIGH_QUALITY_DBLE_FRAMESIZE ;
12291234 }
12301235 break ;
@@ -1253,12 +1258,17 @@ void CClient::Init()
12531258 iCeltNumCodedBytes = OPUS_NUM_BYTES_MONO_HIGH_QUALITY ;
12541259 break ;
12551260 case AQ_RAW :
1256- if ( bRawAudioIsSupported && Channel. IsEnabled () )
1261+ if ( bRawAudioIsSupported )
12571262 {
1263+ // no OPUS encoding or decoding
1264+ CurOpusEncoder = nullptr ;
1265+ CurOpusDecoder = nullptr ;
1266+
12581267 iCeltNumCodedBytes = sizeof ( int16_t ) * iNumAudioChannels * iOPUSFrameSizeSamples;
12591268 }
12601269 else
12611270 {
1271+ // fall back to highest OPUS quality
12621272 iCeltNumCodedBytes = OPUS_NUM_BYTES_MONO_HIGH_QUALITY ;
12631273 }
12641274 break ;
@@ -1282,22 +1292,24 @@ void CClient::Init()
12821292 iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_HIGH_QUALITY ;
12831293 break ;
12841294 case AQ_RAW :
1285- if ( bRawAudioIsSupported && Channel. IsEnabled () )
1295+ if ( bRawAudioIsSupported )
12861296 {
1297+ // no OPUS encoding or decoding
1298+ CurOpusEncoder = nullptr ;
1299+ CurOpusDecoder = nullptr ;
1300+
12871301 iCeltNumCodedBytes = sizeof ( int16_t ) * iNumAudioChannels * iOPUSFrameSizeSamples;
12881302 }
12891303 else
12901304 {
1305+ // fall back to highest OPUS quality
12911306 iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_HIGH_QUALITY ;
12921307 }
12931308 break ;
12941309 }
12951310 }
12961311 }
12971312
1298- // determine whether to use raw audio
1299- bUseRawAudio = bRawAudioIsSupported && eAudioQuality == AQ_RAW ;
1300-
13011313 // calculate stereo (two channels) buffer size
13021314 iStereoBlockSizeSam = 2 * iMonoBlockSizeSam;
13031315
@@ -1306,7 +1318,7 @@ void CClient::Init()
13061318 vecsStereoSndCrdMuteStream.Init ( iStereoBlockSizeSam );
13071319
13081320 // In case we are connected to a non raw audio server or we don't use raw audio we need to initialze the codec
1309- if ( !bUseRawAudio )
1321+ if ( CurOpusEncoder != nullptr )
13101322 {
13111323 opus_custom_encoder_ctl ( CurOpusEncoder,
13121324 OPUS_SET_BITRATE ( CalcBitRateBitsPerSecFromCodedBytes ( iCeltNumCodedBytes, iOPUSFrameSizeSamples ) ) );
@@ -1471,33 +1483,34 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
14711483
14721484 for ( i = 0 , j = 0 ; i < iSndCrdFrameSizeFactor; i++, j += iNumAudioChannels * iOPUSFrameSizeSamples )
14731485 {
1474- if ( !bUseRawAudio )
1486+ // OPUS encoding or copying RAW audio?
1487+ if ( CurOpusEncoder != nullptr )
14751488 {
14761489 // OPUS encoding
1477- if ( CurOpusEncoder != nullptr )
1490+ if ( bMuteOutStream )
14781491 {
1479- if ( bMuteOutStream )
1480- {
1481- iUnused = opus_custom_encode ( CurOpusEncoder, &vecZeros[j], iOPUSFrameSizeSamples, &vecCeltData[0 ], iCeltNumCodedBytes );
1482- }
1483- else
1484- {
1485- iUnused = opus_custom_encode ( CurOpusEncoder, &vecsStereoSndCrd[j], iOPUSFrameSizeSamples, &vecCeltData[0 ], iCeltNumCodedBytes );
1486- }
1492+ iUnused = opus_custom_encode ( CurOpusEncoder, &vecZeros[j], iOPUSFrameSizeSamples, &vecCeltData[0 ], iCeltNumCodedBytes );
1493+ }
1494+ else
1495+ {
1496+ iUnused = opus_custom_encode ( CurOpusEncoder, &vecsStereoSndCrd[j], iOPUSFrameSizeSamples, &vecCeltData[0 ], iCeltNumCodedBytes );
14871497 }
14881498 }
1489- else
1499+ else if ( bRawAudioIsSupported )
14901500 {
1501+ // RAW audio
14911502 if ( bMuteOutStream )
14921503 {
1504+ // output muted - fill with silence
14931505 memset ( &vecCeltData[0 ], 0 , iCeltNumCodedBytes );
14941506 }
14951507 else
14961508 {
1497- // Send raw samples instead of OPUS
1509+ // copy raw audio data
14981510 memcpy ( &vecCeltData[0 ], &vecsStereoSndCrd[j], iCeltNumCodedBytes );
14991511 }
15001512 }
1513+
15011514 // send coded audio through the network
15021515 Channel.PrepAndSendPacket ( &Socket, vecCeltData, iCeltNumCodedBytes );
15031516 }
@@ -1517,38 +1530,40 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
15171530 // get pointer to coded data and manage the flags
15181531 if ( bReceiveDataOk )
15191532 {
1520- if ( eAudioQuality == AQ_RAW && bRawAudioIsSupported )
1521- {
1522- memcpy ( &vecsStereoSndCrd[j], &vecbyNetwData[0 ], iCeltNumCodedBytes );
1523- pCurCodedData = nullptr ;
1524- }
1525- else
1526- {
1527- pCurCodedData = &vecbyNetwData[0 ];
1528- }
1533+ pCurCodedData = &vecbyNetwData[0 ];
15291534
15301535 // on any valid received packet, we clear the initialization phase flag
15311536 bIsInitializationPhase = false ;
15321537 }
15331538 else
15341539 {
1535- if ( eAudioQuality == AQ_RAW && bRawAudioIsSupported )
1536- {
1537- memset ( &vecsStereoSndCrd[j], 0 , iCeltNumCodedBytes );
1538- }
1539-
15401540 // for lost packets use null pointer as coded input data
15411541 pCurCodedData = nullptr ;
15421542
15431543 // invalidate the buffer OK status flag
15441544 bJitterBufferOK = false ;
15451545 }
15461546
1547- if ( !bUseRawAudio && CurOpusDecoder != nullptr )
1547+ // OPUS decoding or copying RAW audio?
1548+ if ( CurOpusDecoder != nullptr )
15481549 {
15491550 // OPUS decoding
15501551 iUnused = opus_custom_decode ( CurOpusDecoder, pCurCodedData, iCeltNumCodedBytes, &vecsStereoSndCrd[j], iOPUSFrameSizeSamples );
15511552 }
1553+ else if ( bRawAudioIsSupported )
1554+ {
1555+ // RAW audio
1556+ if ( pCurCodedData != nullptr )
1557+ {
1558+ // copy raw audio data
1559+ memcpy ( &vecsStereoSndCrd[j], pCurCodedData, iCeltNumCodedBytes );
1560+ }
1561+ else
1562+ {
1563+ // missing audio - fill with silence
1564+ memset ( &vecsStereoSndCrd[j], 0 , iCeltNumCodedBytes );
1565+ }
1566+ }
15521567 }
15531568
15541569 // for muted stream we have to add our local data here
@@ -1626,7 +1641,7 @@ int CClient::EstimatedOverallDelay ( const int iPingTimeMs )
16261641 const float fDelayToFillNetworkPacketsMs = GetSystemMonoBlSize () * 1000 .0f / SYSTEM_SAMPLE_RATE_HZ ;
16271642
16281643 // OPUS additional delay at small frame sizes is half a frame size
1629- const float fAdditionalAudioCodecDelayMs = ( eAudioQuality == AQ_RAW && bRawAudioIsSupported ) ? 0 . 0f : fSystemBlockDurationMs / 2 ;
1644+ const float fAdditionalAudioCodecDelayMs = CurOpusDecoder != nullptr ? fSystemBlockDurationMs / 2 : 0 . 0f ;
16301645
16311646 const float fTotalBufferDelayMs =
16321647 fDelayToFillNetworkPacketsMs + fTotalJitterBufferDelayMs + fTotalSoundCardDelayMs + fAdditionalAudioCodecDelayMs ;
0 commit comments