From 22e4599e0a423d4b6f43cf3161a2d8ed99efbd0a Mon Sep 17 00:00:00 2001 From: Matiq Date: Thu, 20 Aug 2026 01:30:33 +0300 Subject: [PATCH] =?UTF-8?q?P2:=20decode=20mask-accumulator=20combine=20ker?= =?UTF-8?q?nels=20from=20raw=20bytes=20=E2=80=94=20combine3(0x8d60)=3Dsub,?= =?UTF-8?q?=20acc=5Fadd(0x5a20)=3Ddst+=3Dsrc,=20acc=5Ffma(0x3c40)=3Ddst+?= =?UTF-8?q?=3Da=C2=B7b;=20implement=20+=20levelpath=5Fcheck=20ALL=20OK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dsp/levelpath.cpp | 21 +++++++++++++++++++-- dsp/levelpath.hpp | 5 +++++ dsp/levelpath_check.cpp | 15 +++++++++++++++ handoff/NOTES_LEVEL.md | 18 ++++++++++++++++++ 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/dsp/levelpath.cpp b/dsp/levelpath.cpp index fcb4d5b..95d9fac 100644 --- a/dsp/levelpath.cpp +++ b/dsp/levelpath.cpp @@ -156,9 +156,26 @@ void band_lut_apply(void* ctx) { } } +// ---- mask-accumulator combine kernels (FUN_180529fe0, CRT thunks) ---- +// Signatures recovered from raw bytes in the rt snap (objdump of 0x180008d60/5a20/3c40). +// +// 0x8d60 combine3: out[i] = a[i] - b[i] (vsubpd, 3 pointers; dst is the 3rd arg) +// In the per-band loop: 0x5406f8[i] = 0x540678[i] - 0x5407c8[i] +void combine_sub(double* out, const double* a, const double* b, int n) { + for (int i = 0; i < n; i++) out[i] = a[i] - b[i]; +} + +// 0x5a20: dst[i] += src[i] (double; kernel 0x18001a5a0) +void acc_add(double* dst, const double* src, int n) { + for (int i = 0; i < n; i++) dst[i] += src[i]; +} + +// 0x3c40: dst[i] += a[i] * b[i] (double; vfmadd213pd) +void acc_fma(double* dst, const double* a, const double* b, int n) { + for (int i = 0; i < n; i++) dst[i] += a[i] * b[i]; +} + // FUN_180529fe0: coefficient setup (from decomp_funs.txt) -// Generates per-band coefficients via PRNG, applies depth scaling -// This is the vtable method for Soothe2Module void coefficient_setup(void* ctx, int band_idx, int param3, int param4) { auto* base = static_cast(ctx); diff --git a/dsp/levelpath.hpp b/dsp/levelpath.hpp index cbe916c..01edc6e 100644 --- a/dsp/levelpath.hpp +++ b/dsp/levelpath.hpp @@ -11,3 +11,8 @@ void twin_mask_factory(void* ctx, int band_idx, int n_bins); // FUN_180563a60: band LUT apply (level -> gain) t^gamma / power-law, 6 bands. void band_lut_apply(void* ctx); + +// mask-accumulator combine kernels (FUN_180529fe0 CRT thunks). +void combine_sub(double* out, const double* a, const double* b, int n); // 0x8d60 +void acc_add(double* dst, const double* src, int n); // 0x5a20 +void acc_fma(double* dst, const double* a, const double* b, int n); // 0x3c40 diff --git a/dsp/levelpath_check.cpp b/dsp/levelpath_check.cpp index e9162c1..9b064d0 100644 --- a/dsp/levelpath_check.cpp +++ b/dsp/levelpath_check.cpp @@ -48,6 +48,21 @@ int main() { chk("band_lut_apply level_axis[512]", level_gain[1024], 0.5f, 1e-6); } + // ---- combine kernels (0x8d60/0x5a20/0x3c40) ---- + { + double out[4] = {0, 0, 0, 0}; + double a[4] = {5, 2, -1, 8}; + double b[4] = {3, 7, 4, 2}; + combine_sub(out, a, b, 4); + chk("combine_sub[0] a-b", out[0], 2.0, 1e-12); + chk("combine_sub[2] a-b", out[2], -5.0, 1e-12); + acc_add(out, a, 4); // out = (a-b) + a + chk("acc_add[0]", out[0], 7.0, 1e-12); // (5-3)+5 = 7 + acc_fma(out, b, a, 4); // out += b*a + // out[1] = (2-7)+2 = -3, then -3 + b[1]*a[1] = -3 + 7*2 = 11 + chk("acc_fma[1]", out[1], 11.0, 1e-12); + } + std::printf(ok ? "ALL OK\n" : "FAILURES\n"); return ok ? 0 : 1; } \ No newline at end of file diff --git a/handoff/NOTES_LEVEL.md b/handoff/NOTES_LEVEL.md index 21a6cdc..05fc695 100644 --- a/handoff/NOTES_LEVEL.md +++ b/handoff/NOTES_LEVEL.md @@ -160,6 +160,24 @@ Остаток 0.7 dB (Q=0.1) = LUT-колено 0.574 -> нужен FFT-уровень (0x535a70 + окно 0x540658 + freq-axis 0x540698), см. SESSION_HANDOFF §5-6. +## ============ UPDATE 2026-08-20h: P2 mask-accumulator combine kernels DECODED ============ +Raw bytes from rt snap (objdump of image 0x180008d60/5a20/3c40). Implemented in dsp/levelpath.cpp. + +### Exact CRT thunk semantics (per-bin double ops in FUN_180529fe0): +- **0x8d60 combine3(dst,a,b,n) = sub**: out[i] = a[i] − b[i] (vsubpd; dst is the 3rd pointer). + Per-band call: 0x5406f8[i] = 0x540678[i] − 0x5407c8[i]. (corrects NOTES:348 "combine" TBD) +- **0x5a20 acc_add(dst,src,n)**: dst[i] += src[i] (double; kernel 0x18001a5a0). +- **0x3c40 acc_fma(dst,a,b,n)**: dst[i] += a[i]·b[i] (double; vfmadd213pd). +- 0x11940 = copy/mirror (complex, 5th arg stride 0/4 → kernel 0x1a88300), 0x6e40 = dst=src·scalar, + 0x15060 = buf+=scalar, 0x8700 = dst*=src (float, warp), 0x9be0 = buf=scalar·buf. + +### Full mask-accumulator per band (0x5408b8==0): + 1. 0x5406f8 = 0x540678 − 0x5407c8 (8d60 sub) + 2. mirror 0x5406f8 halves (11940) + 3. 0x5407c8 += 0x5406c8 · 0x5406f8_upper (3c40, stride4) + 4. 0x5407c8 += 0x5406e8 · 0x5406f8_lower (3c40) + 5. 0x5407c8 += 0x540678 (5a20) + ## ============ UPDATE 2026-08-20g: P2.5 twin-mask factory + band LUT apply DECODED ============ Source: decomp_funs2.txt (FUN_18056e3e0:7988, FUN_180563a60:8975, FUN_180563440:7697) + f_56e3e0.dis + f_563a60.dis. Implemented in dsp/levelpath.cpp (levelpath_check ALL OK).