mirror of
https://github.com/libretro/boom3.git
synced 2026-11-07 10:15:59 -10:00
Final sweep over every quantization edge in the mixer. Verdict: no defects - but the conventions lived scattered across five files with nothing enforcing them, and one documented claim turned out false. The audit walked every edge: the feed-forward Q15 requantizers (round half up, one shared idiom), the recursive quantizers (QMUL/OCCQ/AIRQ/ EQMUL: sign-symmetric truncation toward zero, deliberately unrounded because |q(x*g)| <= |x*g| is the strict-contraction proof that tails decay to exact zero), the float->s16 edge (round half away, symmetric by construction), the accumulator narrow (saturate only - integer in, and scalar/SSE2-packs/NEON-vqmovn agree exactly), the soft knee (truncating rational, monotone, symmetric; float twin behavioral), Snd_ClampGainQ15 (already rounds, with its measured history), and the gain ramps. No dither anywhere, by decision: dither is noise by design and byte-exact reproducibility is the contract. All of it now lives in one QUANTIZATION CONVENTIONS block at the top of snd_mix_kernels.h, and five bench oracles lock the regimes: requantizer DC bias (measured -0.00001 LSB, max 0.500 pointwise), contraction property over 200k random (x, gain) pairs including sign symmetry, float->s16 symmetry and tie direction, knee float-vs-s16 curve agreement (worst 1.000 LSB over the full range), and the ramp endpoint bound. That last oracle earned the sweep: it disproved this audit's own first claim. The ramp's truncated per-frame increment accumulates, so a block's final gain sits up to numFrames/256 Q15 steps short of target - 16 steps, 0.004 dB, at the longest blocks - not 'under one step' as initially written. Behavior is fine (the next block re-anchors exactly, error never crosses blocks); the comment was wrong, and now says so, with the corrected bound in both the doc and the test. Zero output bytes change anywhere in this commit; FAIL-free on scalar, SSE2, NEON/aarch64, NEON/armv7.