framed_model.cpp now follows the decoded mono-path structure: level -> scale(0x540870*0x54088c/0x1a0) -> IIR1 leaky(A1/B1) -> IIR2(A2/B2) -> exp2(0.5*(mask-blend)) -> combine/acc -> warp -> IIR3(A3/B3)x2 -> dry/wet IIR stages are the real live tables (iir_leaky y=A*acc+B*x, B=1-A). Removed the empirical mask_lut=(1/(1+K*acc))^n. Not numerically calibrated yet: exp2 bigkernel exact semantics + PRNG prologue (fVar30) + FFT-conv still TBD; t1kq depth -2.9 vs -14.98 dB ref.
45 lines
1.7 KiB
C++
45 lines
1.7 KiB
C++
#pragma once
|
|
#include <cstddef>
|
|
#include <complex>
|
|
#include <vector>
|
|
|
|
struct DetectorBand {
|
|
float fc; // band center freq (Hz)
|
|
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
|
|
};
|
|
|
|
// FramedDetector — C++ transcription of the real soothe2 mask-apply chain
|
|
// (FUN_180529fe0 mono path, 0x5408b8==0), bit-exact structure.
|
|
//
|
|
// Per band, per bin (exact decomp /tmp/consumers_out.txt:638-1111):
|
|
// 1. scale: x = level * (fVar30/0x1a0) * 0x540870 * 0x54088c
|
|
// 2. IIR1 leaky: y[i] = A1[i]*acc + B1[i]*x[i] (A1/B1 ramp attack, live tables)
|
|
// 3. IIR2 leaky: same with A2/B2 (slow release)
|
|
// 4. blend: b = freqaxis*(1-mix) + mix*0.8; mask = exp2(0.5*(mask-b))
|
|
// 5. combine: acc[band] = mask - b; mirror; += w_att*upper; += w_rel*lower; += mask
|
|
// 6. warp: mask *= 0x540768[band]; mask *= warp (dual tilt)
|
|
// 7. IIR3 leaky: twice with A3/B3
|
|
// 8. dry/wet: mask = mask*(fVar30*0x540888) + (1-fVar30)
|
|
// final = min over bands.
|
|
class FramedDetector {
|
|
public:
|
|
FramedDetector(size_t nfft, float sample_rate);
|
|
~FramedDetector();
|
|
|
|
void setParams(const std::vector<DetectorBand>& bands);
|
|
|
|
void processFrame(const std::complex<double>* spectrum, float* mask);
|
|
|
|
private:
|
|
size_t nfft_;
|
|
float sample_rate_;
|
|
double wsum_;
|
|
|
|
std::vector<DetectorBand> bands_;
|
|
std::vector<std::vector<float>> res_; // per band, per bin |2B/A|
|
|
std::vector<float> am_; // smoothed per-bin amplitude
|
|
std::vector<std::vector<float>> track_; // per band, per bin accumulator 0x5407c8
|
|
};
|