Merge pull request #654 from ryzom/feature/change-sound-driver-ingame

Feature/change sound driver ingame
core4
nimetu 3 years ago committed by GitHub
commit b184192bc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -127,6 +127,12 @@ public:
/// Return driver name from type.
static const char *getDriverName(TDriver driverType);
/// Return driver dll filename, empty if unsupported driver
static std::string getDriverFileName(TDriver driverType);
/** Return possibly available drivers for current platform.
* If no drivers are available, return empty list.
*/
static std::vector<ISoundDriver::TDriver> getAvailableDrivers();
/** The static method which builds the sound driver instance
* In case of failure, can throw one of these ESoundDriver exception objects:
* ESoundDriverNotFound, ESoundDriverCorrupted, ESoundDriverOldVersion, ESoundDriverUnknownVersion
@ -204,7 +210,6 @@ public:
private:
std::string _DllName;
};

@ -90,6 +90,13 @@ public:
NumDrivers
};
struct TDriverInfo
{
TDriver ID;
const char *Name;
TDriverInfo(TDriver id, const char *name) : ID(id), Name(name)
{}
};
/** Structure that contain the background flags.*/
struct TBackgroundFlags
@ -162,7 +169,10 @@ public:
/// I forgot what this does, but it's fairly important.
bool AutoLoadSample;
};
/// Return list of available sound drivers
static std::vector<TDriverInfo> getDrivers();
//@{
//@name Init methods
/// Create the audio mixer singleton and return a pointer to its instance
@ -212,7 +222,7 @@ public:
* \param forceSoftware: to force the driver to load in software buffer, not hardware
*/
virtual void init(uint maxTrack = 32, bool useEax = true, bool useADPCM = true, NLMISC::IProgressCallback *progressCallBack = NULL, bool autoLoadSample = false, TDriver driverType = DriverAuto, bool forceSoftware = false, bool manualRolloff = true) = 0;
/// Initialize the NeL Sound Driver with given driverName.
virtual void initDriver(const std::string &driverName) = 0;
/// Get the available devices on the loaded driver.

@ -67,16 +67,23 @@ void Init()
AudioMixer->setPackedSheetOption("data", true);
printf("Select NLSOUND Driver:\n");
printf(" [1] FMod\n");
printf(" [2] OpenAl\n");
printf(" [3] DSound\n");
printf(" [4] XAudio2\n");
std::vector<UAudioMixer::TDriverInfo> drivers = UAudioMixer::getDrivers();
if (drivers.size() == 0)
nlerror("No sound drivers available");
for(uint i = 0; i < drivers.size(); ++i)
printf(" [%d] %s\n", i, drivers[i].Name);
printf("> ");
int selection = getchar();
int selection = getchar() - '0';
printf("\n");
UAudioMixer::TDriver selectedDriver = UAudioMixer::DriverAuto;
if (selection >= 0 && selection < drivers.size())
selectedDriver = drivers[selection].ID;
// init with 32 tracks, EAX enabled, no ADPCM, and activate automatic sample bank loading
AudioMixer->init(32, true, false, NULL, true, (UAudioMixer::TDriver)(selection - '0')/*UAudioMixer::DriverFMod*/);
AudioMixer->init(32, true, false, NULL, true, selectedDriver);
/*
* 2. Initialize listener's position and orientation (in NeL coordinate system).

@ -131,6 +131,39 @@ CAudioMixerUser::CAudioMixerUser() : _AutoLoadSample(false),
}
}
// ******************************************************************
std::vector<UAudioMixer::TDriverInfo> UAudioMixer::getDrivers()
{
std::vector<TDriverInfo> drivers;
std::vector<ISoundDriver::TDriver> drv = ISoundDriver::getAvailableDrivers();
for(uint i = 0; i < drv.size(); ++i)
{
switch(drv[i])
{
case ISoundDriver::DriverAuto:
drivers.push_back(TDriverInfo(DriverAuto, ISoundDriver::getDriverName(drv[i])));
break;
case ISoundDriver::DriverFMod:
drivers.push_back(TDriverInfo(DriverFMod, ISoundDriver::getDriverName(drv[i])));
break;
case ISoundDriver::DriverDSound:
drivers.push_back(TDriverInfo(DriverDSound, ISoundDriver::getDriverName(drv[i])));
break;
case ISoundDriver::DriverOpenAl:
drivers.push_back(TDriverInfo(DriverOpenAl, ISoundDriver::getDriverName(drv[i])));
break;
case ISoundDriver::DriverXAudio2:
drivers.push_back(TDriverInfo(DriverXAudio2, ISoundDriver::getDriverName(drv[i])));
break;
default:
nlwarning("Unknown driver id %d, name '%s'", drv[i], ISoundDriver::getDriverName(drv[i]));
break;
}
}
return drivers;
}
// ******************************************************************
@ -374,16 +407,42 @@ void CAudioMixerUser::initDriver(const std::string &driverName)
std::string dn = NLMISC::toLowerAscii(driverName);
nldebug("AM: Init Driver '%s' ('%s')...", driverName.c_str(), dn.c_str());
ISoundDriver::TDriver driverType;
if (dn == "auto") driverType = ISoundDriver::DriverAuto;
else if (dn == "fmod") driverType = ISoundDriver::DriverFMod;
else if (dn == "dsound") driverType = ISoundDriver::DriverDSound;
else if (dn == "openal") driverType = ISoundDriver::DriverOpenAl;
else if (dn == "xaudio2") driverType = ISoundDriver::DriverXAudio2;
else
TDriver driverId = dn == "auto" ? DriverAuto : NumDrivers;
if (driverId == NumDrivers)
{
driverType = ISoundDriver::DriverAuto;
nlwarning("AM: driverName value '%s' ('%s') is invalid.", driverName.c_str(), dn.c_str());
std::vector<TDriverInfo> drivers = UAudioMixer::getDrivers();
for(uint i = 0; i < drivers.size(); ++i)
{
if (nlstricmp(drivers[i].Name, dn.c_str()) == 0)
{
driverId = drivers[i].ID;
break;
}
}
}
ISoundDriver::TDriver driverType;
switch(driverId)
{
case DriverAuto:
driverType = ISoundDriver::DriverAuto;
break;
case DriverFMod:
driverType = ISoundDriver::DriverFMod;
break;
case DriverDSound:
driverType = ISoundDriver::DriverDSound;
break;
case DriverOpenAl:
driverType = ISoundDriver::DriverOpenAl;
break;
case DriverXAudio2:
driverType = ISoundDriver::DriverXAudio2;
break;
case NumDrivers:
driverType = ISoundDriver::DriverAuto;
nlwarning("AM: driverName value '%s' ('%s') is not available.", driverName.c_str(), dn.c_str());
break;
}
try

@ -57,7 +57,7 @@ namespace NLSOUND
/// Interface version, increase when any part of sound_lowlevel is changed.
/// Put your name in comment to make sure you don't commit with
/// the same interface version number as someone else.
const uint32 ISoundDriver::InterfaceVersion = 0x16; // Kaetemi
const uint32 ISoundDriver::InterfaceVersion = 0x17; // Nimetu
#ifdef NL_STATIC
@ -104,6 +104,138 @@ const char *ISoundDriver::getDriverName(TDriver driverType)
}
}
/// Return driver filename from type.
std::string ISoundDriver::getDriverFileName(TDriver driverType)
{
switch(driverType)
{
case DriverFMod:
#if defined (NL_COMP_MINGW)
return "libnel_drv_fmod_win";
#elif defined (NL_OS_WINDOWS)
return "nel_drv_fmod_win";
#elif defined (NL_OS_UNIX)
return "nel_drv_fmod";
#else
# error "Driver name not define for this platform"
#endif // NL_OS_UNIX / NL_OS_WINDOWS
break;
case DriverOpenAl:
#if defined (NL_COMP_MINGW)
return "libnel_drv_openal_win";
#elif defined (NL_OS_WINDOWS)
return "nel_drv_openal_win";
#elif defined (NL_OS_UNIX)
return "nel_drv_openal";
#else
# error "Driver name not define for this platform"
#endif
break;
case DriverDSound:
#if defined (NL_COMP_MINGW)
return "libnel_drv_dsound_win";
#elif defined (NL_OS_WINDOWS)
return "nel_drv_dsound_win";
#elif defined (NL_OS_UNIX)
return "";
#else
# error "Driver name not define for this platform"
#endif
break;
case DriverXAudio2:
#if defined (NL_COMP_MINGW)
return "libnel_drv_xaudio2_win";
#elif defined (NL_OS_WINDOWS)
return "nel_drv_xaudio2_win";
#elif defined (NL_OS_UNIX)
return "";
#else
# error "Driver name not define for this platform"
#endif
break;
case DriverAuto:
#if defined (NL_COMP_MINGW)
return "libnel_drv_xaudio2_win";
#elif defined (NL_OS_WINDOWS)
return "nel_drv_xaudio2_win";
#elif defined (NL_OS_UNIX)
return "nel_drv_openal";
#else
# error "Driver name not define for this platform"
#endif
break;
default:
break;
}
return "";
}
///
std::vector<ISoundDriver::TDriver> ISoundDriver::getAvailableDrivers()
{
static std::vector<TDriver> m_AvailableDrivers;
if (!m_AvailableDrivers.empty())
return m_AvailableDrivers;
#ifdef NL_STATIC
# ifdef NL_FMOD_AVAILABLE
m_AvailableDrivers.push_back(DriverFMod);
# endif
# ifdef NL_OPENAL_AVAILABLE
m_AvailableDrivers.push_back(DriverOpenAl);
# endif
# ifdef NL_DSOUND_AVAILABLE
m_AvailableDrivers.push_back(DriverDSound);
# endif
# ifdef NL_XAUDIO2_AVAILABLE
m_AvailableDrivers.push_back(DriverXAudio2);
# endif
#else // NL_STATIC
const std::vector<TDriver> vec = {
DriverFMod,
DriverOpenAl,
DriverDSound,
DriverXAudio2,
};
#if 0
// if platform has dynamic driver name set, consider it as available
for(uint i = 0; i < vec.size(); i++)
{
std::string dllName = getDriverFileName(vec[i]);
if(!dllName.empty())
m_AvailableDrivers.push_back(vec[i]);
}
#else
CLibrary driverLib;
#if defined(NL_OS_UNIX) && defined(NL_DRIVER_PREFIX)
driverLib.addLibPath(NL_DRIVER_PREFIX);
#endif
nlinfo("Detecting available sound drivers");
for(uint i = 0; i < vec.size(); i++)
{
std::string dllName = getDriverFileName(vec[i]);
if(!dllName.empty())
{
// Load it (adding standard nel pre/suffix, looking in library path and taking ownership)
if (driverLib.loadLibrary(dllName, true, true, true))
{
m_AvailableDrivers.push_back(vec[i]);
driverLib.freeLibrary();
}
}
}
#endif
#endif
return m_AvailableDrivers;
}
/*
* The static method which builds the sound driver instance
*/
@ -151,67 +283,9 @@ ISoundDriver *ISoundDriver::createDriver(IStringMapperProvider *stringMapper, TD
ISDRV_VERSION_PROC versionDriver = NULL;
// dll selected
std::string dllName;
// Choose the DLL
switch(driverType)
{
case DriverFMod:
#if defined (NL_COMP_MINGW)
dllName = "libnel_drv_fmod_win";
#elif defined (NL_OS_WINDOWS)
dllName = "nel_drv_fmod_win";
#elif defined (NL_OS_UNIX)
dllName = "nel_drv_fmod";
#else
# error "Driver name not define for this platform"
#endif // NL_OS_UNIX / NL_OS_WINDOWS
break;
case DriverOpenAl:
#if defined (NL_COMP_MINGW)
dllName = "libnel_drv_openal_win";
#elif defined (NL_OS_WINDOWS)
dllName = "nel_drv_openal_win";
#elif defined (NL_OS_UNIX)
dllName = "nel_drv_openal";
#else
# error "Driver name not define for this platform"
#endif
break;
case DriverDSound:
#if defined (NL_COMP_MINGW)
dllName = "libnel_drv_dsound_win";
#elif defined (NL_OS_WINDOWS)
dllName = "nel_drv_dsound_win";
#elif defined (NL_OS_UNIX)
nlerror("DriverDSound doesn't exist on Unix because it requires DirectX");
#else
# error "Driver name not define for this platform"
#endif
break;
case DriverXAudio2:
#if defined (NL_COMP_MINGW)
dllName = "libnel_drv_xaudio2_win";
#elif defined (NL_OS_WINDOWS)
dllName = "nel_drv_xaudio2_win";
#elif defined (NL_OS_UNIX)
nlerror("DriverXAudio2 doesn't exist on Unix because it requires DirectX");
#else
# error "Driver name not define for this platform"
#endif
break;
default:
#if defined (NL_COMP_MINGW)
dllName = "libnel_drv_xaudio2_win";
#elif defined (NL_OS_WINDOWS)
dllName = "nel_drv_xaudio2_win";
#elif defined (NL_OS_UNIX)
dllName = "nel_drv_openal";
#else
# error "Driver name not define for this platform"
#endif
break;
}
std::string dllName = getDriverFileName(driverType);
if (dllName.empty())
throw ESoundDriverCantCreateDriver(("Driver '%s' not available for this platform", ISoundDriver::getDriverName(driverType)));
CLibrary driverLib;

@ -138,6 +138,7 @@
<variable entry="UI:TEMP:TEXTURE_MODE" type="sint32" value="0" />
<variable entry="UI:TEMP:LANGUAGE" type="sint32" value="0" />
<variable entry="UI:TEMP:SCREEN_RATIO_MODE" type="sint32" value="0" />
<variable entry="UI:TEMP:SOUND_DRIVER" type="sint32" value="0" />
<define id="game_config_screen_ratio_eb" value="ui:interface:game_config:content:general:screen_ratio:edit:eb" />
<define id="game_config_screen_ratio_cb" value="ui:interface:game_config:content:general:screen_ratio:combo" />
@ -683,7 +684,14 @@
<view style="sgc_title" type="text" id="gen" posref="TM TM" x="0" y="0" hardtext="uiSoundGeneral" />
<instance template="tgcw_checkbox" id="enabler" text="uiSoundOnOff" posref="TL TL" x="0" y="-16" />
<instance template="tgcw_checkbox" id="useeax" text="uiUseEax" posref="BL TL" posparent="enabler" x="0" y="-12" />
<group id="driver_gr" posparent="enabler" sizeparent="parent" sizeref="w" h="20" posref="BL TL" x="0" y="-12">
<view type="text" id="text" posref="TL TL" x="0" y="-4" color="255 255 255 192" fontsize="12" shadow="true" hardtext="uigcSoundDriver" />
<group type="combo_box" id="driver" w="70" h="20" value="UI:TEMP:SOUND_DRIVER" posref="MR ML" posparent="text" x="4" y="0">
<instance template="combo_box_def1" />
</group>
<link expr="@UI:TEMP:SOUND_DRIVER" action="game_config_change_sound_driver" />
</group>
<instance template="tgcw_checkbox" id="useeax" text="uiUseEax" posref="BL TL" posparent="driver_gr" x="0" y="-12" />
<instance template="tgcw_checkbox" id="forcesoftbuf" text="uiSoundFSB" posref="BL TL" posparent="useeax" x="0" y="-12" />
<view style="sgc_title2" type="text" id="perf" posparent="forcesoftbuf" posref="BL TL" x="0" y="-8" hardtext="uiSoundPerf" />
<instance template="tgcw_scrollbarint" id="maxtrack" text="uiMaxTracks" posparent="perf" posref="BL TL" x="20" y="-2" />

@ -95,6 +95,8 @@
#include "nel/gui/ctrl_button.h"
#include "../global.h"
#include "nel/sound/u_audio_mixer.h"
using namespace std;
using namespace NL3D;
using namespace NLMISC;
@ -2984,6 +2986,10 @@ static vector<UDriver::CMode> VideoModes;
#define GAME_CONFIG_ANISOTROPIC_COMBO "ui:interface:game_config:content:fx:anisotropic_gr:anisotropic"
#define GAME_CONFIG_ANISOTROPIC_DB "UI:TEMP:ANISOTROPIC"
// Sound driver
#define GAME_CONFIG_SOUND_DRIVER_COMBO "ui:interface:game_config:content:sound:driver_gr:driver"
#define GAME_CONFIG_SOUND_DRIVER_DB "UI:TEMP:SOUND_DRIVER"
// The 3 possible modes editable (NB: do not allow client.cfg HDEntityTexture==1 and DivideTextureSizeBy2=2
enum TTextureMode {LowTextureMode= 0, NormalTextureMode= 1, HighTextureMode= 2};
@ -3031,6 +3037,77 @@ void updateVRDevicesComboUI(bool enable)
}
}
// ***************************************************************************
void updateSoundDriverComboUI()
{
CDBGroupComboBox *pCB = dynamic_cast<CDBGroupComboBox*>(CWidgetManager::getInstance()->getElementFromId(GAME_CONFIG_SOUND_DRIVER_COMBO));
if (!pCB)
{
nlwarning("Sound driver UI element '%s' not found", GAME_CONFIG_SOUND_DRIVER_COMBO);
return;
}
pCB->resetTexts();
uint32 selected = 0;
NLSOUND::UAudioMixer::TDriver cfgDriverId = NLSOUND::UAudioMixer::DriverAuto;
if(ClientCfg.DriverSound==CClientConfig::SoundDrvFMod)
cfgDriverId = NLSOUND::UAudioMixer::DriverFMod;
else if(ClientCfg.DriverSound==CClientConfig::SoundDrvOpenAL)
cfgDriverId = NLSOUND::UAudioMixer::DriverOpenAl;
else if(ClientCfg.DriverSound==CClientConfig::SoundDrvDirectSound)
cfgDriverId = NLSOUND::UAudioMixer::DriverDSound;
else if(ClientCfg.DriverSound==CClientConfig::SoundDrvXAudio2)
cfgDriverId = NLSOUND::UAudioMixer::DriverXAudio2;
std::vector<NLSOUND::UAudioMixer::TDriverInfo> drivers = NLSOUND::UAudioMixer::getDrivers();
// add AUTO for ingame selection, if one is not already in list
bool found = false;
for(uint i = 0; i < drivers.size(); ++i)
{
if (drivers[i].ID == NLSOUND::UAudioMixer::DriverAuto)
{
found = true;
break;
}
}
if (!found)
drivers.insert(drivers.begin(), 1, NLSOUND::UAudioMixer::TDriverInfo(NLSOUND::UAudioMixer::DriverAuto, "Auto"));
for(uint i = 0; i < drivers.size(); ++i)
{
switch(drivers[i].ID)
{
case NLSOUND::UAudioMixer::DriverAuto:
pCB->addText("Auto");
break;
case NLSOUND::UAudioMixer::DriverFMod:
pCB->addText("FMod");
break;
case NLSOUND::UAudioMixer::DriverDSound:
pCB->addText("DirectSound");
break;
case NLSOUND::UAudioMixer::DriverOpenAl:
pCB->addText("OpenAL");
break;
case NLSOUND::UAudioMixer::DriverXAudio2:
pCB->addText("XAudio2");
break;
default:
pCB->addText(drivers[i].Name);
break;
}
if (cfgDriverId == drivers[i].ID)
selected = i;
}
NLGUI::CDBManager::getInstance()->getDbProp(GAME_CONFIG_SOUND_DRIVER_DB)->setValue32(-1);
NLGUI::CDBManager::getInstance()->getDbProp(GAME_CONFIG_SOUND_DRIVER_DB)->setValue32(selected);
}
// ***************************************************************************
class CHandlerGameConfigInit : public IActionHandler
{
@ -3083,6 +3160,8 @@ public:
}
CAHManager::getInstance()->runActionHandler("game_config_change_vid_fullscreen",NULL);
updateSoundDriverComboUI();
// **** Init Texture Size Modes
// init the combo box, according to Texture Installed or not
pCB = dynamic_cast<CDBGroupComboBox*>(CWidgetManager::getInstance()->getElementFromId( GAME_CONFIG_TEXTURE_MODE_COMBO ));
@ -3439,6 +3518,32 @@ class CHandlerGameConfigVRDevice : public IActionHandler
};
REGISTER_ACTION_HANDLER (CHandlerGameConfigVRDevice, "game_config_change_vr_device");
// ***************************************************************************
class CHandlerGameConfigSoundDriver : public IActionHandler
{
virtual void execute (CCtrlBase * pCaller, const string &/* Params */)
{
sint oldDriver = NLGUI::CDBManager::getInstance()->getDbProp(GAME_CONFIG_SOUND_DRIVER_DB)->getOldValue32();
sint newDriver = NLGUI::CDBManager::getInstance()->getDbProp(GAME_CONFIG_SOUND_DRIVER_DB)->getValue32();
if (oldDriver != -1 && newDriver != oldDriver)
{
CDBGroupComboBox *pCB = dynamic_cast<CDBGroupComboBox*>(CWidgetManager::getInstance()->getElementFromId(GAME_CONFIG_SOUND_DRIVER_COMBO));
if (!pCB)
{
nlwarning("Unable to change sound driver. UI '%s' not found.", GAME_CONFIG_SOUND_DRIVER_COMBO);
return;
}
CDDXManager *pDM = CDDXManager::getInstance();
CInterfaceDDX *pDDX = pDM->get(GAME_CONFIG_DDX);
if(pDDX)
pDDX->validateApplyButton();
}
}
};
REGISTER_ACTION_HANDLER (CHandlerGameConfigSoundDriver, "game_config_change_sound_driver");
// ***************************************************************************
class CHandlerGameConfigApply : public IActionHandler
{
@ -3545,6 +3650,17 @@ class CHandlerGameConfigApply : public IActionHandler
ClientCfg.writeString("VRDisplayDeviceId", VRDeviceCache[deviceIdx].second);
}
sint sndDriver = NLGUI::CDBManager::getInstance()->getDbProp(GAME_CONFIG_SOUND_DRIVER_DB)->getValue32();
if (sndDriver != -1)
{
CDBGroupComboBox *pCB = dynamic_cast<CDBGroupComboBox*>(CWidgetManager::getInstance()->getElementFromId(GAME_CONFIG_SOUND_DRIVER_COMBO));
if (pCB)
{
std::string drv = pCB->getText(sndDriver);
ClientCfg.writeString("DriverSound", drv);
}
}
bool requestReboot = false;
// **** Apply the texture mode

@ -324,8 +324,19 @@ void updateFromClientCfg()
bool mustReloadSoundMngrContinent= false;
// disable/enable sound?
if (ClientCfg.SoundOn != LastClientCfg.SoundOn)
if (ClientCfg.SoundOn != LastClientCfg.SoundOn || ClientCfg.DriverSound != LastClientCfg.DriverSound)
{
// changing sound driver
if (ClientCfg.DriverSound != LastClientCfg.DriverSound)
{
if (SoundMngr)
{
nlwarning("Changing sound driver...");
delete SoundMngr;
SoundMngr = NULL;
}
}
if (SoundMngr && !ClientCfg.SoundOn)
{
nlwarning("Deleting sound manager...");

Loading…
Cancel
Save