diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 81d9cfe0a..25cf6b8f8 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -69,6 +69,7 @@ PClass *DefaultListMenuClass; PClass *DefaultOptionMenuClass; void I_BuildALDeviceList(FOptionValues *opt); +void I_BuildALResamplersList(FOptionValues *opt); DEFINE_GLOBAL_NAMED(OptionSettings, OptionMenuSettings) @@ -1433,6 +1434,11 @@ void M_CreateMenus() { I_BuildALDeviceList(*opt); } + opt = OptionValues.CheckKey(NAME_Alresamplers); + if (opt != nullptr) + { + I_BuildALResamplersList(*opt); + } } //============================================================================= diff --git a/src/namedef.h b/src/namedef.h index ad29da9ba..f4f9a22c8 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -713,6 +713,7 @@ xx(Crosshairs) xx(Colorpickermenu) xx(Mididevices) xx(Aldevices) +xx(Alresamplers) xx(CustomizeControls) xx(MessageOptions) xx(AutomapOptions) diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 1354bb679..203ea8955 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -65,6 +65,7 @@ FModule OpenALModule{"OpenAL"}; CVAR (String, snd_aldevice, "Default", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, snd_efx, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR (String, snd_alresampler, "Default", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) #ifdef _WIN32 #define OPENALLIB "openal32.dll" @@ -121,6 +122,32 @@ void I_BuildALDeviceList(FOptionValues *opt) #endif } +void I_BuildALResamplersList(FOptionValues *opt) +{ + opt->mValues.Resize(1); + opt->mValues[0].TextValue = "Default"; + opt->mValues[0].Text = "Default"; + +#ifndef NO_OPENAL + if (!IsOpenALPresent()) + return; + if (!alcGetCurrentContext() || !alIsExtensionPresent("AL_SOFT_source_resampler")) + return; + + LPALGETSTRINGISOFT alGetStringiSOFT = reinterpret_cast(alGetProcAddress("alGetStringiSOFT")); + ALint num_resamplers = alGetInteger(AL_NUM_RESAMPLERS_SOFT); + + unsigned int idx = opt->mValues.Reserve(num_resamplers); + for(ALint i = 0;i < num_resamplers;++i) + { + const ALchar *name = alGetStringiSOFT(AL_RESAMPLER_NAME_SOFT, i); + opt->mValues[idx].TextValue = name; + opt->mValues[idx].Text = name; + ++idx; + } +#endif +} + ReverbContainer *ForcedEnvironment; @@ -788,6 +815,7 @@ OpenALSoundRenderer::OpenALSoundRenderer() AL.EXT_SOURCE_RADIUS = !!alIsExtensionPresent("AL_EXT_SOURCE_RADIUS"); AL.SOFT_deferred_updates = !!alIsExtensionPresent("AL_SOFT_deferred_updates"); AL.SOFT_loop_points = !!alIsExtensionPresent("AL_SOFT_loop_points"); + AL.SOFT_source_resampler = !!alIsExtensionPresent("AL_SOFT_source_resampler"); alDopplerFactor(0.5f); alSpeedOfSound(343.3f * 96.0f); @@ -806,6 +834,9 @@ OpenALSoundRenderer::OpenALSoundRenderer() alProcessUpdatesSOFT = _wrap_ProcessUpdatesSOFT; } + if(AL.SOFT_source_resampler) + LOAD_FUNC(alGetStringiSOFT); + if(ALC.SOFT_pause_device) { LOAD_DEV_FUNC(Device, alcDevicePauseSOFT); @@ -958,6 +989,26 @@ OpenALSoundRenderer::OpenALSoundRenderer() if(EnvSlot) Printf(" EFX enabled\n"); + + if(AL.SOFT_source_resampler && strcmp(*snd_alresampler, "Default") != 0) + { + const ALint num_resamplers = alGetInteger(AL_NUM_RESAMPLERS_SOFT); + ALint ridx = alGetInteger(AL_DEFAULT_RESAMPLER_SOFT); + ALint i; + + for(i = 0;i < num_resamplers;i++) + { + if(strcmp(alGetStringiSOFT(AL_RESAMPLER_NAME_SOFT, i), *snd_alresampler) == 0) + { + ridx = i; + break; + } + } + if(i == num_resamplers) + Printf(TEXTCOLOR_RED" Failed to find resampler " TEXTCOLOR_ORANGE"%s\n", *snd_alresampler); + else for(ALint src : Sources) + alSourcei(src, AL_SOURCE_RESAMPLER_SOFT, ridx); + } } #undef LOAD_DEV_FUNC #undef LOAD_FUNC diff --git a/src/sound/oalsound.h b/src/sound/oalsound.h index 4a69028dc..6c79707bf 100644 --- a/src/sound/oalsound.h +++ b/src/sound/oalsound.h @@ -97,6 +97,17 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi #define AL_SOURCE_RADIUS 0x1031 #endif +#ifndef AL_SOFT_source_resampler +#define AL_SOFT_source_resampler 1 +#define AL_NUM_RESAMPLERS_SOFT 0x1210 +#define AL_DEFAULT_RESAMPLER_SOFT 0x1211 +#define AL_SOURCE_RESAMPLER_SOFT 0x1212 +#define AL_RESAMPLER_NAME_SOFT 0x1213 +typedef const ALchar* (AL_APIENTRY*LPALGETSTRINGISOFT)(ALenum pname, ALsizei index); +#ifdef AL_ALEXT_PROTOTYPES +AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index); +#endif +#endif class OpenALSoundStream; @@ -172,6 +183,7 @@ private: bool EXT_SOURCE_RADIUS; bool SOFT_deferred_updates; bool SOFT_loop_points; + bool SOFT_source_resampler; } AL; // EFX Extension function pointer variables. Loaded after context creation @@ -217,6 +229,8 @@ private: ALvoid (AL_APIENTRY*alDeferUpdatesSOFT)(void); ALvoid (AL_APIENTRY*alProcessUpdatesSOFT)(void); + LPALGETSTRINGISOFT alGetStringiSOFT; + void (ALC_APIENTRY*alcDevicePauseSOFT)(ALCdevice *device); void (ALC_APIENTRY*alcDeviceResumeSOFT)(ALCdevice *device); diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 08b2f650e..6d789497e 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2137,6 +2137,7 @@ SNDMNU_MODREPLAYER = "Module replayer options"; OPENALMNU_TITLE = "OPENAL OPTIONS"; OPENALMNU_PLAYBACKDEVICE = "Playback device"; OPENALMNU_ENABLEEFX = "Enable EFX"; +OPENALMNU_RESAMPLER = "Resampler"; // Advanced Sound Options ADVSNDMNU_TITLE = "ADVANCED SOUND OPTIONS"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 2f324f642..4f300be08 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1531,6 +1531,11 @@ OptionString ALDevices // filled in by the sound code } +OptionString ALResamplers +{ + // filled in by the sound code +} + OptionString OutputFormats { "PCM-8", "$OPTSTR_PCM8BIT" @@ -1572,8 +1577,9 @@ OptionString SoundBackendsOpenALOnly OptionMenu OpenALSoundItems { Title "$OPENALMNU_TITLE" - Option "$OPENALMNU_PLAYBACKDEVICE", "snd_aldevice", "ALDevices" - Option "$OPENALMNU_ENABLEEFX", "snd_efx", "OnOff" + Option "$OPENALMNU_PLAYBACKDEVICE", "snd_aldevice", "ALDevices" + Option "$OPENALMNU_ENABLEEFX", "snd_efx", "OnOff" + Option "$OPENALMNU_RESAMPLER", "snd_alresampler", "ALResamplers" }