An MPEG audio codec in Zig that decodes Layers I, II and III and encodes Layers II and III.

Replace the psychoacoustic model with one that measures tonality properly

The old model decided how tonal a band was from its spectral flatness, which is a reasonable guess and not much more: flatness cannot tell a steady tone from a burst of noise that happens to be concentrated, and it was computed per band, so a single tone in a wide band was averaged against everything beside it. Tonality is the thing this kind of model most needs to get right, since a tone hides far less noise than a noise of the same energy. The replacement is the shape of the standard's informative Psychoacoustic Model 2, whose idea is that tonality is predictability. A steady sinusoid advances its phase by the same amount every frame and holds its magnitude, so the next frame extrapolates from the last two almost exactly; noise does not extrapolate at all. So rather than ask what a band's spectrum looks like, it asks how well each bin was predicted -- per bin, and far sharper. Around that sit thresholds on partitions of a third of a critical band, a spreading curve steepened below the masker, and a limit on how far the threshold may rise above what the last two frames allowed, which is what keeps a loud frame from licensing noise across the quiet one in front of it. Written from the published description rather than ported. The models worth learning from -- LAME's above all -- are LGPL and this is MIT, but a psychoacoustic model is not normative, no decoder ever sees it, and the algorithm is in the literature; what is implemented from a description is not a derivative work of anyone's code. The permissively licensed alternatives were checked and turned down on fit rather than licence: libvorbis's psy.c is BSD-3-Clause and mature, but it is built around Vorbis's own transform sizes and floor curves and does not produce a signal-to-mask ratio at all. Both encoders use it, and both improve at every setting in the matrix: Layer II 48000 stereo 256k 19.16 -> 24.11 dB Layer II 32000 stereo 192k 19.35 -> 22.21 Layer II 44100 stereo 192k 18.79 -> 20.03 Layer III 48000 stereo 256k 29.05 -> 30.09 Layer III 44100 stereo 192k 25.28 -> 26.01 Layer III 44100 stereo 128k 20.06 -> 20.75 Those are signal-to-noise ratios and so the weakest evidence available for a change of this kind: a model exists to put noise where it will not be heard, and a better one can perfectly well score worse. What they do say is that nothing regressed and that fewer bits are going somewhere they were not needed. The claim stops there, because nothing here has been listened to. The model measures a Fourier spectrum and Layer III quantizes an MDCT one, so what crosses between them is the proportion -- how far below its own energy a band's noise has to sit -- applied to the energy the transform really produced. The two scales are not the same and nothing makes them so. `psychoacoustic.zig` is gone rather than kept beside it. Two models that disagree are not a cross-check, since disagreeing is the whole point of replacing one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Aj95dBZhkUtaGfEW8ZXbHx


Author
Co-author Claude Opus 5 (1M context) Date Commit Parent 1ce4a238