Skip to content

Commit bad1367

Browse files
softinsann0see
authored andcommitted
Add RAW_SUPPORTED protocol message and refactor client and server code
1 parent ac281b7 commit bad1367

7 files changed

Lines changed: 148 additions & 99 deletions

File tree

src/channel.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ CChannel::CChannel ( const bool bNIsServer ) :
8383

8484
QObject::connect ( &Protocol, &CProtocol::ClientIDReceived, this, &CChannel::ClientIDReceived );
8585

86+
QObject::connect ( &Protocol, &CProtocol::RawAudioSupported, this, &CChannel::RawAudioSupported );
87+
8688
QObject::connect ( &Protocol, &CProtocol::MuteStateHasChangedReceived, this, &CChannel::MuteStateHasChangedReceived );
8789

8890
QObject::connect ( &Protocol, &CProtocol::ChangeChanInfo, this, &CChannel::OnChangeChanInfo );

src/channel.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class CChannel : public QObject
149149
}
150150
}
151151
void CreateClientIDMes ( const int iChanID ) { Protocol.CreateClientIDMes ( iChanID ); }
152+
void CreateRawAudioSupportedMes() { Protocol.CreateRawAudioSupportedMes(); }
152153
void CreateReqNetwTranspPropsMes() { Protocol.CreateReqNetwTranspPropsMes(); }
153154
void CreateReqSplitMessSupportMes() { Protocol.CreateReqSplitMessSupportMes(); }
154155
void CreateReqJitBufMes() { Protocol.CreateReqJitBufMes(); }
@@ -272,6 +273,7 @@ public slots:
272273
void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo );
273274
void ChanInfoHasChanged();
274275
void ClientIDReceived ( int iChanID );
276+
void RawAudioSupported();
275277
void MuteStateHasChanged ( int iChanID, bool bIsMuted );
276278
void MuteStateHasChangedReceived ( int iChanID, bool bIsMuted );
277279
void ReqChanInfo();

src/client.cpp

Lines changed: 81 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
426401
void 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+
10201016
void 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;

src/client.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,6 @@ class CClient : public QObject
368368
bool bMuteOutStream;
369369
float fMuteOutStreamGain;
370370
CVector<unsigned char> vecCeltData;
371-
bool bUseRawAudio;
372371

373372
CHighPrioSocket Socket;
374373
CSound Sound;
@@ -455,10 +454,10 @@ protected slots:
455454
void OnControllerInFaderIsMute ( int iChannelIdx, bool bIsMute );
456455
void OnControllerInMuteMyself ( bool bMute );
457456
void OnClientIDReceived ( int iServerChanID );
457+
void OnRawAudioSupported();
458458
void OnMuteStateHasChangedReceived ( int iServerChanID, bool bIsMuted );
459459
void OnCLChannelLevelListReceived ( CHostAddress InetAddr, CVector<uint16_t> vecLevelList );
460460
void OnConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo );
461-
void OnVersionAndOSReceived ( COSUtil::EOpSystemType eOSType, QString strVersion );
462461

463462
signals:
464463
void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo );

src/protocol.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,11 @@ MESSAGES (with connection)
235235
note: does not have any data -> n = 0
236236
237237
238+
- PROTMESSID_RAWAUDIO_SUPPORTED: informs client that server supports raw (uncompressed) audio
239+
240+
note: does not have any data -> n = 0
241+
242+
238243
- PROTMESSID_RECORDER_STATE: notifies of changes in the server jam recorder state
239244
240245
+--------------+
@@ -813,6 +818,10 @@ void CProtocol::ParseMessageBody ( const CVector<uint8_t>& vecbyMesBodyData, con
813818
EvaluateSplitMessSupportedMes();
814819
break;
815820

821+
case PROTMESSID_RAWAUDIO_SUPPORTED:
822+
EvaluateRawAudioSupportedMes();
823+
break;
824+
816825
case PROTMESSID_LICENCE_REQUIRED:
817826
EvaluateLicenceRequiredMes ( vecbyMesBodyDataRef );
818827
break;
@@ -1520,6 +1529,16 @@ bool CProtocol::EvaluateSplitMessSupportedMes()
15201529
return false; // no error
15211530
}
15221531

1532+
void CProtocol::CreateRawAudioSupportedMes() { CreateAndSendMessage ( PROTMESSID_RAWAUDIO_SUPPORTED, CVector<uint8_t> ( 0 ) ); }
1533+
1534+
bool CProtocol::EvaluateRawAudioSupportedMes()
1535+
{
1536+
// invoke message action
1537+
emit RawAudioSupported();
1538+
1539+
return false; // no error
1540+
}
1541+
15231542
void CProtocol::CreateLicenceRequiredMes ( const ELicenceType eLicenceType )
15241543
{
15251544
CVector<uint8_t> vecData ( 1 ); // 1 bytes of data

0 commit comments

Comments
 (0)