From cf8b52735faf392591b4a71542113ba22984a613 Mon Sep 17 00:00:00 2001 From: Filoppi Date: Sat, 4 Jul 2020 20:21:52 +0300 Subject: [PATCH] Fix volume of emulated wii mote speakers not being native As in the comment, the panning was denaturalizing the volume (when the panning was at 0). Unless users actually want to use panning, their wii mote volume should not be reduced, it should come out at the same volume the samples were. If users want to reduce the volume of the wii mote speakers, they can do so from the wii home menu. I opted for this instead of adding another setting "Enable Panning" as it would have been confusing, and the changes in the panning formula are unlikely to have any negative effect, as it still works. --- Source/Core/Core/HW/WiimoteEmu/Speaker.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp index c3131cc6f2..ccddee2244 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp @@ -128,16 +128,21 @@ void SpeakerLogic::SpeakerData(const u8* data, int length, float speaker_pan) } // SetWiimoteSpeakerVolume expects values from 0 to 255. - // Multiply by 256, cast to int, and clamp to 255 for a uniform conversion. - const double volume = float(reg_data.volume) / volume_divisor * 256; + // Multiply by 256, floor to int, and clamp to 255 for a uniformly mapped conversion. + const double volume = float(reg_data.volume) * 256.f / volume_divisor; - // Speaker pan using "Constant Power Pan Law" - const double pan_prime = MathUtil::PI * (speaker_pan + 1) / 4; + // This used the "Constant Power Pan Law", but it is undesirable + // if the pan is 0, and it implied that the loudness of a wiimote speaker + // is equal to the loudness of your device speakers, which isn't true at all. + // This way, if the pan is 0, it's like if it is not there. + // We should play the samples from the wiimote at the native volume they came with, + // because you can lower their volume from the Wii settings and because they are + // already extremely low quality, so any additional quality loss isn't welcome. + speaker_pan = std::clamp(speaker_pan, -1.f, 1.f); + const u32 l_volume = std::min(u32(std::min(1.f - speaker_pan, 1.f) * volume), 255u); + const u32 r_volume = std::min(u32(std::min(1.f + speaker_pan, 1.f) * volume), 255u); - const auto left_volume = std::min(int(std::cos(pan_prime) * volume), 255); - const auto right_volume = std::min(int(std::sin(pan_prime) * volume), 255); - - g_sound_stream->GetMixer()->SetWiimoteSpeakerVolume(left_volume, right_volume); + g_sound_stream->GetMixer()->SetWiimoteSpeakerVolume(l_volume, r_volume); // ADPCM sample rate is thought to be x2.(3000 x2 = 6000). const unsigned int sample_rate = sample_rate_dividend / reg_data.sample_rate;