From 719e02574a8cdcccf47dbd3118290a3e2ebd965e Mon Sep 17 00:00:00 2001 From: Pyxellator Date: Sun, 4 Oct 2026 17:48:25 +0200 Subject: [PATCH] launcher: Raise DualSense speaker volume range for SpeakerFX (#1043) controller: restore speaker midpoint and raise volume ceiling --- src/common/emulatorConfig.h | 2 +- .../forms/configuration_edit_dialog.ui | 6 +++--- src/launcher/include/configuration.h | 12 +++++------ src/libs/controller.cpp | 4 +++- src/main.cpp | 2 +- tests/ControllerSettingsTests.cpp | 21 +++++++++++++++++-- tests/PadHapticsTests.cpp | 11 ++++++---- 7 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/common/emulatorConfig.h b/src/common/emulatorConfig.h index 58a9e24d..92cea910 100644 --- a/src/common/emulatorConfig.h +++ b/src/common/emulatorConfig.h @@ -48,7 +48,7 @@ struct ConfigOptions { int32_t user_id = DEFAULT_USER_ID; std::string audio_input_device; std::optional controller_color; - uint32_t controller_speaker_volume = 100; + uint32_t controller_speaker_volume = 50; uint32_t controller_vibration_intensity = 100; PresentMode present_mode = PresentMode::Mailbox; int32_t gpu_index = -1; diff --git a/src/launcher/forms/configuration_edit_dialog.ui b/src/launcher/forms/configuration_edit_dialog.ui index 2ac240c5..52589949 100644 --- a/src/launcher/forms/configuration_edit_dialog.ui +++ b/src/launcher/forms/configuration_edit_dialog.ui @@ -359,16 +359,16 @@ - Scale the DualSense controller speaker over USB and Bluetooth + Scale the DualSense speaker over USB and Bluetooth. 50% is the previous default; 100% adds 6 dB of gain. 100 - 100 + 50 Qt::Horizontal 400 - 100% + 50% diff --git a/src/launcher/include/configuration.h b/src/launcher/include/configuration.h index c5e01351..92c05b8d 100644 --- a/src/launcher/include/configuration.h +++ b/src/launcher/include/configuration.h @@ -48,7 +48,7 @@ QString EnumToText(T value) { struct ControllerSettings { QString color; - int speaker_volume = 100; + int speaker_volume = 50; int vibration_intensity = 100; void WriteSettings(QSettings* s) const { @@ -60,13 +60,13 @@ struct ControllerSettings { void ReadSettings(QSettings* s) { const QColor saved_color(s->value("controller_color").toString()); color = saved_color.isValid() ? saved_color.name(QColor::HexRgb) : QString {}; - const auto read_percent = [s](const char* key) { + const auto read_percent = [s](const char* key, int fallback) { bool ok = false; - const int value = s->value(key, 100).toInt(&ok); - return ok ? qBound(0, value, 100) : 100; + const int value = s->value(key, fallback).toInt(&ok); + return ok ? qBound(0, value, 100) : fallback; }; - speaker_volume = read_percent("controller_speaker_volume"); - vibration_intensity = read_percent("controller_vibration_intensity"); + speaker_volume = read_percent("controller_speaker_volume", 50); + vibration_intensity = read_percent("controller_vibration_intensity", 100); } }; diff --git a/src/libs/controller.cpp b/src/libs/controller.cpp index 379b807c..cdfa6f92 100644 --- a/src/libs/controller.cpp +++ b/src/libs/controller.cpp @@ -224,7 +224,9 @@ void GameController::CycleSetting(Setting setting) { float GameController::GetSettingScale(Setting setting) const { const auto step = m_setting_steps[static_cast(setting)].load(std::memory_order_relaxed); if (setting == Setting::SpeakerVolume) { - return SPEAKER_VOLUME[step] * (Config::GetControllerSpeakerVolume() / 100.0f); + // The old speaker level matches the PS5 slider's midpoint. Give the upper + // half of the global slider up to 6 dB of extra software gain. + return SPEAKER_VOLUME[step] * (Config::GetControllerSpeakerVolume() / 50.0f); } if (setting == Setting::VibrationIntensity) { return INTENSITY[step] * (Config::GetControllerVibrationIntensity() / 100.0f); diff --git a/src/main.cpp b/src/main.cpp index f821e931..ac3ff6c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,7 +54,7 @@ static void PrintUsage() { Config::DEFAULT_USER_ID); ::printf(" --mic Capture from this microphone; omit for silence.\n"); ::printf(" --controller-color <#RRGGBB> Override the controller lightbar color.\n"); - ::printf(" --controller-volume <0-100> DualSense speaker volume. Default: 100.\n"); + ::printf(" --controller-volume <0-100> DualSense speaker volume. Default: 50.\n"); ::printf(" --controller-vibration <0-100> DualSense vibration intensity. Default: 100.\n"); ::printf( " --present-mode Fifo, Mailbox, or Immediate. Default: Mailbox.\n"); diff --git a/tests/ControllerSettingsTests.cpp b/tests/ControllerSettingsTests.cpp index 7ca99a65..e26d7c64 100644 --- a/tests/ControllerSettingsTests.cpp +++ b/tests/ControllerSettingsTests.cpp @@ -112,7 +112,7 @@ struct Controller { Initialize(); Connect(1); Check(GetSettingScale(Setting::SpeakerVolume) == - Config::GetControllerSpeakerVolume() / 100.0f && + Config::GetControllerSpeakerVolume() / 50.0f && GetSettingScale(Setting::VibrationIntensity) == Config::GetControllerVibrationIntensity() / 100.0f && GetSettingScale(Setting::TriggerEffectIntensity) == 1.0f, @@ -165,7 +165,7 @@ void TestSettingCycles() { void TestGlobalControllerLevels() { Config::ConfigOptions options; - options.controller_speaker_volume = 50; + options.controller_speaker_volume = 25; options.controller_vibration_intensity = 25; Config::Load(options); { @@ -190,6 +190,23 @@ void TestGlobalControllerLevels() { Check(rumble.back().large == 17 * 257 && rumble.back().small == 8 * 257, "cycling vibration did not apply the combined intensity to cached rumble"); } + options.controller_speaker_volume = 50; + Config::Load(options); + { + Controller controller; + Check(GetSettingScale(Setting::SpeakerVolume) == 1.0f, + "speaker midpoint did not preserve the previous default level"); + } + options.controller_speaker_volume = 100; + Config::Load(options); + { + Controller controller; + Check(GetSettingScale(Setting::SpeakerVolume) == 2.0f, + "speaker maximum did not add 6 dB of gain"); + CycleSetting(Setting::SpeakerVolume); + Check(GetSettingScale(Setting::SpeakerVolume) == 0.0f, + "speaker maximum prevented the hotkey from muting"); + } options.controller_speaker_volume = 0; options.controller_vibration_intensity = 0; Config::Load(options); diff --git a/tests/PadHapticsTests.cpp b/tests/PadHapticsTests.cpp index 28e420d5..db5dbf65 100644 --- a/tests/PadHapticsTests.cpp +++ b/tests/PadHapticsTests.cpp @@ -1148,6 +1148,9 @@ void TestAudioSpeakerRouting() { speaker_scale = 0.5f; audio.AudioOutOutputs(&output, 1, false); ExpectPcm({0.25f, 0.25f, 0, 0, 0.25f, 0.25f, 0, 0}); + speaker_scale = 2.0f; + audio.AudioOutOutputs(&output, 1, false); + ExpectPcm({1.0f, 1.0f, 0, 0, 1.0f, 1.0f, 0, 0}); speaker_scale = 0.0f; audio.AudioOutOutputs(&output, 1, false); ExpectPcm({}); @@ -1165,7 +1168,7 @@ void TestAudioFallbackGain() { Fixture f; Libs::Audio::Audio audio; active_controller = 2; - speaker_scale = 0.5f; + speaker_scale = 2.0f; const std::array integer_pcm {16384, 16384, 16384, 16384}; const auto format = is_float ? Libs::Audio::Audio::Format::FloatStereo : Libs::Audio::Audio::Format::Signed16bitStereo; @@ -1176,7 +1179,7 @@ void TestAudioFallbackGain() { audio.AudioOutSetVolume(port, 3, volume.data()); Libs::Audio::Audio::OutputParam output {port, data}; audio.AudioOutOutputs(&output, 1, false); - const float expected = type == 4 ? 0.125f : 0.25f; + const float expected = type == 4 ? 0.5f : 0.25f; std::array actual {}; if (is_float) { Check(SDL_GetAudioStreamData(default_stream, actual.data(), sizeof(actual)) == @@ -1231,14 +1234,14 @@ void TestBluetoothAudioSpeakerRouting() { const auto port = audio.AudioOutOpen(4, 1024, 48000, Libs::Audio::Audio::Format::FloatStereo); Check(port.IsValid() && default_stream != nullptr, "Bluetooth pad speaker port did not open"); std::vector sound(2048, 0.25f); - speaker_scale = 0.5f; + speaker_scale = 2.0f; Libs::Audio::Audio::OutputParam output {port, sound.data()}; Check(audio.AudioOutOutputs(&output, 1, false) == 1024 && hid_opens == 1 && SDL_GetAudioStreamQueued(default_stream) == 0, "Bluetooth pad speaker also played on the host output"); fail_hid_write = true; auto pending = Libs::Controller::DualSenseBluetooth::Prepare(now * 1000000); - Check(pending.size() == 1 && std::abs(pending[0].audio[200] - 0.125f) < 1e-4f, + Check(pending.size() == 1 && std::abs(pending[0].audio[200] - 0.5f) < 1e-4f, "Bluetooth speaker did not apply its setting gain"); Libs::Controller::DualSenseBluetooth::Send(pending); Check(audio.AudioOutOutputs(&output, 1, false) == 1024 &&