From 55fafb7d25fe5a127332e3e9f3e54e54ec1ec20c Mon Sep 17 00:00:00 2001 From: Muhammad Rifqi Priyo Susanto Date: Mon, 11 Dec 2023 01:11:39 +0700 Subject: [PATCH] Add sound volume when unfocused setting (#14083) This adds a new setting to set sound volume multiplier when Minetest window is unfocused/inactive (sound_volume_unfocused, located in Settings > Graphics and Audio > Audio > Volume when unfocused). If the window is not focused, the sound volume will be multiplied by sound_volume_unfocused setting. The sound volume will be set back to sound_volume again when the window is focused. --- builtin/settingtypes.txt | 3 +++ src/client/game.cpp | 14 +------------- src/client/sound.cpp | 24 ++++++++++++++++++++++++ src/client/sound.h | 6 ++++++ src/defaultsettings.cpp | 1 + src/gui/guiEngine.cpp | 4 +++- 6 files changed, 38 insertions(+), 14 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index ee7ba72d2..ec71f1998 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -623,6 +623,9 @@ bloom_radius (Bloom Radius) float 1 0.1 8 # Requires the sound system to be enabled. sound_volume (Volume) float 0.8 0.0 1.0 +# Volume multiplier when the window is unfocused. +sound_volume_unfocused (Volume when unfocused) float 0.3 0.0 1.0 + # Whether to mute sounds. You can unmute sounds at any time, unless the # sound system is disabled (enable_sound=false). # In-game, you can toggle the mute state with the mute key or by using the diff --git a/src/client/game.cpp b/src/client/game.cpp index ea57f5085..7bc2c8697 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3209,19 +3209,7 @@ void Game::updateSound(f32 dtime) camera->getDirection(), camera->getCameraNode()->getUpVector()); - bool mute_sound = g_settings->getBool("mute_sound"); - if (mute_sound) { - sound_manager->setListenerGain(0.0f); - } else { - // Check if volume is in the proper range, else fix it. - float old_volume = g_settings->getFloat("sound_volume"); - float new_volume = rangelim(old_volume, 0.0f, 1.0f); - sound_manager->setListenerGain(new_volume); - - if (old_volume != new_volume) { - g_settings->setFloat("sound_volume", new_volume); - } - } + sound_volume_control(sound_manager.get(), device->isWindowActive()); // Tell the sound maker whether to make footstep sounds soundmaker->makes_footstep_sound = player->makes_footstep_sound; diff --git a/src/client/sound.cpp b/src/client/sound.cpp index b4b073242..b2b035b4e 100644 --- a/src/client/sound.cpp +++ b/src/client/sound.cpp @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "log.h" #include "porting.h" +#include "settings.h" #include "util/numeric.h" #include #include @@ -95,3 +96,26 @@ void ISoundManager::freeId(sound_handle_t id, u32 num_owners) else it->second -= num_owners; } + +void sound_volume_control(ISoundManager *sound_mgr, bool is_window_active) +{ + bool mute_sound = g_settings->getBool("mute_sound"); + if (mute_sound) { + sound_mgr->setListenerGain(0.0f); + } else { + // Check if volume is in the proper range, else fix it. + float old_volume = g_settings->getFloat("sound_volume"); + float new_volume = rangelim(old_volume, 0.0f, 1.0f); + + if (old_volume != new_volume) { + g_settings->setFloat("sound_volume", new_volume); + } + + if (!is_window_active) { + new_volume *= g_settings->getFloat("sound_volume_unfocused"); + new_volume = rangelim(new_volume, 0.0f, 1.0f); + } + + sound_mgr->setListenerGain(new_volume); + } +} diff --git a/src/client/sound.h b/src/client/sound.h index ad5dbf649..132da708e 100644 --- a/src/client/sound.h +++ b/src/client/sound.h @@ -184,3 +184,9 @@ public: void fadeSound(sound_handle_t sound, f32 step, f32 target_gain) override {} void updateSoundPosVel(sound_handle_t sound, const v3f &pos, const v3f &vel) override {} }; + +/** + * A helper function to control sound volume based on some values: sound volume + * settings, mute sound setting, and window activity. + */ +void sound_volume_control(ISoundManager *sound_mgr, bool is_window_active); diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 8ca079357..a815f89ed 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -40,6 +40,7 @@ void set_default_settings() settings->setDefault("address", ""); settings->setDefault("enable_sound", "true"); settings->setDefault("sound_volume", "0.8"); + settings->setDefault("sound_volume_unfocused", "0.3"); settings->setDefault("mute_sound", "false"); settings->setDefault("enable_mesh_cache", "false"); settings->setDefault("mesh_generation_interval", "0"); diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index fd1121346..7bdc067ac 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "client/renderingengine.h" #include "scripting_mainmenu.h" -#include "util/numeric.h" #include "config.h" #include "version.h" #include "porting.h" @@ -296,6 +295,7 @@ void GUIEngine::run() driver->endScene(); IrrlichtDevice *device = m_rendering_engine->get_raw_device(); + u32 frametime_min = 1000 / (device->isWindowFocused() ? g_settings->getFloat("fps_max") : g_settings->getFloat("fps_max_unfocused")); @@ -310,6 +310,8 @@ void GUIEngine::run() m_script->step(); + sound_volume_control(m_sound_manager.get(), device->isWindowActive()); + m_sound_manager->step(dtime); #ifdef __ANDROID__