@@ -290,9 +290,10 @@ void CClient::OnNewConnection()
290290 // ### TODO: END ###//
291291}
292292
293- void CClient::OnMuteStateHasChangedReceived ( int iChanID , bool bIsMuted )
293+ void CClient::OnMuteStateHasChangedReceived ( int iServerChanID , bool bIsMuted )
294294{
295- // TODO map iChanID from server channel ID to client channel ID
295+ // map iChanID from server channel ID to client channel ID
296+ int iChanID = FindClientChannel ( iServerChanID, false );
296297
297298 emit MuteStateHasChangedReceived ( iChanID, bIsMuted );
298299}
@@ -306,34 +307,73 @@ void CClient::OnCLChannelLevelListReceived ( CHostAddress InetAddr, CVector<uint
306307
307308void CClient::OnConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo )
308309{
309- // TODO translate from server channel IDs to client channel IDs
310+ // translate from server channel IDs to client channel IDs
310311 // ALSO here is where we allocate and free client channels as required
311312
312313 // Upon receiving a new client list, we have to reset oldGain and newGain
313314 // entries for unused channels. This ensures that a disconnected channel
314315 // does not leave behind wrong cached gain values which would leak into
315316 // any new channel which reused this channel id.
316- int iNumConnectedClients = vecChanInfo.Size ();
317317
318- // Save what channel IDs are in use:
319- bool bChanIdInUse[MAX_NUM_CHANNELS] = {};
320- for ( int i = 0 ; i < iNumConnectedClients; i++ )
318+ const int iNumConnectedClients = vecChanInfo.Size ();
319+ int i, iSrvIdx;
320+
321+ // this relies on the received client list being in order of server channel ID
322+
323+ for ( i = 0 , iSrvIdx = 0 ; i < iNumConnectedClients && iSrvIdx < MAX_NUM_CHANNELS; )
321324 {
322- bChanIdInUse[vecChanInfo[i].iChanID ] = true ;
325+ // server channel ID of this entry
326+ const int iServerChannelID = vecChanInfo[i].iChanID ;
327+
328+ // find matching client channel ID, creating new if necessary
329+ const int iClientChannelID = FindClientChannel ( iServerChannelID, true );
330+
331+ // discard any lower server channels that are no longer in our local list
332+ while ( iSrvIdx < iServerChannelID )
333+ {
334+ const int iId = FindClientChannel ( iSrvIdx, false );
335+
336+ if ( iId != INVALID_INDEX )
337+ {
338+ // reset oldGain and newGain as this channel id is currently unused and will
339+ // start with a server-side gain at 1 (100%) again.
340+ oldGain[iId] = newGain[iId] = 1 ;
341+
342+ // iSrvIdx contains a server channel number that has now gone
343+ FreeClientChannel ( iSrvIdx );
344+ }
345+ iSrvIdx++;
346+ }
347+
348+ // now should have matching server channel IDs
349+ vecChanInfo[i].iChanID = iClientChannelID; // update channel number to be client-side
350+ i++; // next list entry
351+ iSrvIdx++; // next local server channel
323352 }
324353
325- // Reset all gains for unused channel IDs:
326- for ( int iId = 0 ; iId < MAX_NUM_CHANNELS; iId++ )
354+ // have now run out of active channels, discard any remaining from our local list
355+ // note that iActiveChannels will reduce as remaining channels are freed
356+
357+ while ( iActiveChannels > iNumConnectedClients && iSrvIdx < MAX_NUM_CHANNELS )
327358 {
328- if ( !bChanIdInUse[iId] )
359+ const int iId = FindClientChannel ( iSrvIdx, false );
360+
361+ if ( iId != INVALID_INDEX )
329362 {
330363 // reset oldGain and newGain as this channel id is currently unused and will
331364 // start with a server-side gain at 1 (100%) again.
332365 oldGain[iId] = newGain[iId] = 1 ;
366+
367+ // iSrvIdx contains a server channel number that has now gone
368+ FreeClientChannel ( iSrvIdx );
333369 }
370+ iSrvIdx++;
334371 }
335372
373+ Q_ASSERT ( iActiveChannels == iNumConnectedClients );
374+
336375 // TODO vecChanInfo needs to be ordered by client channel ID instead of server channel ID
376+ // check if this is actually necessary, and whether it affects the level meters
337377
338378 emit ConClientListMesReceived ( vecChanInfo );
339379}
@@ -447,7 +487,7 @@ void CClient::SetRemoteChanGain ( const int iId, const float fGain, const bool b
447487 // here the timer was not active:
448488 // send the actual gain and reset the range of channel IDs to empty
449489 oldGain[iId] = newGain[iId] = fGain ;
450- Channel.SetRemoteChanGain ( iId, fGain ); // TODO translate client channel to server channel ID
490+ Channel.SetRemoteChanGain ( clientChannels[ iId]. iServerChannelID , fGain ); // translate client channel to server channel ID
451491
452492 StartDelayTimer ();
453493}
@@ -463,7 +503,7 @@ void CClient::OnTimerRemoteChanGain()
463503 {
464504 // send new gain and record as old gain
465505 float fGain = oldGain[iId] = newGain[iId];
466- Channel.SetRemoteChanGain ( iId, fGain ); // TODO translate client channel to server channel ID
506+ Channel.SetRemoteChanGain ( clientChannels[ iId]. iServerChannelID , fGain ); // translate client channel to server channel ID
467507 bSent = true ;
468508 }
469509 }
@@ -496,7 +536,7 @@ void CClient::StartDelayTimer()
496536
497537void CClient::SetRemoteChanPan ( const int iId, const float fPan )
498538{
499- Channel.SetRemoteChanPan ( iId, fPan ); // TODO translate client channel to server channel ID
539+ Channel.SetRemoteChanPan ( clientChannels[ iId]. iServerChannelID , fPan ); // translate client channel to server channel ID
500540}
501541
502542bool CClient::SetServerAddr ( QString strNAddr )
@@ -874,16 +914,17 @@ void CClient::OnControllerInMuteMyself ( bool bMute )
874914 emit ControllerInMuteMyself ( bMute );
875915}
876916
877- void CClient::OnClientIDReceived ( int iChanID )
917+ void CClient::OnClientIDReceived ( int iServerChanID )
878918{
879- // TODO allocate and map client-side channel 0
919+ // allocate and map client-side channel 0
920+ int iChanID = FindClientChannel ( iServerChanID, true ); // should always return channel 0
880921
881922 // for headless mode we support to mute our own signal in the personal mix
882923 // (note that the check for headless is done in the main.cpp and must not
883924 // be checked here)
884925 if ( bMuteMeInPersonalMix )
885926 {
886- SetRemoteChanGain ( iChanID, 0 , false ); // TODO this will need client channel ID
927+ SetRemoteChanGain ( iChanID, 0 , false );
887928 }
888929
889930 emit ClientIDReceived ( iChanID );
@@ -1434,6 +1475,8 @@ void CClient::ClearClientChannels()
14341475
14351476 clientChannelIDs[i] = INVALID_INDEX;
14361477 }
1478+
1479+ qInfo () << " > Client channel list cleared" ;
14371480}
14381481
14391482void CClient::FreeClientChannel ( const int iServerChannelID )
@@ -1471,7 +1514,7 @@ int CClient::FindClientChannel ( const int iServerChannelID, const bool bCreateI
14711514 return INVALID_INDEX;
14721515 }
14731516
1474- const int iClientChannelID = clientChannelIDs[iServerChannelID];
1517+ int iClientChannelID = clientChannelIDs[iServerChannelID];
14751518
14761519 if ( iClientChannelID != INVALID_INDEX )
14771520 {
@@ -1484,13 +1527,13 @@ int CClient::FindClientChannel ( const int iServerChannelID, const bool bCreateI
14841527 if ( bCreateIfNew )
14851528 {
14861529 // search clientChannels[] for a free client channel
1487- for ( int i = 0 ; i < MAX_NUM_CHANNELS; i ++ )
1530+ for ( iClientChannelID = 0 ; iClientChannelID < MAX_NUM_CHANNELS; iClientChannelID ++ )
14881531 {
1489- if ( clientChannels[i ].iServerChannelID == INVALID_INDEX )
1532+ if ( clientChannels[iClientChannelID ].iServerChannelID == INVALID_INDEX )
14901533 {
1491- clientChannels[i ].iServerChannelID = iServerChannelID;
1492- clientChannels[i ].iJoinSequence = ++iJoinSequence;
1493- clientChannelIDs[iServerChannelID] = i ;
1534+ clientChannels[iClientChannelID ].iServerChannelID = iServerChannelID;
1535+ clientChannels[iClientChannelID ].iJoinSequence = ++iJoinSequence;
1536+ clientChannelIDs[iServerChannelID] = iClientChannelID ;
14941537
14951538 iActiveChannels += 1 ;
14961539
@@ -1499,7 +1542,7 @@ int CClient::FindClientChannel ( const int iServerChannelID, const bool bCreateI
14991542 .arg ( iServerChannelID )
15001543 .arg ( iActiveChannels ) );
15011544
1502- return i ; // new client channel ID
1545+ return iClientChannelID ; // new client channel ID
15031546 }
15041547 }
15051548 }
0 commit comments