From fafd3fb564886602724da12ce0e72f09d92488e1 Mon Sep 17 00:00:00 2001 From: UltraDaCat <113462733+UltraDaCat@users.noreply.github.com> Date: Fri, 18 Jul 2025 10:20:05 +0200 Subject: [PATCH] Volume slider that adjusts how loud games are on a global level (#3240) * Update config.cpp * Update config.h * Update sdl_audio.cpp * Update settings_dialog.cpp * Update settings_dialog.h * Update settings_dialog.ui * Update gui_settings.h * Update audioout.cpp * Update audioout.h * Update settings_dialog.cpp * remove leftover settings_dialog.ui * Update settings_dialog.ui --------- Co-authored-by: georgemoralis --- src/common/config.cpp | 11 + src/common/config.h | 2 + src/core/libraries/audio/audioout.cpp | 15 + src/core/libraries/audio/audioout.h | 1 + src/core/libraries/audio/sdl_audio.cpp | 5 +- src/qt_gui/gui_settings.h | 1 + src/qt_gui/settings_dialog.cpp | 31 +- src/qt_gui/settings_dialog.h | 3 +- src/qt_gui/settings_dialog.ui | 403 +++++++++++++++---------- 9 files changed, 304 insertions(+), 168 deletions(-) diff --git a/src/common/config.cpp b/src/common/config.cpp index 6f8563377..a1b12ee5d 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -32,6 +32,7 @@ std::filesystem::path find_fs_path_or(const basic_value& v, const K& ky, namespace Config { // General +static int volumeSlider = 100; static bool isNeo = false; static bool isDevKit = false; static bool isPSNSignedIn = false; @@ -108,6 +109,9 @@ static std::string trophyKey = ""; // Expected number of items in the config file static constexpr u64 total_entries = 54; +int getVolumeSlider() { + return volumeSlider; +} bool allowHDR() { return isHDRAllowed; } @@ -157,6 +161,10 @@ std::filesystem::path GetSaveDataPath() { return save_data_path; } +void setVolumeSlider(int volumeValue) { + volumeSlider = volumeValue; +} + void setLoadGameSizeEnabled(bool enable) { load_game_size = enable; } @@ -611,6 +619,7 @@ void load(const std::filesystem::path& path) { if (data.contains("General")) { const toml::value& general = data.at("General"); + volumeSlider = toml::find_or(general, "volumeSlider", volumeSlider); isNeo = toml::find_or(general, "isPS4Pro", isNeo); isDevKit = toml::find_or(general, "isDevKit", isDevKit); isPSNSignedIn = toml::find_or(general, "isPSNSignedIn", isPSNSignedIn); @@ -806,6 +815,7 @@ void save(const std::filesystem::path& path) { fmt::print("Saving new configuration file {}\n", fmt::UTF(path.u8string())); } + data["General"]["volumeSlider"] = volumeSlider; data["General"]["isPS4Pro"] = isNeo; data["General"]["isDevKit"] = isDevKit; data["General"]["isPSNSignedIn"] = isPSNSignedIn; @@ -901,6 +911,7 @@ void save(const std::filesystem::path& path) { void setDefaultValues() { // General + volumeSlider = 100; isNeo = false; isDevKit = false; isPSNSignedIn = false; diff --git a/src/common/config.h b/src/common/config.h index e54425676..4ace4d316 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -19,6 +19,8 @@ enum HideCursorState : int { Never, Idle, Always }; void load(const std::filesystem::path& path); void save(const std::filesystem::path& path); +int getVolumeSlider(); +void setVolumeSlider(int volumeValue); std::string getTrophyKey(); void setTrophyKey(std::string key); bool getIsFullscreen(); diff --git a/src/core/libraries/audio/audioout.cpp b/src/core/libraries/audio/audioout.cpp index 421289a9d..2ec44e80f 100644 --- a/src/core/libraries/audio/audioout.cpp +++ b/src/core/libraries/audio/audioout.cpp @@ -523,9 +523,24 @@ s32 PS4_SYSV_ABI sceAudioOutSetVolume(s32 handle, s32 flag, s32* vol) { } port.impl->SetVolume(port.volume); } + AdjustVol(); return ORBIS_OK; } +void AdjustVol() { + if (audio == nullptr) { + return; + } + + for (int i = 0; i < ports_out.size(); i++) { + std::unique_lock lock{ports_out[i].mutex}; + if (!ports_out[i].IsOpen()) { + continue; + } + ports_out[i].impl->SetVolume(ports_out[i].volume); + } +} + int PS4_SYSV_ABI sceAudioOutSetVolumeDown() { LOG_ERROR(Lib_AudioOut, "(STUBBED) called"); return ORBIS_OK; diff --git a/src/core/libraries/audio/audioout.h b/src/core/libraries/audio/audioout.h index 4f799665e..5247561ee 100644 --- a/src/core/libraries/audio/audioout.h +++ b/src/core/libraries/audio/audioout.h @@ -181,5 +181,6 @@ int PS4_SYSV_ABI sceAudioOutSystemControlSet(); int PS4_SYSV_ABI sceAudioOutSparkControlSetEqCoef(); int PS4_SYSV_ABI sceAudioOutSetSystemDebugState(); +void AdjustVol(); void RegisterLib(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::AudioOut diff --git a/src/core/libraries/audio/sdl_audio.cpp b/src/core/libraries/audio/sdl_audio.cpp index 9aee2b447..94d624b0c 100644 --- a/src/core/libraries/audio/sdl_audio.cpp +++ b/src/core/libraries/audio/sdl_audio.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "common/logging/log.h" #include "core/libraries/audio/audioout.h" @@ -41,6 +42,7 @@ public: stream = nullptr; return; } + SDL_SetAudioStreamGain(stream, Config::getVolumeSlider() / 100.0f); } ~SDLPortBackend() override { @@ -77,7 +79,8 @@ public: } // SDL does not have per-channel volumes, for now just take the maximum of the channels. const auto vol = *std::ranges::max_element(ch_volumes); - if (!SDL_SetAudioStreamGain(stream, static_cast(vol) / SCE_AUDIO_OUT_VOLUME_0DB)) { + if (!SDL_SetAudioStreamGain(stream, static_cast(vol) / SCE_AUDIO_OUT_VOLUME_0DB * + Config::getVolumeSlider() / 100.0f)) { LOG_WARNING(Lib_AudioOut, "Failed to change SDL audio stream volume: {}", SDL_GetError()); } diff --git a/src/qt_gui/gui_settings.h b/src/qt_gui/gui_settings.h index 4c1eafc95..4d2a1b7f7 100644 --- a/src/qt_gui/gui_settings.h +++ b/src/qt_gui/gui_settings.h @@ -37,6 +37,7 @@ const gui_value gl_showBackgroundImage = gui_value(game_list, "showBackgroundIma const gui_value gl_backgroundImageOpacity = gui_value(game_list, "backgroundImageOpacity", 50); const gui_value gl_playBackgroundMusic = gui_value(game_list, "playBackgroundMusic", true); const gui_value gl_backgroundMusicVolume = gui_value(game_list, "backgroundMusicVolume", 50); +const gui_value gl_VolumeSlider = gui_value(game_list, "volumeSlider", 100); // game grid settings const gui_value gg_icon_size = gui_value(game_grid, "icon_size", 69); diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index f903562f9..b08bb5aee 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -11,6 +11,7 @@ #include "common/config.h" #include "common/scm_rev.h" +#include "core/libraries/audio/audioout.h" #include "qt_gui/compatibility_info.h" #ifdef ENABLE_DISCORD_RPC #include "common/discord_rpc_handler.h" @@ -68,6 +69,7 @@ QMap chooseHomeTabMap; int backgroundImageOpacitySlider_backup; int bgm_volume_backup; +int volume_slider_backup; static std::vector m_physical_devices; @@ -149,9 +151,11 @@ SettingsDialog::SettingsDialog(std::shared_ptr gui_settings, } else if (button == ui->buttonBox->button(QDialogButtonBox::Close)) { ui->backgroundImageOpacitySlider->setValue(backgroundImageOpacitySlider_backup); emit BackgroundOpacityChanged(backgroundImageOpacitySlider_backup); + ui->horizontalVolumeSlider->setValue(volume_slider_backup); + Config::setVolumeSlider(volume_slider_backup); ui->BGMVolumeSlider->setValue(bgm_volume_backup); BackgroundMusicPlayer::getInstance().setVolume(bgm_volume_backup); - ResetInstallFolders(); + SyncRealTimeWidgetstoConfig(); } if (Common::Log::IsActive()) { Common::Log::Filter filter; @@ -170,6 +174,12 @@ SettingsDialog::SettingsDialog(std::shared_ptr gui_settings, // GENERAL TAB { + connect(ui->horizontalVolumeSlider, &QSlider::valueChanged, this, [this](int value) { + VolumeSliderChange(value); + Config::setVolumeSlider(value); + Libraries::AudioOut::AdjustVol(); + }); + #ifdef ENABLE_UPDATER #if (QT_VERSION < QT_VERSION_CHECK(6, 7, 0)) connect(ui->updateCheckBox, &QCheckBox::stateChanged, this, [this](int state) { @@ -398,6 +408,8 @@ void SettingsDialog::closeEvent(QCloseEvent* event) { if (!is_saving) { ui->backgroundImageOpacitySlider->setValue(backgroundImageOpacitySlider_backup); emit BackgroundOpacityChanged(backgroundImageOpacitySlider_backup); + ui->horizontalVolumeSlider->setValue(volume_slider_backup); + Config::setVolumeSlider(volume_slider_backup); ui->BGMVolumeSlider->setValue(bgm_volume_backup); BackgroundMusicPlayer::getInstance().setVolume(bgm_volume_backup); } @@ -463,6 +475,8 @@ void SettingsDialog::LoadValuesFromConfig() { ui->radioButton_Bottom->setChecked(side == "bottom"); ui->BGMVolumeSlider->setValue(m_gui_settings->GetValue(gui::gl_backgroundMusicVolume).toInt()); + ui->horizontalVolumeSlider->setValue(m_gui_settings->GetValue(gui::gl_VolumeSlider).toInt()); + ui->volumeText->setText(QString::number(ui->horizontalVolumeSlider->sliderPosition()) + "%"); ui->discordRPCCheckbox->setChecked( toml::find_or(data, "General", "enableDiscordRPC", true)); QString translatedText_FullscreenMode = @@ -532,7 +546,7 @@ void SettingsDialog::LoadValuesFromConfig() { toml::find_or(data, "Input", "isMotionControlsEnabled", true)); ui->removeFolderButton->setEnabled(!ui->gameFoldersListWidget->selectedItems().isEmpty()); - ResetInstallFolders(); + SyncRealTimeWidgetstoConfig(); ui->backgroundImageOpacitySlider->setValue( m_gui_settings->GetValue(gui::gl_backgroundImageOpacity).toInt()); ui->showBackgroundImageCheckBox->setChecked( @@ -541,6 +555,7 @@ void SettingsDialog::LoadValuesFromConfig() { backgroundImageOpacitySlider_backup = m_gui_settings->GetValue(gui::gl_backgroundImageOpacity).toInt(); bgm_volume_backup = m_gui_settings->GetValue(gui::gl_backgroundMusicVolume).toInt(); + volume_slider_backup = m_gui_settings->GetValue(gui::gl_VolumeSlider).toInt(); } void SettingsDialog::InitializeEmulatorLanguages() { @@ -599,6 +614,10 @@ void SettingsDialog::OnCursorStateChanged(s16 index) { } } +void SettingsDialog::VolumeSliderChange(int value) { + ui->volumeText->setText(QString::number(ui->horizontalVolumeSlider->sliderPosition()) + "%"); +} + int SettingsDialog::exec() { return QDialog::exec(); } @@ -719,7 +738,6 @@ bool SettingsDialog::eventFilter(QObject* obj, QEvent* event) { if (qobject_cast(obj)) { bool hovered = (event->type() == QEvent::Enter); QString elementName = obj->objectName(); - if (hovered) { updateNoteTextEdit(elementName); } else { @@ -759,6 +777,7 @@ void SettingsDialog::UpdateSettings() { Config::setCursorState(ui->hideCursorComboBox->currentIndex()); Config::setCursorHideTimeout(ui->idleTimeoutSpinBox->value()); Config::setGpuId(ui->graphicsAdapterBox->currentIndex() - 1); + m_gui_settings->SetValue(gui::gl_VolumeSlider, ui->horizontalVolumeSlider->value()); m_gui_settings->SetValue(gui::gl_backgroundMusicVolume, ui->BGMVolumeSlider->value()); Config::setLanguage(languageIndexes[ui->consoleLanguageComboBox->currentIndex()]); Config::setEnableDiscordRPC(ui->discordRPCCheckbox->isChecked()); @@ -815,9 +834,10 @@ void SettingsDialog::UpdateSettings() { #endif BackgroundMusicPlayer::getInstance().setVolume(ui->BGMVolumeSlider->value()); + Config::setVolumeSlider(ui->horizontalVolumeSlider->value()); } -void SettingsDialog::ResetInstallFolders() { +void SettingsDialog::SyncRealTimeWidgetstoConfig() { ui->gameFoldersListWidget->clear(); std::filesystem::path userdir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); @@ -865,6 +885,7 @@ void SettingsDialog::setDefaultValues() { m_gui_settings->SetValue(gui::gl_backgroundImageOpacity, 50); m_gui_settings->SetValue(gui::gl_playBackgroundMusic, false); m_gui_settings->SetValue(gui::gl_backgroundMusicVolume, 50); + m_gui_settings->SetValue(gui::gl_VolumeSlider, 100); m_gui_settings->SetValue(gui::gen_checkForUpdates, false); m_gui_settings->SetValue(gui::gen_showChangeLog, false); if (Common::g_is_release) { @@ -873,4 +894,4 @@ void SettingsDialog::setDefaultValues() { m_gui_settings->SetValue(gui::gen_updateChannel, "Nightly"); } m_gui_settings->SetValue(gui::gen_guiLanguage, "en_US"); -} \ No newline at end of file +} diff --git a/src/qt_gui/settings_dialog.h b/src/qt_gui/settings_dialog.h index d9fbcb214..13fab36a2 100644 --- a/src/qt_gui/settings_dialog.h +++ b/src/qt_gui/settings_dialog.h @@ -39,12 +39,13 @@ signals: private: void LoadValuesFromConfig(); void UpdateSettings(); - void ResetInstallFolders(); + void SyncRealTimeWidgetstoConfig(); void InitializeEmulatorLanguages(); void OnLanguageChanged(int index); void OnCursorStateChanged(s16 index); void closeEvent(QCloseEvent* event) override; void setDefaultValues(); + void VolumeSliderChange(int value); std::unique_ptr ui; diff --git a/src/qt_gui/settings_dialog.ui b/src/qt_gui/settings_dialog.ui index 8d239b58c..9ebb1cbc1 100644 --- a/src/qt_gui/settings_dialog.ui +++ b/src/qt_gui/settings_dialog.ui @@ -59,7 +59,7 @@ - 5 + 0 @@ -73,8 +73,8 @@ 0 0 - 946 - 536 + 944 + 537 @@ -86,148 +86,7 @@ 6 - - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Emulator - - - false - - - false - - - - 6 - - - 9 - - - 9 - - - 9 - - - 9 - - - - - 10 - - - - - Show Splash - - - - - - - Enable Discord Rich Presence - - - - - - - - - - - - - - 6 - - - 0 - - - - - - 0 - 0 - - - - - 0 - 0 - - - - System - - - - 70 - - - - - Console Language - - - - - - - - - - - - Emulator Language - - - - - - - - - - - - - - - - - Qt::Orientation::Vertical - - - - 20 - 40 - - - - - + Qt::Orientation::Vertical @@ -240,8 +99,8 @@ - - + + Qt::Orientation::Vertical @@ -253,7 +112,7 @@ - + 6 @@ -427,6 +286,228 @@ + + + + 6 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + System + + + + 70 + + + + + Console Language + + + + + + + + + + + + Emulator Language + + + + + + + + + + + + + + + + + Volume + + + + + + + 0 + 0 + + + + + + + true + + + + + 0 + 0 + 414 + 69 + + + + + + + + 0 + 0 + + + + + 60 + 16777215 + + + + 100% + + + Qt::AlignmentFlag::AlignCenter + + + true + + + + + + + Qt::FocusPolicy::StrongFocus + + + 500 + + + 100 + + + 100 + + + Qt::Orientation::Horizontal + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Emulator + + + false + + + false + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 10 + + + + + Show Splash + + + + + + + Enable Discord Rich Presence + + + + + + + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + @@ -444,8 +525,8 @@ 0 0 - 946 - 536 + 944 + 537 @@ -700,7 +781,7 @@ - + 0 0 @@ -893,8 +974,8 @@ 0 0 - 946 - 536 + 944 + 537 @@ -1188,8 +1269,8 @@ 0 0 - 946 - 536 + 944 + 537 @@ -1430,8 +1511,8 @@ 0 0 - 946 - 536 + 944 + 537 @@ -1684,8 +1765,8 @@ 0 0 - 946 - 536 + 944 + 537 @@ -1826,8 +1907,8 @@ 0 0 - 946 - 536 + 944 + 537