diff --git a/UnleashedRecomp/cfg/config.h b/UnleashedRecomp/cfg/config.h index c99a1a8c..c19afa41 100644 --- a/UnleashedRecomp/cfg/config.h +++ b/UnleashedRecomp/cfg/config.h @@ -27,6 +27,7 @@ public: CONFIG_DEFINE_LOCALISED("Audio", float, SEVolume, 1.0f); CONFIG_DEFINE_ENUM_LOCALISED("Audio", EVoiceLanguage, VoiceLanguage, EVoiceLanguage::English); CONFIG_DEFINE_LOCALISED("Audio", bool, Subtitles, true); + CONFIG_DEFINE_LOCALISED("Audio", bool, MusicAttenuation, false); CONFIG_DEFINE_LOCALISED("Audio", bool, WerehogBattleMusic, true); CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::D3D12); diff --git a/UnleashedRecomp/cfg/config_locale.h b/UnleashedRecomp/cfg/config_locale.h index b3ea789a..05b7168a 100644 --- a/UnleashedRecomp/cfg/config_locale.h +++ b/UnleashedRecomp/cfg/config_locale.h @@ -207,6 +207,16 @@ CONFIG_DEFINE_DESCRIPTION_LOCALE(SEVolume) { ELanguage::English, "Adjust the volume for sound effects." } }; +CONFIG_DEFINE_LOCALE(MusicAttenuation) +{ + { ELanguage::English, "Music Attenuation" } +}; + +CONFIG_DEFINE_DESCRIPTION_LOCALE(MusicAttenuation) +{ + { ELanguage::English, "Fade out the game's music when external media is playing.\n\nRequires Windows 10 or later." } +}; + CONFIG_DEFINE_LOCALE(VoiceLanguage) { { ELanguage::English, "Voice Language" } diff --git a/UnleashedRecomp/patches/audio_patches.cpp b/UnleashedRecomp/patches/audio_patches.cpp index a4389393..fdadb31d 100644 --- a/UnleashedRecomp/patches/audio_patches.cpp +++ b/UnleashedRecomp/patches/audio_patches.cpp @@ -3,6 +3,42 @@ #include #include +#if _WIN32 +#include +#include + +using namespace winrt; +using namespace Windows::Foundation; +using namespace Windows::Media::Control; + +GlobalSystemMediaTransportControlsSessionManager m_sessionManager = nullptr; + +GlobalSystemMediaTransportControlsSessionManager GetSessionManager() +{ + if (m_sessionManager) + return m_sessionManager; + + init_apartment(); + + return m_sessionManager = GlobalSystemMediaTransportControlsSessionManager::RequestAsync().get(); +} + +GlobalSystemMediaTransportControlsSession GetCurrentSession() +{ + return GetSessionManager().GetCurrentSession(); +} + +bool IsExternalAudioPlaying() +{ + auto session = GetCurrentSession(); + + if (!session) + return false; + + return session.GetPlaybackInfo().PlaybackStatus() == GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing; +} +#endif + be* GetVolume(bool isMusic = true) { auto ppUnkClass = (be*)g_memory.Translate(0x83362FFC); @@ -22,8 +58,27 @@ void audio_patches::Update(float deltaTime) if (!pMusicVolume || !pSEVolume) return; +#if _WIN32 + if (Config::MusicAttenuation) + { + auto time = 1.0f - expf(2.5f * -deltaTime); + + if (IsExternalAudioPlaying()) + { + *pMusicVolume = std::lerp(*pMusicVolume, 0.0f, time); + } + else + { + *pMusicVolume = std::lerp(*pMusicVolume, Config::MusicVolume, time); + } + } + else +#endif + { + *pMusicVolume = Config::MusicVolume; + } + *pSEVolume = Config::SEVolume; - *pMusicVolume = Config::MusicVolume; } // Stub volume setter. diff --git a/UnleashedRecomp/ui/options_menu.cpp b/UnleashedRecomp/ui/options_menu.cpp index 08db827a..edce3bb5 100644 --- a/UnleashedRecomp/ui/options_menu.cpp +++ b/UnleashedRecomp/ui/options_menu.cpp @@ -828,6 +828,7 @@ static void DrawConfigOptions() DrawConfigOption(rowCount++, yOffset, &Config::SEVolume); DrawConfigOption(rowCount++, yOffset, &Config::VoiceLanguage); DrawConfigOption(rowCount++, yOffset, &Config::Subtitles); + DrawConfigOption(rowCount++, yOffset, &Config::MusicAttenuation); // TODO: grey this out for non-Windows platforms. DrawConfigOption(rowCount++, yOffset, &Config::WerehogBattleMusic); break; case 3: // VIDEO