diff --git a/src/client.cpp b/src/client.cpp index cf8da89978..f86d471206 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -526,9 +526,18 @@ QString CClient::SetSndCrdDev ( const QString strNewDev ) const QString strError = Sound.SetDev ( strNewDev ); - // init again because the sound card actual buffer size might - // be changed on new device - Init(); + if ( strError.isEmpty() ) + { + // init again because the sound card actual buffer size might + // be changed on new device + Init(); + } + else + { + bFraSiFactPrefSupported = false; + bFraSiFactDefSupported = false; + bFraSiFactSafeSupported = false; + } if ( bWasRunning ) { @@ -536,11 +545,8 @@ QString CClient::SetSndCrdDev ( const QString strNewDev ) Sound.Start(); } - // in case of an error inform the GUI about it - if ( !strError.isEmpty() ) - { - emit SoundDeviceChanged ( strError ); - } + // inform the GUI about change in state + emit SoundDeviceChanged ( strError ); return strError; } diff --git a/src/clientdlg.cpp b/src/clientdlg.cpp index 993a343f72..c7a1b6be1d 100755 --- a/src/clientdlg.cpp +++ b/src/clientdlg.cpp @@ -1195,6 +1195,7 @@ void CClientDlg::OnSoundDeviceChanged ( QString strError ) } // update the settings dialog + ClientSettingsDlg.SetDeviceErrors ( strError ); ClientSettingsDlg.UpdateSoundDeviceChannelSelectionFrame(); } diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index b86556d62b..08a784d719 100755 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -104,6 +104,9 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, "panel." ) + TOOLTIP_COM_END_TEXT ); #endif + lblErrors->setText ( pSettings->strLoadErrors ); + lblErrors->setWordWrap ( true ); + // sound card input/output channel mapping QString strSndCrdChanMapp = "" + tr ( "Sound Card Channel Mapping" ) + ": " + tr ( "If the selected sound card device offers more than one " @@ -481,6 +484,11 @@ QString CClientSettingsDlg::GenSndCrdBufferDelayString ( const int iFrameSiz QString().setNum ( iFrameSize ) + strAddText + ")"; } +void CClientSettingsDlg::SetDeviceErrors ( const QString& strError ) +{ + lblErrors->setText ( strError ); +} + void CClientSettingsDlg::UpdateSoundCardFrame() { // get current actual buffer size value diff --git a/src/clientsettingsdlg.h b/src/clientsettingsdlg.h index d6fef72c3b..d3fb175b8b 100755 --- a/src/clientsettingsdlg.h +++ b/src/clientsettingsdlg.h @@ -73,6 +73,7 @@ class CClientSettingsDlg : public CBaseDlg, private Ui_CClientSettingsDlgBase const CMultiColorLED::ELightColor eOverallDelayLEDColor ); void UpdateDisplay(); + void SetDeviceErrors ( const QString& strError ); void UpdateSoundDeviceChannelSelectionFrame(); protected: diff --git a/src/clientsettingsdlgbase.ui b/src/clientsettingsdlgbase.ui index dd36343733..04f9fd01e6 100755 --- a/src/clientsettingsdlgbase.ui +++ b/src/clientsettingsdlgbase.ui @@ -49,6 +49,10 @@ + + + + diff --git a/src/settings.cpp b/src/settings.cpp index 903032d2ce..ce32f35eec 100755 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -352,14 +352,7 @@ void CClientSettings::ReadSettingsFromXML ( const QDomDocument& IniXMLDocument // sound card selection const QString strError = pClient->SetSndCrdDev ( FromBase64ToString ( GetIniSetting ( IniXMLDocument, "client", "auddev_base64", "" ) ) ); - if ( !strError.isEmpty() ) - { -#ifndef HEADLESS - // special case: when settings are loaded no GUI is yet created, therefore - // we have to create a warning message box here directly - QMessageBox::warning ( nullptr, APP_NAME, strError ); -#endif - } + strLoadErrors = strError; // sound card channel mapping settings: make sure these settings are // set AFTER the sound card device is set, otherwise the settings are diff --git a/src/settings.h b/src/settings.h index 55a5aecfc6..27fd011a0b 100755 --- a/src/settings.h +++ b/src/settings.h @@ -189,6 +189,7 @@ class CClientSettings : public CSettings bool bWindowWasShownProfile; bool bWindowWasShownConnect; + QString strLoadErrors; protected: // No CommandLineOptions used when reading Client inifile virtual void WriteSettingsToXML ( QDomDocument& IniXMLDocument ) override; diff --git a/src/soundbase.cpp b/src/soundbase.cpp index 50a3b9d283..b2ab061cf4 100755 --- a/src/soundbase.cpp +++ b/src/soundbase.cpp @@ -80,12 +80,20 @@ QStringList CSoundBase::GetDevNames() QStringList slDevNames; + bool currentInList = false; + // put all device names in the string list for ( int iDev = 0; iDev < lNumDevs; iDev++ ) { + currentInList |= ( strDriverNames[iDev] == strCurDevName ); slDevNames << strDriverNames[iDev]; } + if ( !currentInList ) + { + slDevNames << strCurDevName; + } + return slDevNames; } @@ -94,114 +102,9 @@ QString CSoundBase::SetDev ( const QString strDevName ) { QMutexLocker locker ( &MutexDevProperties ); - // init return parameter with "no error" - QString strReturn = ""; - - // init flag for "load any driver" - bool bTryLoadAnyDriver = false; - - // check if an ASIO driver was already initialized - if ( !strCurDevName.isEmpty() ) - { - // a device was already been initialized and is used, first clean up - // driver - UnloadCurrentDriver(); - - const QString strErrorMessage = LoadAndInitializeDriver ( strDevName, false ); - - if ( !strErrorMessage.isEmpty() ) - { - if ( strDevName != strCurDevName ) - { - // loading and initializing the new driver failed, go back to - // original driver and create error message - LoadAndInitializeDriver ( strCurDevName, false ); - - // store error return message - strReturn = QString ( tr ( "The selected audio device could not be used " - "because of the following error: " ) ) + strErrorMessage + - QString ( tr ( " The previous driver will be selected." ) ); - } - else - { - // loading and initializing the current driver failed, try to find - // at least one usable driver - bTryLoadAnyDriver = true; - } - } - } - else - { - if ( !strDevName.isEmpty() ) - { - // This is the first time a driver is to be initialized, we first - // try to load the selected driver, if this fails, we try to load - // the first available driver in the system. If this fails, too, we - // throw an error that no driver is available -> it does not make - // sense to start the software if no audio hardware is available. - if ( !LoadAndInitializeDriver ( strDevName, false ).isEmpty() ) - { - // loading and initializing the new driver failed, try to find - // at least one usable driver - bTryLoadAnyDriver = true; - } - } - else - { - // try to find one usable driver (select the first valid driver) - bTryLoadAnyDriver = true; - } - } - - if ( bTryLoadAnyDriver ) - { - // if a driver was previously selected, show a warning message - if ( !strDevName.isEmpty() ) - { - strReturn = tr ( "The previously selected audio device " - "is no longer available or the audio driver properties have changed to a state which " - "is incompatible with this software. We now try to find a valid audio device. This new " - "audio device might cause audio feedback. So, before connecting to a server, please " - "check the audio device setting." ); - } - - // try to load and initialize any valid driver - QVector vsErrorList = LoadAndInitializeFirstValidDriver(); - - if ( !vsErrorList.isEmpty() ) - { - // create error message with all details - QString sErrorMessage = "" + tr ( "No usable " ) + - strSystemDriverTechniqueName + tr ( " audio device " - "(driver) found." ) + "

" + tr ( - "In the following there is a list of all available drivers " - "with the associated error message:" ) + "
    "; - - for ( int i = 0; i < lNumDevs; i++ ) - { - sErrorMessage += "
  • " + GetDeviceName ( i ) + ": " + vsErrorList[i] + "
  • "; - } - sErrorMessage += "
"; - -#ifdef _WIN32 - // to be able to access the ASIO driver setup for changing, e.g., the sample rate, we - // offer the user under Windows that we open the driver setups of all registered - // ASIO drivers - sErrorMessage = sErrorMessage + "
" + tr ( "Do you want to open the ASIO driver setups?" ); - - if ( QMessageBox::Yes == QMessageBox::information ( nullptr, APP_NAME, sErrorMessage, QMessageBox::Yes|QMessageBox::No ) ) - { - LoadAndInitializeFirstValidDriver ( true ); - } - - sErrorMessage = APP_NAME + tr ( " could not be started because of audio interface issues." ); -#endif - - throw CGenErr ( sErrorMessage ); - } - } + strCurDevName = strDevName; // Update current device, even if loading fails. - return strReturn; + return LoadAndInitializeDriver ( strDevName, false ); } QVector CSoundBase::LoadAndInitializeFirstValidDriver ( const bool bOpenDriverSetup )