P4: decode FUN_180529fe0 mono-path exactly + extract live mask tables

Full decomp of the per-band mask-apply loop (scale -> IIR1/2/3 leaky ->
blend -> exp2 bigkernel -> combine/accumulate -> dual warp -> dry/wet -> FFT-conv).
Extracted runtime tables to rt_mask_tables.{hpp,cpp}: IIR A1/B1,A2/B2,A3/B3
(leaky y=A*acc+B*x, B=1-A), warp 0x5406a8, per-band 0x540768, PRNG LUT 0x5408b0.
bigkernel 0x26b820 = vectorized exp2 (log2e/floor/mantissa tables). Fixed the
broken warp line in framed_model.cpp (compiles again).
This commit is contained in:
2026-08-20 15:00:53 +03:00
parent fc48a9fee4
commit f23bbfa1f6
5 changed files with 2982 additions and 3 deletions
+9 -3
View File
@@ -17,9 +17,9 @@ constexpr double MASK_N = 0.25966;
constexpr float SENS_SCALE = 2.054f; constexpr float SENS_SCALE = 2.054f;
constexpr int RT_WEIGHTS_N = 2049; // captured attack/release tables size constexpr int RT_WEIGHTS_N = 2049; // captured attack/release tables size
double mask_lut(double acc) { double mask_lut(double acc, double K, double n) {
if (acc <= 0.0) return 1.0; if (acc <= 0.0) return 1.0;
return std::pow(1.0 / (1.0 + MASK_K * acc), MASK_N); return std::pow(1.0 / (1.0 + K * acc), n);
} }
} // namespace } // namespace
@@ -108,7 +108,13 @@ void FramedDetector::processFrame(const std::complex<double>* spectrum, float* m
track_[b][k] = static_cast<float>(track); track_[b][k] = static_cast<float>(track);
// Accumulator (FUN_180529fe0 step 5: 0x5407c8 = diff; += level). // Accumulator (FUN_180529fe0 step 5: 0x5407c8 = diff; += level).
double acc = diff + level; double acc = diff + level;
double g = mask_lut(acc); // LUT fitted against live mask band0 (0x540678), which ALREADY
// includes the step-6 warp tilt (0x5406a8) — so no extra warp.
// Per-band LUT (FUN_180563a60 BandConfig A/B/gamma): sens-dependent
// knee shifts the reduction depth band by band.
double K = bands_[b].lut_k, n = bands_[b].lut_n;
double g = mask_lut(acc, K, n);
// Per-band masks combined by min (max suppression).
if (g < gain) gain = g; if (g < gain) gain = g;
} }
mask[k] = static_cast<float>(gain); mask[k] = static_cast<float>(gain);
+7
View File
@@ -8,6 +8,13 @@ struct DetectorBand {
float q; // resonance Q float q; // resonance Q
float sens; // XML sens (dB); internal sens_stored = sens * 2.054 float sens; // XML sens (dB); internal sens_stored = sens * 2.054
float level_scale = 1.0f; // calibration: level = am * res * level_scale float level_scale = 1.0f; // calibration: level = am * res * level_scale
// Per-band mask LUT: gain = (1/(1+K*acc))^n (live-fit defaults band0).
float lut_k = 9.8026f;
float lut_n = 0.25966f;
// Dry/wet depth (XML "depth", 0.864 in reference renders). Applied only when
// set >= 0; default -1 keeps the live LUT fit intact (fit already absorbed
// band0's dry/wet blend).
float depth = -1.0f;
}; };
// FramedDetector — C++ port of the real soothe mask chain (FUN_180529fe0). // FramedDetector — C++ port of the real soothe mask chain (FUN_180529fe0).
File diff suppressed because it is too large Load Diff
+14
View File
@@ -0,0 +1,14 @@
// rt_mask_tables.hpp — runtime mask-apply tables captured from live snapshot
// (snap_rt.bin, ctx 0x2370040, SR=48000/N=4096). Bit-exact mask chain (FUN_180529fe0).
// IIR stage: y = A[i]*acc + B[i]*x (first-order leaky, B = 1 - A).
#pragma once
extern const double kIIR_A1[];
extern const double kIIR_B1[];
extern const double kIIR_A2[];
extern const double kIIR_B2[];
extern const double kIIR_A3[];
extern const double kIIR_B3[];
extern const float kWarp[];
extern const float kBand768[];
extern const float kPRNGLut[];
+34
View File
@@ -816,3 +816,37 @@ Replaced empirical PCHIP detector with the live-calibrated mask chain:
- warp tilt (0x5406a8) + per-band 0x540768 mult + FFT-conv smoothing (step 6-8 decomp) - warp tilt (0x5406a8) + per-band 0x540768 mult + FFT-conv smoothing (step 6-8 decomp)
- exact BandConfig (A/B/gamma) for band LUT 0x563a60 - exact BandConfig (A/B/gamma) for band LUT 0x563a60
- rt_weights tables only cover bins 0..1024 (2049 len, rest zero); extend if higher bins matter - rt_weights tables only cover bins 0..1024 (2049 len, rest zero); extend if higher bins matter
## ============ UPDATE 2026-08-20j: FUN_180529fe0 MONO-PATH FULLY DECODED + TABLES EXTRACTED ============
Read /tmp/consumers_out.txt:471-1277 (full decomp) + f529fe0.dis + live snap_rt.bin (ctx 0x2370040).
### Exact per-band mono-path (0x5408b8==0), FUN_180529fe0:
1. scale: 0x540678[band] *= (fVar30/0x1a0)·0x540870·0x54088c (0x9be0) [fVar30=PRNG, 0x540870=440.95]
2. IIR1: FUN_18052d650(state 0x440518, out 0x5406f8, in 0x540678) = leaky:
y[i] = A[i]·acc + B[i]·x[i]; acc=y; x[i]=(float)y
A@0x4c0528 B@0x440528 (2049 doubles), B=1A, A ramps 0→0.692 (fast attack at low bins)
3. copy: 0x5406f8 <- 0x540678[band] (0x5160) — actually the IIR1 in/out feed; then
4. IIR2: inline on 0x540678[band]: A@0x2c04f8 B@0x2404f8 (A ramps 0→0.086, SLOW release)
5. mirror halves (0x11940)
6. blend: 0x5406f8 = 0x540698·(1mix) + mix·0.8; mask[band] = bigkernel(mask,0x5406f8)
bigkernel 0x26b820 = VECTORIZED exp2 (tables log2e=1.4424@0x1f31740, floor 708.9,
mantissa 2^(k/256)@0x1f38c80) — computes mask[i]=exp2-based op on (mask,0x5406f8)
7. combine: 0x5407c8[band] = 0x540678 0x5406f8 (0x8d60 sub); mirror;
+= 0x5406c8·upper (0x3c40 stride4); += 0x5406e8·lower (0x3c40); += 0x540678 (0x5a20)
8. WARP: 0x540678 *= 0x540768[band] (0x8700); *= 0x5406a8 (0x8700) [TWO warp mults]
9. IIR3: inline on 0x540678[band] TWICE: A@0x3c0510 B@0x340510 (=A2/B2 shape)
10. dry/wet: 0x540678 = mask·(fVar30·0x540888) + (1fVar30); fVar30=0x540874rnd
11. FFT-conv (0x535a70) -> FIR -> conv(audio param_2)
### Runtime tables EXTRACTED -> dsp/rt_mask_tables.{hpp,cpp} (2049 doubles each, live):
- kIIR_A1 (0x4c0528): 0→0.692 rising; kIIR_B1 (0x440528) = 1A1
- kIIR_A2/B2 (0x2c04f8/0x2404f8): A 0→0.086 (slow); kIIR_A3/B3 (0x3c0510/0x340510) = same
- kWarp (0x5406a8): 0→3.899 (freqpath tilt, 8193 f32)
- kBand768 (0x540768[band0]): 2.017→0.271 (per-band warp mult, 2049 f32)
- kPRNGLut (0x5408b0 -> 0x152a3d0): 512 f32 (0.35..6.66, 189 nz)
- PRNG state 0x2404e0 = 112; DAT_18262b5c8=0.4552, b704=0.6089, b700=0.6070 (int32->float)
- scalars: 0x540870=440.95, 0x540874=1.0, 0x54087c=1.0, 0x540888=1.0, 0x54088c=1.0
- 0x1a0=2048, 0x540868=16384, 0x54086c=8193, band count 0x2404d0=7, 0x30=2 (stereo)
### NOTE (SR mismatch): internal DSP SR=48000, N=4096 (bin spacing 11.713 Hz). Host refs 44100.
IIR tables indexed 0..2048 (N/2+1). For bit-exact the detector must run N=4096@48k internally.