From afd2d8e7f1f315356f252df942a6cba8a3e16561 Mon Sep 17 00:00:00 2001 From: ann0see <20726856+ann0see@users.noreply.github.com> Date: Sun, 31 Jul 2022 15:31:14 +0200 Subject: [PATCH 1/2] Improve algorithm to find in use channels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This replaces the O(n²) approach to find channels in use with a simpler O(n) approach. --- src/audiomixerboard.cpp | 160 +++++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 77 deletions(-) diff --git a/src/audiomixerboard.cpp b/src/audiomixerboard.cpp index 4cb4eac4d0..06c514b2aa 100644 --- a/src/audiomixerboard.cpp +++ b/src/audiomixerboard.cpp @@ -1210,92 +1210,98 @@ void CAudioMixerBoard::ApplyNewConClientList ( CVector& vecChanInf // search for channels with are already present and preserve their gain // setting, for all other channels reset gain - for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) + + // get all channels which are in use/not in use. We use the array index of vecChanInfo + // if the fader is in use, else INVALID_INDEX to specify it is not in use + int iFaderNumber[MAX_NUM_CHANNELS]; + + for ( int iChanID = 0; iChanID < MAX_NUM_CHANNELS; iChanID++ ) + { + iFaderNumber[iChanID] = INVALID_INDEX; + } + + for ( int iFader = 0; iFader < iNumConnectedClients; iFader++ ) { - bool bFaderIsUsed = false; + iFaderNumber[vecChanInfo[iFader].iChanID] = iFader; + } + + for ( int iChanID = 0; iChanID < MAX_NUM_CHANNELS; iChanID++ ) + { + if ( iFaderNumber[iChanID] == INVALID_INDEX ) + { + // fader is not used --> hide it + // before hiding the fader, store its level (if some conditions are fulfilled) + StoreFaderSettings ( vecpChanFader[iChanID] ); - for ( int j = 0; j < iNumConnectedClients; j++ ) + vecpChanFader[iChanID]->Hide(); + continue; + } + + // current fader is used + // check if fader was already in use -> preserve gain value + if ( !vecpChanFader[iChanID]->IsVisible() ) { - // check if current fader is used - if ( vecChanInfo[j].iChanID == i ) + // the fader was not in use, reset everything for new client + vecpChanFader[iChanID]->Reset(); + vecAvgLevels[iChanID] = 0.0f; + + // check if this is my own fader and set fader property + if ( iChanID == iMyChannelID ) + { + vecpChanFader[iChanID]->SetIsMyOwnFader(); + } + + // set and increment the running new client counter needed for sorting (per definition: + // a fader for a new client shall always be inserted at the right-hand-side if no other + // sorting type is selected (i.e. "no sorting" is active) (#673) + vecpChanFader[iChanID]->SetRunningNewClientCnt ( iRunningNewClientCnt++ ); + + // show fader + vecpChanFader[iChanID]->Show(); + + // Set the default initial fader level. Check first that + // this is not the initialization (i.e. previously there + // were no faders visible) to avoid that our own level is + // adjusted. If we have received our own channel ID, then + // we can adjust the level even if no fader was visible. + // The fader level of 100 % is the default in the + // server, in that case we do not have to do anything here. + if ( ( !bNoFaderVisible || ( ( iMyChannelID != INVALID_INDEX ) && ( iMyChannelID != iChanID ) ) ) && + ( pSettings->iNewClientFaderLevel != 100 ) ) { - // check if fader was already in use -> preserve gain value - if ( !vecpChanFader[i]->IsVisible() ) - { - // the fader was not in use, reset everything for new client - vecpChanFader[i]->Reset(); - vecAvgLevels[i] = 0.0f; - - // check if this is my own fader and set fader property - if ( i == iMyChannelID ) - { - vecpChanFader[i]->SetIsMyOwnFader(); - } - - // set and increment the running new client counter needed for sorting (per definition: - // a fader for a new client shall always be inserted at the right-hand-side if no other - // sorting type is selected (i.e. "no sorting" is active) (#673) - vecpChanFader[i]->SetRunningNewClientCnt ( iRunningNewClientCnt++ ); - - // show fader - vecpChanFader[i]->Show(); - - // Set the default initial fader level. Check first that - // this is not the initialization (i.e. previously there - // were no faders visible) to avoid that our own level is - // adjusted. If we have received our own channel ID, then - // we can adjust the level even if no fader was visible. - // The fader level of 100 % is the default in the - // server, in that case we do not have to do anything here. - if ( ( !bNoFaderVisible || ( ( iMyChannelID != INVALID_INDEX ) && ( iMyChannelID != i ) ) ) && - ( pSettings->iNewClientFaderLevel != 100 ) ) - { - // the value is in percent -> convert range - vecpChanFader[i]->SetFaderLevel ( pSettings->iNewClientFaderLevel / 100.0 * AUD_MIX_FADER_MAX ); - } - } - - // restore gain (if new name is different from the current one) - if ( vecpChanFader[i]->GetReceivedName().compare ( vecChanInfo[j].strName ) ) - { - // the text has actually changed, search in the list of - // stored settings if we have a matching entry - int iStoredFaderLevel; - int iStoredPanValue; - bool bStoredFaderIsSolo; - bool bStoredFaderIsMute; - int iGroupID; - - if ( GetStoredFaderSettings ( vecChanInfo[j].strName, - iStoredFaderLevel, - iStoredPanValue, - bStoredFaderIsSolo, - bStoredFaderIsMute, - iGroupID ) ) - { - vecpChanFader[i]->SetFaderLevel ( iStoredFaderLevel, true ); // suppress group update - vecpChanFader[i]->SetPanValue ( iStoredPanValue ); - vecpChanFader[i]->SetFaderIsSolo ( bStoredFaderIsSolo ); - vecpChanFader[i]->SetFaderIsMute ( bStoredFaderIsMute ); - vecpChanFader[i]->SetGroupID ( iGroupID ); // Must be the last to be set in the fader! - } - } - - // set the channel infos - vecpChanFader[i]->SetChannelInfos ( vecChanInfo[j] ); - - bFaderIsUsed = true; + // the value is in percent -> convert range + vecpChanFader[iChanID]->SetFaderLevel ( pSettings->iNewClientFaderLevel / 100.0 * AUD_MIX_FADER_MAX ); } } - // if current fader is not used, hide it - if ( !bFaderIsUsed ) + // restore gain (if new name is different from the current one) + if ( vecpChanFader[iChanID]->GetReceivedName().compare ( vecChanInfo[iFaderNumber[iChanID]].strName ) ) { - // before hiding the fader, store its level (if some conditions are fulfilled) - StoreFaderSettings ( vecpChanFader[i] ); - - vecpChanFader[i]->Hide(); + // the text has actually changed, search in the list of + // stored settings if we have a matching entry + int iStoredFaderLevel; + int iStoredPanValue; + bool bStoredFaderIsSolo; + bool bStoredFaderIsMute; + int iGroupID; + + if ( GetStoredFaderSettings ( vecChanInfo[iFaderNumber[iChanID]].strName, + iStoredFaderLevel, + iStoredPanValue, + bStoredFaderIsSolo, + bStoredFaderIsMute, + iGroupID ) ) + { + vecpChanFader[iChanID]->SetFaderLevel ( iStoredFaderLevel, true ); // suppress group update + vecpChanFader[iChanID]->SetPanValue ( iStoredPanValue ); + vecpChanFader[iChanID]->SetFaderIsSolo ( bStoredFaderIsSolo ); + vecpChanFader[iChanID]->SetFaderIsMute ( bStoredFaderIsMute ); + vecpChanFader[iChanID]->SetGroupID ( iGroupID ); // Must be the last to be set in the fader! + } } + + // set the channel infos + vecpChanFader[iChanID]->SetChannelInfos ( vecChanInfo[iFaderNumber[iChanID]] ); } // update the solo states since if any channel was on solo and a new client From 603cea1039216d477f55c5d8615e4d446304666a Mon Sep 17 00:00:00 2001 From: ann0see <20726856+ann0see@users.noreply.github.com> Date: Sun, 31 Jul 2022 19:11:39 +0200 Subject: [PATCH 2/2] Refactoring: Improve/Remove comments Co-Authored-By: Peter L Jones --- src/audiomixerboard.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/audiomixerboard.cpp b/src/audiomixerboard.cpp index 06c514b2aa..faf7048a60 100644 --- a/src/audiomixerboard.cpp +++ b/src/audiomixerboard.cpp @@ -1208,7 +1208,7 @@ void CAudioMixerBoard::ApplyNewConClientList ( CVector& vecChanInf UpdateTitle(); } - // search for channels with are already present and preserve their gain + // search for channels which are already present and preserve their gain // setting, for all other channels reset gain // get all channels which are in use/not in use. We use the array index of vecChanInfo @@ -1225,12 +1225,12 @@ void CAudioMixerBoard::ApplyNewConClientList ( CVector& vecChanInf iFaderNumber[vecChanInfo[iFader].iChanID] = iFader; } + // Hide all unused faders and initialize used ones for ( int iChanID = 0; iChanID < MAX_NUM_CHANNELS; iChanID++ ) { if ( iFaderNumber[iChanID] == INVALID_INDEX ) { - // fader is not used --> hide it - // before hiding the fader, store its level (if some conditions are fulfilled) + // current fader is not used StoreFaderSettings ( vecpChanFader[iChanID] ); vecpChanFader[iChanID]->Hide(); @@ -1238,22 +1238,22 @@ void CAudioMixerBoard::ApplyNewConClientList ( CVector& vecChanInf } // current fader is used - // check if fader was already in use -> preserve gain value if ( !vecpChanFader[iChanID]->IsVisible() ) { - // the fader was not in use, reset everything for new client + // the fader was not in use, + // reset everything for new client vecpChanFader[iChanID]->Reset(); vecAvgLevels[iChanID] = 0.0f; - // check if this is my own fader and set fader property if ( iChanID == iMyChannelID ) { + // this is my own fader --> set fader property vecpChanFader[iChanID]->SetIsMyOwnFader(); } - // set and increment the running new client counter needed for sorting (per definition: - // a fader for a new client shall always be inserted at the right-hand-side if no other - // sorting type is selected (i.e. "no sorting" is active) (#673) + // keep track of each new client + // for "no sorting" channel sort order new clients are added + // to the right-hand side of the mixer (#673) vecpChanFader[iChanID]->SetRunningNewClientCnt ( iRunningNewClientCnt++ ); // show fader @@ -1274,7 +1274,6 @@ void CAudioMixerBoard::ApplyNewConClientList ( CVector& vecChanInf } } - // restore gain (if new name is different from the current one) if ( vecpChanFader[iChanID]->GetReceivedName().compare ( vecChanInfo[iFaderNumber[iChanID]].strName ) ) { // the text has actually changed, search in the list of