From 9c1516171e748075c6d586a4d233fea7b0dbbd1b Mon Sep 17 00:00:00 2001 From: Matiq Date: Wed, 19 Aug 2026 20:10:22 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20runtime=20capture=20settled=20=E2=80=94?= =?UTF-8?q?=20registry=20heartbeat=20decodes=20live=200x540658=20window=20?= =?UTF-8?q?&=20freq-axis=20(internal=20SR=3D48000);=20vptr-scan=20route=20?= =?UTF-8?q?closed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handoff/NOTES_LEVEL.md | 66 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/handoff/NOTES_LEVEL.md b/handoff/NOTES_LEVEL.md index 9abe708..d1c5e5d 100644 --- a/handoff/NOTES_LEVEL.md +++ b/handoff/NOTES_LEVEL.md @@ -556,3 +556,69 @@ Weighted refits move error around but never reduce max < 0.7: rp(Q) ~ Q^0.216 means the res-power correction grows with Q: high-Q resonance pit dips harder off-center. Consistent with decomp (res-weighted gain path in twin-mask factory). The q1@2000 residual is structural warp/model mismatch, not rp. + +## ============ 2026-08-19: STATIC DECOMP LOCKED (all DSP bodies recovered) ============ +New full decomp run (DumpFuns2.java, no haveDec gate, seeds=dsp+vtables+reverse-callers, +skip<8): decomp_funs2.txt (7746 bodies), fun_map2.txt (7928 funcs), consts2.txt (41622). +Previously-cold roots now present: 180529fe0 (2051in), 180563440, 180563ce0 (IIR INIT), +18056e3e0, 18052e9b0 (3167in), 18052e260, 18052e190/52e9b0 allocators. + +### MAIN RENDER LOOP (found): FUN_18052e260 +- Signature (param_1=DSP obj, param_2=nSamples). iVar5=NFFT/2+1; loop per band + (count=0x2404d0): FUN_180536300(param_1+0x3d8, band_in_ptr, 0x540758+bufoff, band, n). + Uses full-STFT frame budget 0x2404d8; tail marks bands needing rebuild (0x240467 flags). +- => 52e260 = per-frame dual-band SIDE-CHAIN driver; twin = per-band. + +### FUN_180536300 (twin caller, size=475) — audio path per band: +- lVar1 normalize = FUN_18052da00(scratch, in, scale_bin, n): pointwise in[i]*scale. +- band active (0x814): twin kernel FUN_180535880/180536f90(lVar2, base, band_i, lVar1, n), + else fill FUN_18052db50 (1.0 / 0.0). +- combine lVar4/lVar3 (52d990, 0x814>1), output copy 52dbc0(base, lVar4, n). +- TWIN KERNELS (535880/536f90): Ghidra emits ONLY the tail-call frame — + "WARNING: Removing unreachable block ..." => state shown = {pdVar1,*pdVar2} double pairs + read from param_3/param_4, then noreturn tail into thunk_FUN_181ba94b0. **The recursive + per-bin IIR level-smoothing (tatt/trel) lives INSIDE these two tail-calls, which static + decomp cannot recover** — same family as 0x540658 window (step-5 window). Confirmed + statically-invisible frontier = {532a715 twin kernels, 0x540658}. + +### Level-param setters (vtable stubs, auto-named .?AV?$Soothe2Module@M$01@@::vtbl_...): +- 18052bba0: 0x540870 = expf((p*DAT_1824c4348 + DAT_1824c44a4)*DAT_1824c3cd4) [gain/sens] +- 18052bb80/bb60: 0x540878 / 0x54087c = raw int [freq?/bandwidth?] +- 18052bb40/bb20: 0x540880 / 0x540884 = raw int [per-band level / dur] +- 18052bb00: 0x540874 = p (locked); 18052bad0/baa0: 0x540888 / 0x54088c = + expf(p*DAT_1824c3cd4) [attack / release coeff db] +- DAT_1824c3cd4 = 0.115129255 = ln(10)/20 => expf(p*0.11513) = 10^(p/20): **all these + setters convert dB-speed params to linear coeffs**. 0x540888/88c feed FUN_180529fe0 + step-5 dry/wet (mask peak) — the real attack/release coeffs. +- FUN_180530d30 (0x5406b8/6c8/6d8/6e8 weights): fVar9 = 2000.0/NFFT? base; w8=pow(base,0.25); + v = level*0.25*w8*factor(4.0); q=1/(1+v/(level*4)); dVar1=(sr/0x1a0)*0x1ac*0.001; + w = 0.1^(1/(max(q*v)*dVar1)); pairs (w,1-w). +- Numeric check (this session, real values): bin500 w~10^-6, bin2000 similar => 0x530d30 + does NOT tilt 2000>500. Tilt stays = warp (0x5406a8, K=7.942) + twin-mask curving. + Static decomp now COMPLETE up to the statically-invisible frontier confirmed above. + +## ============ 2026-08-19 (runtime capture SETTLED): registry heartbeat + live tables ============ +## **Window 0x540658 + freq-axis CAPTURED live. Internal DSP sample rate = 48000 (not 44100).** +- rtsnap_fast.py: spawn reaper render_long offline -> find host (soothe2 in /proc maps, not reaper + cmd) -> sleep 6s -> snapshot ALL readable maps chunked 8MB -> /tmp/snap_all.bin (318MB, 546 regs, + entries {lo,sz,bytes}+pad, idx in /tmp/snap_all.idx). Chunked pread REQUIRED: whole-region pread EIO. +- **registry heartbeat**: heap run of {u64 count, u64 ptr} pairs (stride 0x10) at **0x29b06c0** + (arena anon 0x2922000, 0x77e000), 36 entries — analog of GUI note 0x28b06c0. Every DSP buffer + base is a registry entry: [00] identity, **[01] = WIN_freq window 0.5->1.0 (saturates)** (this is + live 0x540658 8193 f32: 0.5, idx512=0.345?; idx1024=0.68, idx2048=0.8, tail 1.0), + [02] 0->~0.01, [03]=rwin_C0 0.596->0.126, [04]=0.404->0.874 complement, [05]=0.0435->~0, + [06]=0.9565->~1.0, [07] zeros+neg, [0d]=**freq-axis 0..23988.3 spacing 11.713 = 48000/4096**, + [0e]=2.017->0, [0f] doubled, [10]=1.2914->0, FFT work bufs 131072/32768/65536/16384. +- **CRITICAL**: freq-axis spacing 11.713 Hz => internal SR = 48000 regardless of project 44100. + Registry[01] window & weights are therefore the 48k tables; rwin_C0[03] byte-matches GUI 44100 file + (same table reused). Saved live tables: + - handoff/rtfreqaxis_48000_internal.npy (2048 f32, 0..23988.287, spacing 11.713) + - handoff/rtwin_freq_44100.npy (8193 f32 WIN window 0.5->1.0) <-- THE 0x540658 live capture + - handoff/rtwa_596.npy, rtwb_404.npy, rtwc_043.npy, rtwd_956.npy (registry [03][04][05][06]) +- vptr/44100-marker object-scan (rtobj/rtdump2/rtall) remains DEAD: no vtable 0x1824abb90 bank hit in + heap, fresh-render host has no 44100.0 constants (internal is 48k). The registry run is the beacon. +- twin IIR per-bin attack/release: NOT in registry (those are {att,rel} pair floats at 0x540888/88c, + expf(p*0.11513), per-note-band smoothing inside tail-call thunks). Live capture needs the twin band + object; not yet located. Registry gives per-bin WEIGHTS (done) — attack/release remain static-only. +- Registry dump + all raw tables saved: /tmp/rtcapt/registry.txt, /tmp/rtcapt/*.f32. +- Scripts captured into repo: rtsnap_fast.py (snapshot), findctx.py (locate), rtchunk.py (chunked IO).