From 7a108c529a708985de3c9d64903b954536c9ed8b Mon Sep 17 00:00:00 2001 From: Matiq Date: Fri, 21 Aug 2026 12:36:35 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20NOTES=5FLEVEL=20update=20=E2=80=94=20LU?= =?UTF-8?q?T=20level-domain=20discovery,=20sweep=20tooling=20hazard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handoff/NOTES_LEVEL.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/handoff/NOTES_LEVEL.md b/handoff/NOTES_LEVEL.md index 0e16b63..b9370df 100644 --- a/handoff/NOTES_LEVEL.md +++ b/handoff/NOTES_LEVEL.md @@ -1182,3 +1182,42 @@ cut. => Naive additive/sens formulas CANNOT model the negative-sens band interac lives in the structural combine/acc 0x5407c8 (per-bin weights kRTAtt/kRTRel + negative sens entering the level path with opposite sign), which requires the real exp2-domain chain, not the bridge. comb stays OPEN (structural combine/acc, P4/P5). + +## ============ UPDATE 2026-08-21: LUT moved to LEVEL domain (structural chain) ============ +### Discovery: mask-domain LUT clamps on loud input +- Mask-domain LUT (committed 9b7e9d3) computes t=(mask_dB-A)/(B-A); for loud input + (tone1k 0dBFS) post-exp2 mask_dB < A=-13.78 => t clamps to 0 => val=0 => FULL cut. + Measured t1k err -24.04 dB. Root cause: exp2(-level) output dB range is unbounded + below, LUT domain [A,B] assumes bounded input. +- FIX: apply FUN_180563a60 power-law to LEVEL (am/res*scale) BEFORE IIR/exp2: + lvl = pow(t, gamma)*MULT, t=(20*log10(lvl)-A)/(B-A) clamp [0,1]. + Level dB stays inside [A,B] for both quiet (t1kq: +6.2dB) and loud (t1k: +24dB). + Result: t1k err -24.04 -> +2.45 dB. + +### TOOLING HAZARD: stale-binary sweeps +- cmake --build skips recompile when source mtime unchanged within same second; + param sweeps silently re-run the SAME binary (9-point sweep -> 1 unique result). + Earlier "gamma doesn't matter" observation was this artifact, NOT DSP behavior. +- Protocol now: os.utime(src) before build + assert binary mtime fresh (sweep_fresh.py). + +### Fresh 2D sweep (g x mult, verified builds), 3-case smoke (render48k 48k/4096): + g=0.344 m=3.8 optimum: t1kq=-0.788 t1k=+2.453 al12=+0.037 mean|err|=1.093 + (committed version was mean 8.2). gamma>=0.9 ALL worse (+2..+5): spatial IIR + after LUT redistributes peaks; naive ratio math (need g=1.17 from raw t ratio + 1.744->2.0) does NOT survive the IIR chain. Empirics rule. +- MULT=3.8 is a PLACEHOLDER (maps t^gamma back to level domain; no decomp basis yet). + A/B/gamma are decomp-extracted (BandConfig ctx+0x188 refs, NOTES:967). + +### Scope clarification +- scripts/corpus.py exercises the BRIDGE path only (44.1k non-internal grid): + full corpus 1.594 mean / comb 10.15 — UNCHANGED by structural work (verified + stash-compare). comb regression is pre-existing bridge state, separate issue. +- Structural chain validated via render48k smoke (3 cases) + module checks + (fn529fe0/exp2/twin/tables/leveltrack/levelpath/fftconv all PASS). +- render48k tail artifact: last BLK=65536 block zero-pads => am decays in final + frames (~last 0.06s of y48). Cosmetic; metric window barely affected. + +### Commit: 535b150 (LUT level-domain restructure). +NEXT: step 3 wire combine_acc track into mask output (currently computed, +discarded); step 4 FFT-conv 0x535a70 mask smoothing; then decode BandConfig +ctx+0x188 writers to replace MULT placeholder with decomp value.