/******************************************************************************\ * Copyright (c) 2004-2014 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * \******************************************************************************/ #include "audiomixerboard.h" /******************************************************************************\ * CChanneFader * \******************************************************************************/ CChannelFader::CChannelFader ( QWidget* pNW, QHBoxLayout* pParentLayout ) { // create new GUI control objects and store pointers to them (note that // QWidget takes the ownership of the pMainGrid so that this only has // to be created locally in this constructor) pFrame = new QFrame ( pNW ); QVBoxLayout* pMainGrid = new QVBoxLayout ( pFrame ); pFader = new QSlider ( Qt::Vertical, pFrame ); pcbMute = new QCheckBox ( "Mute", pFrame ); pcbSolo = new QCheckBox ( "Solo", pFrame ); QGroupBox* pLabelInstBox = new QGroupBox ( pFrame ); plblLabel = new QLabel ( "", pFrame ); plblInstrument = new QLabel ( pFrame ); plblCountryFlag = new QLabel ( pFrame ); QHBoxLayout* pLabelGrid = new QHBoxLayout ( pLabelInstBox ); // setup slider pFader->setPageStep ( 1 ); pFader->setTickPosition ( QSlider::TicksBothSides ); pFader->setRange ( 0, AUD_MIX_FADER_MAX ); pFader->setTickInterval ( AUD_MIX_FADER_MAX / 9 ); // setup group box for label/instrument picture (use white background of // label and set a thick black border with nice round edges) pLabelInstBox->setStyleSheet ( "QGroupBox { border: 2px solid black;" " border-radius: 4px;" " padding: 3px;" " background-color: white; }" ); // setup fader tag label (black bold text which is centered) plblLabel->setTextFormat ( Qt::PlainText ); plblLabel->setAlignment ( Qt::AlignHCenter ); plblLabel->setStyleSheet ( "QLabel { color: black;" " font: bold; }" ); // set margins of the layouts to zero to get maximum space for the controls pMainGrid->setContentsMargins ( 0, 0, 0, 0 ); pLabelGrid->setContentsMargins ( 0, 0, 0, 0 ); pLabelGrid->setSpacing ( 2 ); // only minimal space between picture and text // add user controls to the grids pLabelGrid->addWidget ( plblInstrument ); pLabelGrid->addWidget ( plblLabel, 0, Qt::AlignVCenter ); pLabelGrid->addWidget ( plblCountryFlag, 0, Qt::AlignRight ); pMainGrid->addWidget ( pFader, 0, Qt::AlignHCenter ); pMainGrid->addWidget ( pcbMute, 0, Qt::AlignLeft ); pMainGrid->addWidget ( pcbSolo, 0, Qt::AlignLeft ); pMainGrid->addWidget ( pLabelInstBox ); // add fader frame to audio mixer board layout pParentLayout->addWidget( pFrame ); // reset current fader Reset(); // add help text to controls pFader->setWhatsThis ( tr ( "Mixer Fader: Adjusts the audio level of " "this channel. All connected clients at the server will be assigned " "an audio fader at each client." ) ); pFader->setAccessibleName ( tr ( "Mixer level setting of the connected client " "at the server" ) ); pcbMute->setWhatsThis ( tr ( "Mute: With the Mute checkbox, the current " "audio channel can be muted." ) ); pcbMute->setAccessibleName ( tr ( "Mute button" ) ); pcbSolo->setWhatsThis ( tr ( "Solo: With the Solo checkbox, the current " "audio channel can be set to solo which means that all other channels " "except of the current channel are muted. It is possible to set more than " "one channel to solo." ) ); pcbSolo->setAccessibleName ( tr ( "Solo button" ) ); QString strFaderText = tr ( "Fader Tag: The fader tag " "identifies the connected client. The tag name, the picture of your " "instrument and a flag of your country can be set in the main window." ); plblInstrument->setWhatsThis ( strFaderText ); plblInstrument->setAccessibleName ( tr ( "Mixer channel instrument picture" ) ); plblLabel->setWhatsThis ( strFaderText ); plblLabel->setAccessibleName ( tr ( "Mixer channel label (fader tag)" ) ); plblCountryFlag->setWhatsThis ( strFaderText ); plblCountryFlag->setAccessibleName ( tr ( "Mixer channel country flag" ) ); // Connections ------------------------------------------------------------- QObject::connect ( pFader, SIGNAL ( valueChanged ( int ) ), this, SLOT ( OnLevelValueChanged ( int ) ) ); QObject::connect ( pcbMute, SIGNAL ( stateChanged ( int ) ), this, SLOT ( OnMuteStateChanged ( int ) ) ); QObject::connect ( pcbSolo, SIGNAL ( stateChanged ( int ) ), SIGNAL ( soloStateChanged ( int ) ) ); } void CChannelFader::SetGUIDesign ( const EGUIDesign eNewDesign ) { switch ( eNewDesign ) { case GD_ORIGINAL: // fader pFader->setStyleSheet ( "QSlider { width: 45px;" " border-image: url(:/png/fader/res/faderbackground.png) repeat;" " border-top: 10px transparent;" " border-bottom: 10px transparent;" " border-left: 20px transparent;" " border-right: -25px transparent; }" "QSlider::groove { image: url();" " padding-left: -38px;" " padding-top: -10px;" " padding-bottom: -15px; }" "QSlider::handle { image: url(:/png/fader/res/faderhandle.png); }" ); // mute button pcbMute->setText ( tr ( "MUTE" ) ); // solo button pcbSolo->setText ( tr ( "SOLO" ) ); break; default: // reset style sheet and set original paramters pFader->setStyleSheet ( "" ); pcbMute->setText ( tr ( "Mute" ) ); pcbSolo->setText ( tr ( "Solo" ) ); break; } } void CChannelFader::Reset() { // init gain value -> maximum value as definition according to server pFader->setValue ( AUD_MIX_FADER_MAX ); // reset mute/solo check boxes pcbMute->setChecked ( false ); pcbSolo->setChecked ( false ); // clear instrument picture, country flag, tool tips and label text plblInstrument->setVisible ( false ); plblInstrument->setToolTip ( "" ); plblCountryFlag->setVisible ( false ); plblCountryFlag->setToolTip ( "" ); plblLabel->setText ( "" ); strReceivedName = ""; bOtherChannelIsSolo = false; } void CChannelFader::SetFaderLevel ( const int iLevel ) { // first make a range check if ( ( iLevel >= 0 ) && ( iLevel <= AUD_MIX_FADER_MAX ) ) { // we set the new fader level in the GUI (slider control) and also tell the // server about the change pFader->setValue ( iLevel ); SendFaderLevelToServer ( iLevel ); } } void CChannelFader::SetFaderIsSolo ( const bool bIsSolo ) { // changing the state automatically emits the signal, too pcbSolo->setChecked ( bIsSolo ); } void CChannelFader::SendFaderLevelToServer ( const int iLevel ) { // if mute flag is set or other channel is on solo, do not apply the new // fader value (exception: we are on solo, in that case we ignore the // "other channel is on solo" flag) if ( ( pcbMute->checkState() == Qt::Unchecked ) && ( !bOtherChannelIsSolo || IsSolo() ) ) { // emit signal for new fader gain value emit gainValueChanged ( CalcFaderGain ( iLevel ) ); } } void CChannelFader::OnMuteStateChanged ( int value ) { // call muting function SetMute ( static_cast ( value ) == Qt::Checked ); } void CChannelFader::SetMute ( const bool bState ) { if ( bState ) { // mute channel -> send gain of 0 emit gainValueChanged ( 0 ); } else { // only unmute if we are not solot but an other channel is on solo if ( !bOtherChannelIsSolo || IsSolo() ) { // mute was unchecked, get current fader value and apply emit gainValueChanged ( CalcFaderGain ( GetFaderLevel() ) ); } } } void CChannelFader::UpdateSoloState ( const bool bNewOtherSoloState ) { // store state (must be done before the SetMute() call!) bOtherChannelIsSolo = bNewOtherSoloState; // mute overwrites solo -> if mute is active, do not change anything if ( !pcbMute->isChecked() ) { // mute channel if we are not solo but another channel is solo SetMute ( bOtherChannelIsSolo && !IsSolo() ); } } void CChannelFader::SetText ( const CChannelInfo& ChanInfo ) { // store original received name strReceivedName = ChanInfo.strName; // break text at predefined position const int iBreakPos = MAX_LEN_FADER_TAG / 2; QString strModText = GenFaderText ( ChanInfo ); if ( strModText.length() > iBreakPos ) { strModText.insert ( iBreakPos, QString ( "\n" ) ); } plblLabel->setText ( strModText ); } void CChannelFader::SetInstrumentPicture ( const int iInstrument ) { // get the resource reference string for this instrument const QString strCurResourceRef = CInstPictures::GetResourceReference ( iInstrument ); // first check if instrument picture is used or not and if it is valid if ( CInstPictures::IsNotUsedInstrument ( iInstrument ) || strCurResourceRef.isEmpty() ) { // disable instrument picture and tool tip plblInstrument->setVisible ( false ); plblInstrument->setToolTip ( "" ); } else { // set correct picture and tool tip text plblInstrument->setPixmap ( QPixmap ( strCurResourceRef ) ); plblInstrument->setToolTip ( CInstPictures::GetName ( iInstrument ) ); // enable instrument picture plblInstrument->setVisible ( true ); } } void CChannelFader::SetCountryFlag ( const QLocale::Country eCountry ) { if ( eCountry != QLocale::AnyCountry ) { // try to load the country flag icon QPixmap CountryFlagPixmap ( CCountyFlagIcons::GetResourceReference ( eCountry ) ); // first check if resource reference was valid if ( CountryFlagPixmap.isNull() ) { // disable country flag and tool tip plblCountryFlag->setVisible ( false ); plblCountryFlag->setToolTip ( "" ); } else { // set correct picture and tool tip text plblCountryFlag->setPixmap ( CountryFlagPixmap ); plblCountryFlag->setToolTip ( QLocale::countryToString ( eCountry ) ); // enable country flag plblCountryFlag->setVisible ( true ); } } else { // disable country flag and tool tip plblCountryFlag->setVisible ( false ); plblCountryFlag->setToolTip ( "" ); } } double CChannelFader::CalcFaderGain ( const int value ) { // convert actual slider range in gain values // and normalize so that maximum gain is 1 return static_cast ( value ) / AUD_MIX_FADER_MAX; } QString CChannelFader::GenFaderText ( const CChannelInfo& ChanInfo ) { // if text is empty, show IP address instead if ( ChanInfo.strName.isEmpty() ) { // convert IP address to text and show it (use dummy port number // since it is not used here) const CHostAddress TempAddr = CHostAddress ( QHostAddress ( ChanInfo.iIpAddr ), 0 ); return TempAddr.toString ( CHostAddress::SM_IP_NO_LAST_BYTE ); } else { // show name of channel return ChanInfo.strName; } } /******************************************************************************\ * CAudioMixerBoard * \******************************************************************************/ CAudioMixerBoard::CAudioMixerBoard ( QWidget* parent, Qt::WindowFlags ) : QGroupBox ( parent ), vecStoredFaderTags ( MAX_NUM_STORED_FADER_SETTINGS, "" ), vecStoredFaderLevels ( MAX_NUM_STORED_FADER_SETTINGS, AUD_MIX_FADER_MAX ), vecStoredFaderIsSolo ( MAX_NUM_STORED_FADER_SETTINGS, false ) { // set title text (default: no server given) SetServerName ( "" ); // add hboxlayout pMainLayout = new QHBoxLayout ( this ); // create all mixer controls and make them invisible vecpChanFader.Init ( MAX_NUM_CHANNELS ); for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { vecpChanFader[i] = new CChannelFader ( this, pMainLayout ); vecpChanFader[i]->Hide(); } // insert horizontal spacer pMainLayout->addItem ( new QSpacerItem ( 0, 0, QSizePolicy::Expanding ) ); // Connections ------------------------------------------------------------- // CODE TAG: MAX_NUM_CHANNELS_TAG // make sure we have MAX_NUM_CHANNELS connections!!! QObject::connect ( vecpChanFader[0], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh0 ( double ) ) ); QObject::connect ( vecpChanFader[1], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh1 ( double ) ) ); QObject::connect ( vecpChanFader[2], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh2 ( double ) ) ); QObject::connect ( vecpChanFader[3], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh3 ( double ) ) ); QObject::connect ( vecpChanFader[4], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh4 ( double ) ) ); QObject::connect ( vecpChanFader[5], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh5 ( double ) ) ); QObject::connect ( vecpChanFader[6], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh6 ( double ) ) ); QObject::connect ( vecpChanFader[7], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh7 ( double ) ) ); QObject::connect ( vecpChanFader[8], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh8 ( double ) ) ); QObject::connect ( vecpChanFader[9], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh9 ( double ) ) ); QObject::connect ( vecpChanFader[10], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh10 ( double ) ) ); QObject::connect ( vecpChanFader[11], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh11 ( double ) ) ); QObject::connect ( vecpChanFader[12], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh12 ( double ) ) ); QObject::connect ( vecpChanFader[13], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh13 ( double ) ) ); QObject::connect ( vecpChanFader[14], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh14 ( double ) ) ); QObject::connect ( vecpChanFader[15], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh15 ( double ) ) ); QObject::connect ( vecpChanFader[16], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh16 ( double ) ) ); QObject::connect ( vecpChanFader[17], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh17 ( double ) ) ); QObject::connect ( vecpChanFader[18], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh18 ( double ) ) ); QObject::connect ( vecpChanFader[19], SIGNAL ( gainValueChanged ( double ) ), this, SLOT ( OnGainValueChangedCh19 ( double ) ) ); QObject::connect ( vecpChanFader[0], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[1], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[2], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[3], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[4], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[5], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[6], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[7], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[8], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[9], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[10], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[11], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[12], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[13], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[14], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[15], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[16], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[17], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[18], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); QObject::connect ( vecpChanFader[19], SIGNAL ( soloStateChanged ( int ) ), this, SLOT ( OnChSoloStateChanged() ) ); } void CAudioMixerBoard::SetServerName ( const QString& strNewServerName ) { // set title text of the group box if ( strNewServerName.isEmpty() ) { setTitle ( "Server" ); } else { setTitle ( strNewServerName ); } } void CAudioMixerBoard::SetGUIDesign ( const EGUIDesign eNewDesign ) { // apply GUI design to child GUI controls for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { vecpChanFader[i]->SetGUIDesign ( eNewDesign ); } } void CAudioMixerBoard::HideAll() { // make all controls invisible for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { // before hiding the fader, store its level (if some conditions are fullfilled) StoreFaderSettings ( vecpChanFader[i] ); vecpChanFader[i]->Hide(); } // emit status of connected clients emit NumClientsChanged ( 0 ); // -> no clients connected } void CAudioMixerBoard::ApplyNewConClientList ( CVector& vecChanInfo ) { // get number of connected clients const int iNumConnectedClients = vecChanInfo.Size(); // 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++ ) { bool bFaderIsUsed = false; for ( int j = 0; j < iNumConnectedClients; j++ ) { // check if current fader is used if ( vecChanInfo[j].iChanID == i ) { // 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(); // show fader vecpChanFader[i]->Show(); } // 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; bool bStoredFaderIsSolo; if ( GetStoredFaderSettings ( vecChanInfo[j], iStoredFaderLevel, bStoredFaderIsSolo ) ) { vecpChanFader[i]->SetFaderLevel ( iStoredFaderLevel ); vecpChanFader[i]->SetFaderIsSolo ( bStoredFaderIsSolo ); } } // set the text in the fader vecpChanFader[i]->SetText ( vecChanInfo[j] ); // update other channel infos (only available for new protocol // which is not compatible with old versions -> this way we make // sure that the protocol which transferrs only the name does // change the other client infos // #### COMPATIBILITY OLD VERSION, TO BE REMOVED #### -> the "if-condition" can be removed later on... if ( !vecChanInfo[j].bOnlyNameIsUsed ) { // update instrument picture vecpChanFader[i]-> SetInstrumentPicture ( vecChanInfo[j].iInstrument ); // update country flag vecpChanFader[i]-> SetCountryFlag ( vecChanInfo[j].eCountry ); } bFaderIsUsed = true; } } // if current fader is not used, hide it if ( !bFaderIsUsed ) { // before hiding the fader, store its level (if some conditions are fullfilled) StoreFaderSettings ( vecpChanFader[i] ); vecpChanFader[i]->Hide(); } } // update the solo states since if any channel was on solo and a new client // has just connected, the new channel must be muted UpdateSoloStates(); // emit status of connected clients emit NumClientsChanged ( iNumConnectedClients ); } void CAudioMixerBoard::UpdateSoloStates() { // first check if any channel has a solo state active bool bAnyChannelIsSolo = false; for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { // check if fader is in use and has solo state active if ( vecpChanFader[i]->IsVisible() && vecpChanFader[i]->IsSolo() ) { bAnyChannelIsSolo = true; continue; } } // now update the solo state of all active faders for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { if ( vecpChanFader[i]->IsVisible() ) { vecpChanFader[i]->UpdateSoloState ( bAnyChannelIsSolo ); } } } void CAudioMixerBoard::OnGainValueChanged ( const int iChannelIdx, const double dValue ) { emit ChangeChanGain ( iChannelIdx, dValue ); } void CAudioMixerBoard::StoreFaderSettings ( CChannelFader* pChanFader ) { // if the fader was visible and the name is not empty, we store the old gain if ( pChanFader->IsVisible() && !pChanFader->GetReceivedName().isEmpty() ) { CVector viOldStoredFaderLevels ( vecStoredFaderLevels ); CVector vbOldStoredFaderIsSolo ( vecStoredFaderIsSolo ); // init temporary list count (may be overwritten later on) int iTempListCnt = 0; // check if the new fader level and solo state is the default one -> in // that case the entry must be deleted from the list if currently // present in the list const bool bNewFaderLevelAndSoloIsDefault = ( ( pChanFader->GetFaderLevel() == AUD_MIX_FADER_MAX ) && ( !pChanFader->IsSolo() ) // solo=OFF is the default ); // if the new value is not the default value, put it on the top of the // list, otherwise just remove it from the list const int iOldIdx = vecStoredFaderTags.StringFiFoWithCompare ( pChanFader->GetReceivedName(), !bNewFaderLevelAndSoloIsDefault ); if ( !bNewFaderLevelAndSoloIsDefault ) { // current fader level and solo state is at the top of the list vecStoredFaderLevels[0] = pChanFader->GetFaderLevel(); vecStoredFaderIsSolo[0] = pChanFader->IsSolo(); iTempListCnt = 1; } for ( int iIdx = 0; iIdx < MAX_NUM_STORED_FADER_SETTINGS; iIdx++ ) { // first check if we still have space in our data storage if ( iTempListCnt < MAX_NUM_STORED_FADER_SETTINGS ) { // check for the old index of the current entry (this has to be // skipped), note that per definition: the old index is an illegal // index in case the entry was not present in the vector before if ( iIdx != iOldIdx ) { vecStoredFaderLevels[iTempListCnt] = viOldStoredFaderLevels[iIdx]; vecStoredFaderIsSolo[iTempListCnt] = vbOldStoredFaderIsSolo[iIdx]; iTempListCnt++; } } } } } bool CAudioMixerBoard::GetStoredFaderSettings ( const CChannelInfo& ChanInfo, int& iStoredFaderLevel, bool& bStoredFaderIsSolo ) { // only do the check if the name string is not empty if ( !ChanInfo.strName.isEmpty() ) { for ( int iIdx = 0; iIdx < MAX_NUM_STORED_FADER_SETTINGS; iIdx++ ) { // check if fader text is already known in the list if ( !vecStoredFaderTags[iIdx].compare ( ChanInfo.strName ) ) { // copy stored settings values iStoredFaderLevel = vecStoredFaderLevels[iIdx]; bStoredFaderIsSolo = vecStoredFaderIsSolo[iIdx] != false; // values found and copied, return OK return true; } } } // return "not OK" since we did not find matching fader settings return false; }