From 63a0b97dd18047ec6916b993ccdac942a6090122 Mon Sep 17 00:00:00 2001 From: arabek Date: Fri, 25 Oct 2019 11:56:47 +0200 Subject: [PATCH] Normalize audio when downmixing to avoid clipping (#6867) * Normalize audio when downmixing to avoid clipping Idea came from this topic: https://hydrogenaud.io/index.php?topic=104214.msg855199#msg855199 Fixes very loud audio in Motorstorm (and probably other games when playing over headphones/stereo speakers with Downmix to Stereo option enabled) --- rpcs3/Emu/Cell/Modules/cellAudio.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellAudio.cpp b/rpcs3/Emu/Cell/Modules/cellAudio.cpp index 2285e85a62..15c354b855 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudio.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAudio.cpp @@ -754,7 +754,9 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset) if (port.state != audio_port_state::started) continue; auto buf = port.get_vm_ptr(offset); - static const float k = 1.0f; + static const float k = 1.f; + static const float minus_3db = 0.707f; /* value taken from + https://www.dolby.com/us/en/technologies/a-guide-to-dolby-metadata.pdf */ float& m = port.level; // part of cellAudioSetPortLevel functionality @@ -835,9 +837,10 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset) if constexpr (DownmixToStereo) { - const float mid = (center + low_freq) * 0.708f; - out_buffer[out + 0] = (left + rear_left + side_left + mid) * k; - out_buffer[out + 1] = (right + rear_right + side_right + mid) * k; + const float mid = center * minus_3db; /* don't mix in the lfe as per + dolby specification */ + out_buffer[out + 0] = (left + rear_left + (side_left * minus_3db) + mid) * k; + out_buffer[out + 1] = (right + rear_right + (side_right * minus_3db) + mid) * k; } else { @@ -870,9 +873,9 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset) if constexpr (DownmixToStereo) { - const float mid = (center + low_freq) * 0.708f; - out_buffer[out + 0] += (left + rear_left + side_left + mid) * k; - out_buffer[out + 1] += (right + rear_right + side_right + mid) * k; + const float mid = center * minus_3db; + out_buffer[out + 0] += (left + rear_left + (side_left * minus_3db) + mid) * k; + out_buffer[out + 1] += (right + rear_right + (side_right * minus_3db) + mid) * k; } else {