From b7170e03c4671d2296d1526508afd6e06c7ece89 Mon Sep 17 00:00:00 2001 From: Michael Giacomelli Date: Tue, 6 Oct 2026 01:15:08 -0400 Subject: [PATCH] atrac3: apply the whole mdct window Only the first and last 128 points of the 512 point window were applied, and the 256 between were taken to be one. They are not: the window rises to 1.207 there. Every block was therefore up to 1.6 dB low over half its length, which left the output 0.7 dB low on average and an error about 23 dB below the signal at all frequencies. Add the missing half of the table and apply it. Checked with perfsim (Sansa e200v1 build) against ffmpeg's decode, with the two previous fixes applied before and after: level SNR five plain stereo RM files -0.7 dB 23 dB -> 0.0 dB 54-57 dB joint stereo RM file -0.7 dB 23 dB -> 0.0 dB 37-45 dB joint stereo OMA file -0.7 dB 23 dB -> 0.0 dB 45 dB Co-Authored-By: Claude Opus 5.5 --- lib/rbcodec/codecs/libatrac/atrac3.c | 7 ++++- .../codecs/libatrac/atrac3data_fixed.h | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/rbcodec/codecs/libatrac/atrac3.c b/lib/rbcodec/codecs/libatrac/atrac3.c index 877e2fbfc6..ea3b02fc86 100644 --- a/lib/rbcodec/codecs/libatrac/atrac3.c +++ b/lib/rbcodec/codecs/libatrac/atrac3.c @@ -252,11 +252,16 @@ atrac3_imdct_windowing(int32_t *buffer, const int32_t *win) { int32_t i; - /* win[0..127] = win[511..384], win[128..383] = 1 */ + /* win[0..127] = win[511..384] */ for(i = 0; i<128; i++) { buffer[ i] = fixmul31(win[i], buffer[ i]); buffer[511-i] = fixmul31(win[i], buffer[511-i]); } + /* win[128..255] = win[383..256] = 1 + window_lookup_mid[] */ + for(i = 0; i<128; i++) { + buffer[128+i] += fixmul31(window_lookup_mid[i], buffer[128+i]); + buffer[383-i] += fixmul31(window_lookup_mid[i], buffer[383-i]); + } } diff --git a/lib/rbcodec/codecs/libatrac/atrac3data_fixed.h b/lib/rbcodec/codecs/libatrac/atrac3data_fixed.h index 3cc4e0837c..54ec832880 100644 --- a/lib/rbcodec/codecs/libatrac/atrac3data_fixed.h +++ b/lib/rbcodec/codecs/libatrac/atrac3data_fixed.h @@ -76,6 +76,35 @@ static const int32_t window_lookup[128] ICONST_ATTR MEM_ALIGN_ATTR = { -0x82660c01, -0x80ca4a01, }; +/* The window above is the first 128 points of the 512 point mdct window. + * Points 128..255 are these values plus one, scaled by 2^31; they rise to + * 1.207 and fall back to 1. The second half of the window mirrors the + * first. */ +static const int32_t window_lookup_mid[128] ICONST_ATTR MEM_ALIGN_ATTR = { + 0x00c7d1c8, 0x024fd962, 0x03cd6738, 0x05401bc8, 0x06a79e95, 0x08039e75, + 0x0953d1d1, 0x0a97f6df, 0x0bcfd3c6, 0x0cfb36c3, 0x0e19f636, 0x0f2bf0a8, + 0x10310cc9, 0x11293955, 0x12146d01, 0x12f2a64e, 0x13c3eb59, 0x148849a0, + 0x153fd5c0, 0x15eaab2c, 0x1688ebd9, 0x171abfeb, 0x17a05559, 0x1819df8c, + 0x188796ff, 0x18e9b8db, 0x1940868e, 0x198c456d, 0x19cd3e43, 0x1a03bcf6, + 0x1a301021, 0x1a5288af, 0x1a6b7984, 0x1a7b371a, 0x1a821730, 0x1a807072, + 0x1a769a2c, 0x1a64ebfc, 0x1a4bbd8d, 0x1a2b6653, 0x1a043d52, 0x19d698de, + 0x19a2ce6d, 0x19693261, 0x192a17e5, 0x18e5d0be, 0x189cad2d, 0x184efbcf, + 0x17fd0985, 0x17a72158, 0x174d8c6b, 0x16f091e8, 0x169076f2, 0x162d7ea1, + 0x15c7e9f4, 0x155ff7cf, 0x14f5e4fc, 0x1489ec23, 0x141c45d4, 0x13ad2886, + 0x133cc89d, 0x12cb5870, 0x12590851, 0x11e60697, 0x11727fa4, 0x10fe9df7, + 0x108a8a2e, 0x10166b1a, 0x0fa265c6, 0x0f2e9d86, 0x0ebb3404, 0x0e48494e, + 0x0dd5fbe2, 0x0d6468bc, 0x0cf3ab63, 0x0c83ddf9, 0x0c151945, 0x0ba774c2, + 0x0b3b06af, 0x0acfe414, 0x0a6620d7, 0x09fdcfc5, 0x0997029e, 0x0931ca20, + 0x08ce3615, 0x086c555d, 0x080c35f8, 0x07ade513, 0x07516f11, 0x06f6df92, + 0x069e4182, 0x06479f20, 0x05f30203, 0x05a0732a, 0x054ffafe, 0x0501a15d, + 0x04b56d9f, 0x046b66a1, 0x042392c9, 0x03ddf80e, 0x039a9bfc, 0x035983bd, + 0x031ab41f, 0x02de3196, 0x02a40042, 0x026c23f9, 0x0236a043, 0x02037867, + 0x01d2af6a, 0x01a44813, 0x017844f1, 0x014ea85c, 0x0127747d, 0x0102ab49, + 0x00e04e8c, 0x00c05fe5, 0x00a2e0cf, 0x0087d29c, 0x006f367d, 0x00590d81, + 0x00455897, 0x00341890, 0x00254e20, 0x0018f9df, 0x000f1c4a, 0x0007b5c4, + 0x0002c697, 0x00004ef5, +}; + /* Gain tables scaled by 2^16 */ static const int32_t gain_tab2[31] ICONST_ATTR = { 0x0003ab03, 0x00035d14, 0x0003159d, 0x0002d414, 0x000297fb, 0x000260e0,