Files
soothe2-re/dsp/framed_model.hpp
T
Matiq f23bbfa1f6 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).
2026-08-20 15:00:53 +03:00

48 lines
1.9 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
// 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).
// Per band, per bin:
// level_k = am_k * res_k (twin resonance x smoothed amplitude)
// track += w_k * (level - track) (per-bin level tracker, attack/release
// weights w from live capture rt_weights)
// acc_k = 2*level_k - track_k (accumulator, live peak ~10.08 at tone)
// mask_k = LUT(acc_k) (fitted mask curve from live capture)
// final mask = min over bands (max suppression), like soothe's band combine.
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> warp_; // per-bin warp tilt
std::vector<float> am_; // smoothed per-bin amplitude
std::vector<std::vector<float>> track_; // per band, per bin level tracker
};