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:
@@ -17,9 +17,9 @@ constexpr double MASK_N = 0.25966;
|
||||
constexpr float SENS_SCALE = 2.054f;
|
||||
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;
|
||||
return std::pow(1.0 / (1.0 + MASK_K * acc), MASK_N);
|
||||
return std::pow(1.0 / (1.0 + K * acc), n);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -108,7 +108,13 @@ void FramedDetector::processFrame(const std::complex<double>* spectrum, float* m
|
||||
track_[b][k] = static_cast<float>(track);
|
||||
// Accumulator (FUN_180529fe0 step 5: 0x5407c8 = 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;
|
||||
}
|
||||
mask[k] = static_cast<float>(gain);
|
||||
|
||||
@@ -8,6 +8,13 @@ struct DetectorBand {
|
||||
float q; // resonance Q
|
||||
float sens; // XML sens (dB); internal sens_stored = sens * 2.054
|
||||
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).
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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[];
|
||||
@@ -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)
|
||||
- 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
|
||||
|
||||
## ============ 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=1−A, 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·(1−mix) + 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) + (1−fVar30); fVar30=0x540874−rnd
|
||||
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) = 1−A1
|
||||
- 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.
|
||||
|
||||
Reference in New Issue
Block a user