Files
soothe2-re/dsp/framed_model.hpp
T
Matiq d4a0a68584 P4: transcribe exact FUN_180529fe0 mask chain (structural, not yet calibrated)
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.
2026-08-20 15:10:29 +03:00

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
};