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[];
|
||||
Reference in New Issue
Block a user