From 5f71c81e1bce080f70509d53d256375acf9a665c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Fri, 14 Oct 2022 12:22:18 +0200 Subject: [PATCH] LibAudio: Correctly rescale 8-bit PCM samples 8-bit PCM samples are unsigned, at least in WAV, so after rescaling them to the correct range we also need to center them around 0. This fix should make 8-bit WAVs have the correct volume of double of what it was before, and also future-proof for all other unsigned PCM sample formats we may encounter. --- Userland/Libraries/LibAudio/WavLoader.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibAudio/WavLoader.cpp b/Userland/Libraries/LibAudio/WavLoader.cpp index ee3ff339b6..2747615386 100644 --- a/Userland/Libraries/LibAudio/WavLoader.cpp +++ b/Userland/Libraries/LibAudio/WavLoader.cpp @@ -83,8 +83,16 @@ static ErrorOr read_sample(Core::Stream::Stream& stream) { T sample { 0 }; TRY(stream.read(Bytes { &sample, sizeof(T) })); + // Remap integer samples to normalized floating-point range of -1 to 1. if constexpr (IsIntegral) { - return static_cast(AK::convert_between_host_and_little_endian(sample)) / static_cast(NumericLimits::max()); + if constexpr (NumericLimits::is_signed()) { + // Signed integer samples are centered around zero, so this division is enough. + return static_cast(AK::convert_between_host_and_little_endian(sample)) / static_cast(NumericLimits::max()); + } else { + // Unsigned integer samples, on the other hand, need to be shifted to center them around zero. + // The first division therefore remaps to the range 0 to 2. + return static_cast(AK::convert_between_host_and_little_endian(sample)) / (static_cast(NumericLimits::max()) / 2.0) - 1.0; + } } else { return static_cast(AK::convert_between_host_and_little_endian(sample)); }