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 )