diff --git a/src/cvars.cpp b/src/cvars.cpp index d0e776194..3c61539a0 100644 --- a/src/cvars.cpp +++ b/src/cvars.cpp @@ -324,12 +324,9 @@ consvar_t cv_controlperkey = Player("controlperkey", "One").values({{1, "One"}, // actual general (maximum) sound & music volume, saved into the config // Volume scale is 0-100 in new mixer. 100 is treated as -0dB or 100% gain. No more weirdness to work around SDL_mixer // problems -void MasterVolume_OnChange(void); -void DigMusicVolume_OnChange(void); -void SoundVolume_OnChange(void); -consvar_t cv_mastervolume = Player("volume", "80").min_max(0, 100).onchange_noinit(MasterVolume_OnChange); -consvar_t cv_digmusicvolume = Player("musicvolume", "80").min_max(0, 100).onchange_noinit(DigMusicVolume_OnChange); -consvar_t cv_soundvolume = Player("soundvolume", "80").min_max(0, 100).onchange_noinit(SoundVolume_OnChange); +consvar_t cv_mastervolume = Player("volume", "80").min_max(0, 100); +consvar_t cv_digmusicvolume = Player("musicvolume", "80").min_max(0, 100); +consvar_t cv_soundvolume = Player("soundvolume", "80").min_max(0, 100); #ifdef HAVE_DISCORDRPC void DRPC_UpdatePresence(void); diff --git a/src/i_sound.h b/src/i_sound.h index 7bca60cc1..29767114e 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -232,6 +232,8 @@ void I_SetCurrentSongVolume(int volume); boolean I_SetSongTrack(INT32 track); +void I_SetMasterVolume(int volume); + /// ------------------------ /// MUSIC FADING /// ------------------------ diff --git a/src/menus/options-sound.cpp b/src/menus/options-sound.cpp index 3be61bcb0..e5d0eeff6 100644 --- a/src/menus/options-sound.cpp +++ b/src/menus/options-sound.cpp @@ -97,19 +97,11 @@ struct Slider void input(INT32 c) { - if (c == -1 && &volume_ == &cv_mastervolume) + M_ChangeCvarDirect(c, &volume_); + + if (!toggle_(false)) { - // Master volume does not necessarily change when - // music or sound volumes change separately. So - // cv_mastervolume could still have its default - // value, and M_ChangeCvarDirect would do - // nothing. - CV_Set(&cv_digmusicvolume, cv_mastervolume.defaultvalue); - CV_Set(&cv_soundvolume, cv_mastervolume.defaultvalue); - } - else - { - M_ChangeCvarDirect(c, &volume_); + toggle_(true); } shake_ = !shake_; @@ -186,7 +178,7 @@ void draw_routine() sliders.at(it.mvar2).draw( x, y, - it.mvar2 == Slider::kMasterVolume, + false, i == itemOn ); } diff --git a/src/s_sound.c b/src/s_sound.c index 908a10923..885f6d1c2 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -660,6 +660,7 @@ void S_StopSound(void *origin) // static INT32 actualsfxvolume; // check for change through console static INT32 actualdigmusicvolume; +static INT32 actualmastervolume; void S_UpdateSounds(void) { @@ -676,6 +677,8 @@ void S_UpdateSounds(void) S_SetSfxVolume(); if (actualdigmusicvolume != cv_digmusicvolume.value) S_SetMusicVolume(); + if (actualmastervolume != cv_mastervolume.value) + S_SetMasterVolume(); // We're done now, if we're not in a level. if (gamestate != GS_LEVEL) @@ -869,6 +872,13 @@ void S_SetSfxVolume(void) I_SetSfxVolume(actualsfxvolume); } +void S_SetMasterVolume(void) +{ + actualmastervolume = cv_mastervolume.value; + + I_SetMasterVolume(actualmastervolume); +} + void S_ClearSfx(void) { size_t i; @@ -2325,6 +2335,7 @@ static void Command_RestartAudio_f(void) S_SetSfxVolume(); S_SetMusicVolume(); + S_SetMasterVolume(); S_StartSound(NULL, sfx_strpst); @@ -2492,6 +2503,9 @@ void GameSounds_OnChange(void) if (M_CheckParm("-nosound") || M_CheckParm("-noaudio")) return; + if (cv_gamesounds.value != sound_disabled) + return; + if (sound_disabled) { sound_disabled = false; @@ -2514,6 +2528,9 @@ void GameDigiMusic_OnChange(void) else if (M_CheckParm("-nodigmusic")) return; + if (cv_gamedigimusic.value != digital_disabled) + return; + if (digital_disabled) { digital_disabled = false; @@ -2528,49 +2545,6 @@ void GameDigiMusic_OnChange(void) } } -void MasterVolume_OnChange(void); -void MasterVolume_OnChange(void) -{ - INT32 adj = cv_mastervolume.value - max(cv_digmusicvolume.value, cv_soundvolume.value); - - if (adj < 0) - { - INT32 under = min(cv_digmusicvolume.value, cv_soundvolume.value) + adj; - - if (under < 0) - { - // Ensure balance between music/sound volume does - // not change at lower bound. (This is already - // guaranteed at upper bound.) - adj -= under; - CV_StealthSetValue(&cv_mastervolume, cv_mastervolume.value - under); - } - } - - CV_SetValue(&cv_digmusicvolume, cv_digmusicvolume.value + adj); - CV_SetValue(&cv_soundvolume, cv_soundvolume.value + adj); -} - -void DigMusicVolume_OnChange(void); -void DigMusicVolume_OnChange(void) -{ - if (!cv_gamedigimusic.value && !con_startup) - { - CV_SetValue(&cv_gamedigimusic, 1); - } - CV_StealthSetValue(&cv_mastervolume, max(cv_digmusicvolume.value, cv_soundvolume.value)); -} - -void SoundVolume_OnChange(void); -void SoundVolume_OnChange(void) -{ - if (!cv_gamesounds.value && !con_startup) - { - CV_SetValue(&cv_gamesounds, 1); - } - CV_StealthSetValue(&cv_mastervolume, max(cv_digmusicvolume.value, cv_soundvolume.value)); -} - void BGAudio_OnChange(void); void BGAudio_OnChange(void) { diff --git a/src/s_sound.h b/src/s_sound.h index cb22dfd74..94dc4935a 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -33,7 +33,7 @@ extern "C" { #define DEFAULT_MUSICDEF_VOLUME 100 extern consvar_t stereoreverse; -extern consvar_t cv_soundvolume, cv_closedcaptioning, cv_digmusicvolume; +extern consvar_t cv_soundvolume, cv_closedcaptioning, cv_digmusicvolume; extern consvar_t surround; extern consvar_t cv_numChannels; @@ -246,6 +246,7 @@ INT32 S_GetSoundVolume(sfxinfo_t *sfx, INT32 volume); void S_SetSfxVolume(void); void S_SetMusicVolume(void); +void S_SetMasterVolume(void); INT32 S_OriginPlaying(void *origin); INT32 S_IdPlaying(sfxenum_t id); diff --git a/src/sdl/new_sound.cpp b/src/sdl/new_sound.cpp index 91225367c..941e1d0f3 100644 --- a/src/sdl/new_sound.cpp +++ b/src/sdl/new_sound.cpp @@ -55,7 +55,8 @@ using namespace srb2::io; // extern in i_sound.h UINT8 sound_started = false; -static unique_ptr> master; +static unique_ptr> master_gain; +static shared_ptr> master; static shared_ptr> mixer_sound_effects; static shared_ptr> mixer_music; static shared_ptr music_player; @@ -144,10 +145,10 @@ void audio_callback(void* userdata, Uint8* buffer, int len) float_buffer[i] = Sample<2> {0.f, 0.f}; } - if (!master) + if (!master_gain) return; - master->generate(tcb::span {float_buffer, float_len}); + master_gain->generate(tcb::span {float_buffer, float_len}); for (size_t i = 0; i < float_len; i++) { @@ -197,7 +198,9 @@ void initialize_sound() { SdlAudioLockHandle _; - master = make_unique>(); + master_gain = make_unique>(); + master = make_shared>(); + master_gain->bind(master); mixer_sound_effects = make_shared>(); mixer_music = make_shared>(); music_player = make_shared(); @@ -378,6 +381,17 @@ void I_SetSfxVolume(int volume) } } +void I_SetMasterVolume(int volume) +{ + SdlAudioLockHandle _; + float vol = static_cast(volume) / 100.f; + + if (master_gain) + { + master_gain->gain(std::clamp(vol * vol * vol, 0.f, 1.f)); + } +} + /// ------------------------ // MUSIC SYSTEM /// ------------------------