From cd58959cee0d6964fdba243047082f83d3b5f33e Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 1 Jan 2025 13:42:12 +0100 Subject: [PATCH] Audio: Add mute/unmute and volume shortcuts Also add auto repeat to volume shortcuts --- rpcs3/Emu/Audio/audio_utils.cpp | 39 ++++++++++++++++ rpcs3/Emu/Audio/audio_utils.h | 14 ++++++ rpcs3/Emu/CMakeLists.txt | 1 + rpcs3/Emu/Cell/Modules/cellAudio.cpp | 3 +- rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp | 9 ++-- .../Trophies/overlay_trophy_list_dialog.cpp | 2 +- rpcs3/Emu/localized_string_id.h | 5 ++ rpcs3/emucore.vcxproj | 2 + rpcs3/emucore.vcxproj.filters | 6 +++ rpcs3/rpcs3qt/gs_frame.cpp | 16 +++++++ rpcs3/rpcs3qt/gui_application.cpp | 3 +- rpcs3/rpcs3qt/localized_emu.h | 3 ++ rpcs3/rpcs3qt/shortcut_handler.cpp | 2 +- rpcs3/rpcs3qt/shortcut_settings.cpp | 46 +++++++++++-------- rpcs3/rpcs3qt/shortcut_settings.h | 4 ++ 15 files changed, 127 insertions(+), 28 deletions(-) create mode 100644 rpcs3/Emu/Audio/audio_utils.cpp create mode 100644 rpcs3/Emu/Audio/audio_utils.h diff --git a/rpcs3/Emu/Audio/audio_utils.cpp b/rpcs3/Emu/Audio/audio_utils.cpp new file mode 100644 index 0000000000..bcff7bf947 --- /dev/null +++ b/rpcs3/Emu/Audio/audio_utils.cpp @@ -0,0 +1,39 @@ +#include "stdafx.h" +#include "audio_utils.h" +#include "Emu/system_config.h" +#include "Emu/System.h" +#include "Emu/IdManager.h" +#include "Emu/RSX/Overlays/overlay_message.h" + +namespace audio +{ + f32 get_volume() + { + return g_fxo->get().audio_muted ? 0.0f : g_cfg.audio.volume / 100.0f; + } + + void toggle_mute() + { + audio_fxo& fxo = g_fxo->get(); + fxo.audio_muted = !fxo.audio_muted; + Emu.GetCallbacks().update_emu_settings(); + + rsx::overlays::queue_message(fxo.audio_muted ? localized_string_id::AUDIO_MUTED : localized_string_id::AUDIO_UNMUTED, 3'000'000); + } + + void change_volume(s32 delta) + { + // Ignore if muted + if (g_fxo->get().audio_muted) return; + + const s32 old_volume = g_cfg.audio.volume; + const s32 new_volume = old_volume + delta; + + if (old_volume == new_volume) return; + + g_cfg.audio.volume.set(std::clamp(new_volume, g_cfg.audio.volume.min, g_cfg.audio.volume.max)); + Emu.GetCallbacks().update_emu_settings(); + + rsx::overlays::queue_message(get_localized_string(localized_string_id::AUDIO_CHANGED, fmt::format("%d%%", g_cfg.audio.volume.get()).c_str()), 3'000'000); + } +} diff --git a/rpcs3/Emu/Audio/audio_utils.h b/rpcs3/Emu/Audio/audio_utils.h new file mode 100644 index 0000000000..048776c1c1 --- /dev/null +++ b/rpcs3/Emu/Audio/audio_utils.h @@ -0,0 +1,14 @@ +#pragma once + +namespace audio +{ + struct audio_fxo + { + atomic_t audio_muted {false}; + }; + + f32 get_volume(); + + void toggle_mute(); + void change_volume(s32 delta); +} diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt index e77399784e..4cd083ab90 100644 --- a/rpcs3/Emu/CMakeLists.txt +++ b/rpcs3/Emu/CMakeLists.txt @@ -125,6 +125,7 @@ target_sources(rpcs3_emu PRIVATE # Audio target_sources(rpcs3_emu PRIVATE Audio/audio_resampler.cpp + Audio/audio_utils.cpp Audio/AudioDumper.cpp Audio/AudioBackend.cpp Audio/Cubeb/CubebBackend.cpp diff --git a/rpcs3/Emu/Cell/Modules/cellAudio.cpp b/rpcs3/Emu/Cell/Modules/cellAudio.cpp index 2e31d37b6b..ceeb02da63 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudio.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAudio.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "Emu/System.h" #include "Emu/system_config.h" +#include "Emu/Audio/audio_utils.h" #include "Emu/Cell/PPUModule.h" #include "Emu/Cell/lv2/sys_process.h" #include "Emu/Cell/lv2/sys_event.h" @@ -1041,7 +1042,7 @@ void cell_audio_thread::mix(float* out_buffer, s32 offset) constexpr u32 out_channels = static_cast(channels); constexpr u32 out_buffer_sz = out_channels * AUDIO_BUFFER_SAMPLES; - const float master_volume = g_cfg.audio.volume / 100.0f; + const float master_volume = audio::get_volume(); // Reset out_buffer std::memset(out_buffer, 0, out_buffer_sz * sizeof(float)); diff --git a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp index c391602bc3..5f06415ac7 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp @@ -3,6 +3,7 @@ #include "Emu/IdManager.h" #include "Emu/System.h" #include "Emu/system_config.h" +#include "Emu//Audio/audio_utils.h" #include "Emu//Cell/Modules/cellAudioOut.h" #include "util/video_provider.h" @@ -1308,11 +1309,11 @@ rsxaudio_backend_thread::rsxaudio_backend_thread() { new_emu_cfg = get_emu_cfg(); - const u64 new_vol = g_cfg.audio.volume; + const f32 new_vol = audio::get_volume(); callback_cfg.atomic_op([&](callback_config& val) { - val.target_volume = static_cast(new_vol / 100.0 * callback_config::VOL_NOMINAL); + val.target_volume = static_cast(new_vol * callback_config::VOL_NOMINAL); val.initial_volume = val.current_volume; }); } @@ -1332,11 +1333,11 @@ void rsxaudio_backend_thread::update_emu_cfg() { std::unique_lock lock(state_update_m); const emu_audio_cfg _new_emu_cfg = get_emu_cfg(); - const u64 new_vol = g_cfg.audio.volume; + const f32 new_vol = audio::get_volume(); callback_cfg.atomic_op([&](callback_config& val) { - val.target_volume = static_cast(new_vol / 100.0 * callback_config::VOL_NOMINAL); + val.target_volume = static_cast(new_vol * callback_config::VOL_NOMINAL); val.initial_volume = val.current_volume; }); diff --git a/rpcs3/Emu/RSX/Overlays/Trophies/overlay_trophy_list_dialog.cpp b/rpcs3/Emu/RSX/Overlays/Trophies/overlay_trophy_list_dialog.cpp index 46b471d83f..8213b29a2d 100644 --- a/rpcs3/Emu/RSX/Overlays/Trophies/overlay_trophy_list_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/Trophies/overlay_trophy_list_dialog.cpp @@ -68,7 +68,7 @@ namespace rsx { m_dim_background = std::make_unique(); m_dim_background->set_size(virtual_width, virtual_height); - m_dim_background->back_color.a = 0.5f; + m_dim_background->back_color.a = 0.9f; m_list = std::make_unique(virtual_width - 2 * 20, 540); m_list->set_pos(20, 85); diff --git a/rpcs3/Emu/localized_string_id.h b/rpcs3/Emu/localized_string_id.h index 67bc9fe2a8..21437762bb 100644 --- a/rpcs3/Emu/localized_string_id.h +++ b/rpcs3/Emu/localized_string_id.h @@ -282,6 +282,10 @@ enum class localized_string_id HOME_MENU_TROPHY_GRADE_GOLD, HOME_MENU_TROPHY_GRADE_PLATINUM, + AUDIO_MUTED, + AUDIO_UNMUTED, + AUDIO_CHANGED, + PROGRESS_DIALOG_PROGRESS, PROGRESS_DIALOG_PROGRESS_ANALYZING, PROGRESS_DIALOG_REMAINING, @@ -303,6 +307,7 @@ enum class localized_string_id EMULATION_PAUSED_RESUME_WITH_START, EMULATION_RESUMING, EMULATION_FROZEN, + SAVESTATE_FAILED_DUE_TO_VDEC, SAVESTATE_FAILED_DUE_TO_SAVEDATA, SAVESTATE_FAILED_DUE_TO_SPU, diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 486cb1078e..3da2dc1872 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -58,6 +58,7 @@ + true @@ -530,6 +531,7 @@ + true diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 2c25be4696..90df56b77e 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1324,6 +1324,9 @@ Emu\GPU\RSX\Overlays\Trophies + + Emu\Audio + @@ -2677,6 +2680,9 @@ Emu\GPU\RSX\Overlays\Trophies + + Emu\Audio + diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index dd94f41857..8af0b84757 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -10,6 +10,7 @@ #include "Emu/system_config.h" #include "Emu/system_progress.hpp" #include "Emu/IdManager.h" +#include "Emu/Audio/audio_utils.h" #include "Emu/Cell/Modules/cellScreenshot.h" #include "Emu/Cell/Modules/cellVideoOut.h" #include "Emu/Cell/Modules/cellAudio.h" @@ -358,6 +359,21 @@ void gs_frame::handle_shortcut(gui::shortcuts::shortcut shortcut_key, const QKey pad::g_home_menu_requested = true; break; } + case gui::shortcuts::shortcut::gw_mute_unmute: + { + audio::toggle_mute(); + break; + } + case gui::shortcuts::shortcut::gw_volume_up: + { + audio::change_volume(5); + break; + } + case gui::shortcuts::shortcut::gw_volume_down: + { + audio::change_volume(-5); + break; + } default: { break; diff --git a/rpcs3/rpcs3qt/gui_application.cpp b/rpcs3/rpcs3qt/gui_application.cpp index fd5a50e326..0a3ff110ce 100644 --- a/rpcs3/rpcs3qt/gui_application.cpp +++ b/rpcs3/rpcs3qt/gui_application.cpp @@ -18,6 +18,7 @@ #include "_discord_utils.h" #endif +#include "Emu/Audio/audio_utils.h" #include "Emu/Io/Null/null_camera_handler.h" #include "Emu/Io/Null/null_music_handler.h" #include "Emu/vfs_config.h" @@ -621,7 +622,7 @@ void gui_application::InitializeCallbacks() // Create a new sound effect. Re-using the same object seems to be broken for some users starting with Qt 6.6.3. std::unique_ptr sound_effect = std::make_unique(); sound_effect->setSource(QUrl::fromLocalFile(QString::fromStdString(path))); - sound_effect->setVolume(g_cfg.audio.volume * 0.01f); + sound_effect->setVolume(audio::get_volume()); sound_effect->play(); m_sound_effects.push_back(std::move(sound_effect)); diff --git a/rpcs3/rpcs3qt/localized_emu.h b/rpcs3/rpcs3qt/localized_emu.h index 2a44ce7fae..8ea21f6d03 100644 --- a/rpcs3/rpcs3qt/localized_emu.h +++ b/rpcs3/rpcs3qt/localized_emu.h @@ -302,6 +302,9 @@ private: case localized_string_id::HOME_MENU_TROPHY_GRADE_SILVER: return tr("Silver", "Trophy type"); case localized_string_id::HOME_MENU_TROPHY_GRADE_GOLD: return tr("Gold", "Trophy type"); case localized_string_id::HOME_MENU_TROPHY_GRADE_PLATINUM: return tr("Platinum", "Trophy type"); + case localized_string_id::AUDIO_MUTED: return tr("Audio muted", "Audio"); + case localized_string_id::AUDIO_UNMUTED: return tr("Audio unmuted", "Audio"); + case localized_string_id::AUDIO_CHANGED: return tr("Volume changed to %0", "Audio").arg(std::forward(args)...); case localized_string_id::PROGRESS_DIALOG_PROGRESS: return tr("Progress:"); case localized_string_id::PROGRESS_DIALOG_PROGRESS_ANALYZING: return tr("Progress: analyzing..."); case localized_string_id::PROGRESS_DIALOG_REMAINING: return tr("remaining"); diff --git a/rpcs3/rpcs3qt/shortcut_handler.cpp b/rpcs3/rpcs3qt/shortcut_handler.cpp index a6b9bf8413..9d70aa0262 100644 --- a/rpcs3/rpcs3qt/shortcut_handler.cpp +++ b/rpcs3/rpcs3qt/shortcut_handler.cpp @@ -20,7 +20,7 @@ shortcut_handler::shortcut_handler(gui::shortcuts::shortcut_handler_id handler_i const QKeySequence key_sequence = sc_settings.get_key_sequence(info, gui_settings); QShortcut* shortcut = new QShortcut(key_sequence, parent); - shortcut->setAutoRepeat(false); + shortcut->setAutoRepeat(info.allow_auto_repeat); shortcut_key_info key_info{}; key_info.shortcut = shortcut; diff --git a/rpcs3/rpcs3qt/shortcut_settings.cpp b/rpcs3/rpcs3qt/shortcut_settings.cpp index d8f376cfeb..bca0fd57a9 100644 --- a/rpcs3/rpcs3qt/shortcut_settings.cpp +++ b/rpcs3/rpcs3qt/shortcut_settings.cpp @@ -29,6 +29,9 @@ void fmt_class_string::format(std::string& out, u64 arg) case shortcut::gw_frame_limit: return "gw_frame_limit"; case shortcut::gw_toggle_mouse_and_keyboard: return "gw_toggle_mouse_and_keyboard"; case shortcut::gw_home_menu: return "gw_home_menu"; + case shortcut::gw_mute_unmute: return "gw_mute_unmute"; + case shortcut::gw_volume_up: return "gw_volume_up"; + case shortcut::gw_volume_down: return "gw_volume_down"; case shortcut::count: return "count"; } @@ -53,26 +56,29 @@ void fmt_class_string::format(std::string& out, u64 arg) shortcut_settings::shortcut_settings() : shortcut_map({ - { shortcut::mw_start, shortcut_info{ "main_window_start", tr("Start"), "Ctrl+E", shortcut_handler_id::main_window } }, - { shortcut::mw_stop, shortcut_info{ "main_window_stop", tr("Stop"), "Ctrl+S", shortcut_handler_id::main_window } }, - { shortcut::mw_pause, shortcut_info{ "main_window_pause", tr("Pause"), "Ctrl+P", shortcut_handler_id::main_window } }, - { shortcut::mw_restart, shortcut_info{ "main_window_restart", tr("Restart"), "Ctrl+R", shortcut_handler_id::main_window } }, - { shortcut::mw_toggle_fullscreen, shortcut_info{ "main_window_toggle_fullscreen", tr("Toggle Fullscreen"), "Alt+Return", shortcut_handler_id::main_window } }, - { shortcut::mw_exit_fullscreen, shortcut_info{ "main_window_exit_fullscreen", tr("Exit Fullscreen"), "Esc", shortcut_handler_id::main_window } }, - { shortcut::mw_refresh, shortcut_info{ "main_window_refresh", tr("Refresh"), "Ctrl+F5", shortcut_handler_id::main_window } }, - { shortcut::gw_toggle_fullscreen, shortcut_info{ "game_window_toggle_fullscreen", tr("Toggle Fullscreen"), "Alt+Return", shortcut_handler_id::game_window } }, - { shortcut::gw_exit_fullscreen, shortcut_info{ "game_window_exit_fullscreen", tr("Exit Fullscreen"), "Esc", shortcut_handler_id::game_window } }, - { shortcut::gw_log_mark, shortcut_info{ "game_window_log_mark", tr("Add Log Mark"), "Alt+L", shortcut_handler_id::game_window } }, - { shortcut::gw_mouse_lock, shortcut_info{ "game_window_mouse_lock", tr("Mouse lock"), "Ctrl+L", shortcut_handler_id::game_window } }, - { shortcut::gw_toggle_recording, shortcut_info{ "game_window_toggle_recording", tr("Start/Stop Recording"), "F11", shortcut_handler_id::game_window } }, - { shortcut::gw_screenshot, shortcut_info{ "game_window_screenshot", tr("Screenshot"), "F12", shortcut_handler_id::game_window } }, - { shortcut::gw_pause_play, shortcut_info{ "game_window_pause_play", tr("Pause/Play"), "Ctrl+P", shortcut_handler_id::game_window } }, - { shortcut::gw_savestate, shortcut_info{ "game_window_savestate", tr("Savestate"), "Ctrl+S", shortcut_handler_id::game_window } }, - { shortcut::gw_restart, shortcut_info{ "game_window_restart", tr("Restart"), "Ctrl+R", shortcut_handler_id::game_window } }, - { shortcut::gw_rsx_capture, shortcut_info{ "game_window_rsx_capture", tr("RSX Capture"), "Alt+C", shortcut_handler_id::game_window } }, - { shortcut::gw_frame_limit, shortcut_info{ "game_window_frame_limit", tr("Toggle Framelimit"), "Ctrl+F10", shortcut_handler_id::game_window } }, - { shortcut::gw_toggle_mouse_and_keyboard, shortcut_info{ "game_window_toggle_mouse_and_keyboard", tr("Toggle Keyboard"), "Ctrl+F11", shortcut_handler_id::game_window } }, - { shortcut::gw_home_menu, shortcut_info{ "gw_home_menu", tr("Open Home Menu"), "Shift+F10", shortcut_handler_id::game_window } }, + { shortcut::mw_start, shortcut_info{ "main_window_start", tr("Start"), "Ctrl+E", shortcut_handler_id::main_window, false } }, + { shortcut::mw_stop, shortcut_info{ "main_window_stop", tr("Stop"), "Ctrl+S", shortcut_handler_id::main_window, false } }, + { shortcut::mw_pause, shortcut_info{ "main_window_pause", tr("Pause"), "Ctrl+P", shortcut_handler_id::main_window, false } }, + { shortcut::mw_restart, shortcut_info{ "main_window_restart", tr("Restart"), "Ctrl+R", shortcut_handler_id::main_window, false } }, + { shortcut::mw_toggle_fullscreen, shortcut_info{ "main_window_toggle_fullscreen", tr("Toggle Fullscreen"), "Alt+Return", shortcut_handler_id::main_window, false } }, + { shortcut::mw_exit_fullscreen, shortcut_info{ "main_window_exit_fullscreen", tr("Exit Fullscreen"), "Esc", shortcut_handler_id::main_window, false } }, + { shortcut::mw_refresh, shortcut_info{ "main_window_refresh", tr("Refresh"), "Ctrl+F5", shortcut_handler_id::main_window, false } }, + { shortcut::gw_toggle_fullscreen, shortcut_info{ "game_window_toggle_fullscreen", tr("Toggle Fullscreen"), "Alt+Return", shortcut_handler_id::game_window, false } }, + { shortcut::gw_exit_fullscreen, shortcut_info{ "game_window_exit_fullscreen", tr("Exit Fullscreen"), "Esc", shortcut_handler_id::game_window, false } }, + { shortcut::gw_log_mark, shortcut_info{ "game_window_log_mark", tr("Add Log Mark"), "Alt+L", shortcut_handler_id::game_window, false } }, + { shortcut::gw_mouse_lock, shortcut_info{ "game_window_mouse_lock", tr("Mouse lock"), "Ctrl+L", shortcut_handler_id::game_window, false } }, + { shortcut::gw_toggle_recording, shortcut_info{ "game_window_toggle_recording", tr("Start/Stop Recording"), "F11", shortcut_handler_id::game_window, false } }, + { shortcut::gw_screenshot, shortcut_info{ "game_window_screenshot", tr("Screenshot"), "F12", shortcut_handler_id::game_window, false } }, + { shortcut::gw_pause_play, shortcut_info{ "game_window_pause_play", tr("Pause/Play"), "Ctrl+P", shortcut_handler_id::game_window, false } }, + { shortcut::gw_savestate, shortcut_info{ "game_window_savestate", tr("Savestate"), "Ctrl+S", shortcut_handler_id::game_window, false } }, + { shortcut::gw_restart, shortcut_info{ "game_window_restart", tr("Restart"), "Ctrl+R", shortcut_handler_id::game_window, false } }, + { shortcut::gw_rsx_capture, shortcut_info{ "game_window_rsx_capture", tr("RSX Capture"), "Alt+C", shortcut_handler_id::game_window, false } }, + { shortcut::gw_frame_limit, shortcut_info{ "game_window_frame_limit", tr("Toggle Framelimit"), "Ctrl+F10", shortcut_handler_id::game_window, false } }, + { shortcut::gw_toggle_mouse_and_keyboard, shortcut_info{ "game_window_toggle_mouse_and_keyboard", tr("Toggle Keyboard"), "Ctrl+F11", shortcut_handler_id::game_window, false } }, + { shortcut::gw_home_menu, shortcut_info{ "gw_home_menu", tr("Open Home Menu"), "Shift+F10", shortcut_handler_id::game_window, false } }, + { shortcut::gw_mute_unmute, shortcut_info{ "gw_mute_unmute", tr("Mute/Unmute Audio"), "Shift+M", shortcut_handler_id::game_window, false } }, + { shortcut::gw_volume_up, shortcut_info{ "gw_volume_up", tr("Volume Up"), "Shift++", shortcut_handler_id::game_window, true } }, + { shortcut::gw_volume_down, shortcut_info{ "gw_volume_down", tr("Volume Down"), "Shift+-", shortcut_handler_id::game_window, true } }, }) { } diff --git a/rpcs3/rpcs3qt/shortcut_settings.h b/rpcs3/rpcs3qt/shortcut_settings.h index c47f8ff3a9..4e119c4f21 100644 --- a/rpcs3/rpcs3qt/shortcut_settings.h +++ b/rpcs3/rpcs3qt/shortcut_settings.h @@ -37,6 +37,9 @@ namespace gui gw_frame_limit, gw_toggle_mouse_and_keyboard, gw_home_menu, + gw_mute_unmute, + gw_volume_up, + gw_volume_down, count }; @@ -49,6 +52,7 @@ struct shortcut_info QString localized_name; QString key_sequence; gui::shortcuts::shortcut_handler_id handler_id{}; + bool allow_auto_repeat = false; }; class shortcut_settings : public QObject