From 6ee3d0102b51798c7f8001948e202a0b3758cd9a Mon Sep 17 00:00:00 2001 From: Simon Arlott <sa.me.uk> Date: Sat, 27 May 2023 20:13:53 +0100 Subject: [PATCH] decoder/mad: Fix decode of LAME peak value 6d91b5c7b21926137c63561e313afd1fb72274f8 ("fix double promotions") changed how LAME peak values are decoded, producing large incorrect values that cause some MP3 files to play silently. Restore the original decode from MAD fixed-point format to double and document what it's doing. Fixes #1823 --- NEWS | 2 ++ src/decoder/plugins/MadDecoderPlugin.cxx | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index b82032c82..fec18ffb4 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.23.14 (not yet released) +* decoder + - mad: fix calculation of LAME peak values ver 0.23.13 (2023/05/22) * input diff --git a/src/decoder/plugins/MadDecoderPlugin.cxx b/src/decoder/plugins/MadDecoderPlugin.cxx index 7e34c25b1..d861e2e6e 100644 --- a/src/decoder/plugins/MadDecoderPlugin.cxx +++ b/src/decoder/plugins/MadDecoderPlugin.cxx @@ -562,7 +562,21 @@ parse_lame(struct lame *lame, struct mad_bitptr *ptr, int *bitlen) noexcept mad_bit_skip(ptr, 16); - lame->peak = MAD_F(mad_bit_read(ptr, 32) << 5); /* peak */ + /* The lame peak value is a float multiplied by 2^23 and stored as an + * unsigned integer (it is always positive). MAD's fixed-point format uses + * 28 bits for the fractional part, so shift the 23 bit fraction up before + * converting to a float. + */ + unsigned long peak_int = mad_bit_read(ptr, 32); + +#define LAME_PEAK_FRACBITS 23 +#if MAD_F_FRACBITS > LAME_PEAK_FRACBITS + peak_int <<= (MAD_F_FRACBITS - LAME_PEAK_FRACBITS); +#elif LAME_PEAK_FRACBITS > MAD_F_FRACBITS + peak_int >>= (LAME_PEAK_FRACBITS - MAD_F_FRACBITS); +#endif + + lame->peak = mad_f_todouble(peak_int); /* peak */ FmtDebug(mad_domain, "LAME peak found: {}", lame->peak); lame->track_gain = 0;