Very low bitrate WMA files send their spectral envelope as LSP
coefficients. The curve computed from them squares two products
whose value can reach about a million, in 16.16 fixed point. Where
the envelope should be lowest the squares overflowed, and those
points came out near the curve's maximum instead: bands at the top
of the spectrum up to 17 dB too loud, and everything else a few dB
low, as levels are taken relative to the maximum.
Sum the squares in 64 bits, and let pow_m1_4() take a value above
the 16.16 range.
Checked with perfsim (Sansa e200v1 build). The curve is within
0.2 dB of ffmpeg's formula at all 57600 points of 80 blocks traced
from two files. Against ffmpeg's decode, as the mean difference in
band levels over the whole file, with the noise coding fix applied
before and after:
StutteringFile (22 kHz mono, 20 kbps) 1.6 dB -> 0.3 dB
shoujicomcn2117164 (same) 0.2 dB -> 0.1 dB
terra8k (11 kHz mono, 8 kbps) 0.3 dB -> 0.0 dB
Only the five files that use LSP exponents change; the other 23
are byte-identical.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Low bitrate WMA files code their upper bands as noise at a given
power. Those bands came out 12 to 25 dB too quiet, which dulled
the treble. Two things were wrong.
The exponent pointer was moved too far in blocks whose exponents
have another resolution. This is ffmpeg's r20756 (f78501b264,
"Fix apparent 10l typos introduced in r8627"); r8627 was merged
here in 2f1da8d24a but the fix for it never was.
The fixed point gain of a band lost nearly all its precision: it
was zero for three bands in four in the file traced, and the sum
for a band's power overflowed in a quarter of them. Compute the
gain in 64 bits, once a band. The factor for the noise below the
first coded coefficient (WMA v1 only) was 16 bits too large and is
corrected by the same reasoning; no file here exercises it.
Checked with perfsim (Sansa e200v1 build) against ffmpeg's decode,
as the mean difference in band levels over the whole file:
01 - Jane Austen (44.1 kHz, 32 kbps) 5.5 dB -> 0.0 dB
07.Devil.In.My.Mind (same) 6.2 dB -> 0.0 dB
beyonthepain907z (same) 6.8 dB -> 0.0 dB
moshimoashitaga (same) 2.8 dB -> 0.0 dB
Four more noise coded files, already within 0.3 dB, now match too.
The output of the 15 files without noise coding is byte-identical.
Files that use LSP exponents still differ in their top bands; that
is a separate fault in the LSP curve.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The LSP feature in WMA requires that the noise table values be
doubled verses when it is not used. Unfortunately, the previous
code would double the same values every time a LSP file was
decoded without first resetting them to their original values.
Change the code to check if the values are already doubled, and
then double/halve them as needed. This is still a bit ugly,
in the future consider using the built in rockbox dither instead
of a lookup table.
Fixes playback when skipping back and forth between low and high
bitrate WMA.
Change-Id: I4c393092e4a789bc8f98d74274fe207400b9550e
Reviewed-on: http://gerrit.rockbox.org/226
Reviewed-by: Michael Giacomelli <giac2000@hotmail.com>
Tested-by: Michael Giacomelli <giac2000@hotmail.com>