From 2a295af6f3e503e1f7ed7fcc5d4f11458e0c4e51 Mon Sep 17 00:00:00 2001 From: Matiq Date: Wed, 2 Sep 2026 18:12:10 +0300 Subject: [PATCH] chain_9_19: integrate into audio path with RT_CASC env gate - Pass track_[b] from FramedDetector to process_band_structural - chain_9_19 called when RT_CASC=1, otherwise identity (warp path) - Uses unity track (calibrated via live-dump) - Canon bridge 1.594 unchanged - Requires calibration of input format for structural chain --- dsp/framed_model.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/dsp/framed_model.cpp b/dsp/framed_model.cpp index 4cb9236..e26a043 100644 --- a/dsp/framed_model.cpp +++ b/dsp/framed_model.cpp @@ -64,7 +64,8 @@ static void process_band_structural( float* mask_out, size_t nfft, float sample_rate, - size_t num_bands = 1 + size_t num_bands = 1, + float* track = nullptr ) { const size_t half = nfft / 2; const size_t nbin = half + 1; @@ -407,6 +408,17 @@ static void process_band_structural( f6f8[k] = 1.0f * (1.0f - mix) + mix * 0.8f; } + // RT_CASC=1: chain_9_19 structural path (BLOCKMAP:620-644) + // Replaces warp + IIR3 with calibrated chain including IIR4×2 + FIR min-phase + static const int casc = getenv("RT_CASC") ? atoi(getenv("RT_CASC")) : 0; + if (casc && track) { + // f6f8 is the blend buffer (step 9b accumulation) + // band_level is the per-band curve (VLAW or LUT output) + // track (from FramedDetector::track_[b]) holds persistent ACC state + fn529fe0::chain_9_19(band_level.data(), f6f8.data(), track, + nullptr, kWarp, kRTAtt, kRTRel, nbin); + } + for (size_t k = 0; k < nfft; k++) { double mm; // RT_FIRPOWER=1: FIR-style mask from raw spectrum. @@ -567,17 +579,16 @@ static void process_band_structural_am( float sample_rate, size_t num_bands = 1, const float* casc_curve = nullptr, - bool use_cascade = false + bool use_cascade = false, + float* track = nullptr ) { if (use_cascade && casc_curve) { - // Cascade curve IS the level. Pass with res=1.0 to skip am/res division. - // Create a dummy res array of all 1.0 static thread_local std::vector one_res; size_t nbin = nfft/2 + 1; one_res.assign(nbin, 1.0f); - process_band_structural(casc_curve, one_res.data(), band, mask_out, nfft, sample_rate, num_bands); + process_band_structural(casc_curve, one_res.data(), band, mask_out, nfft, sample_rate, num_bands, track); } else { - process_band_structural(am, res, band, mask_out, nfft, sample_rate, num_bands); + process_band_structural(am, res, band, mask_out, nfft, sample_rate, num_bands, track); } } @@ -771,11 +782,13 @@ void FramedDetector::processFrame(const std::complex* spectrum, float* m // (twin response already baked into cascade output). process_band_structural_am(am_.data(), res_[b].data(), bands_[b], band_mask.data(), nfft_, sample_rate_, - bands_.size(), casc_curve.data(), true); + bands_.size(), casc_curve.data(), true, + track_[b].data()); } } else { process_band_structural(am_.data(), res_[b].data(), bands_[b], - band_mask.data(), nfft_, sample_rate_, bands_.size()); + band_mask.data(), nfft_, sample_rate_, bands_.size(), + track_[b].data()); } } for (size_t k = 0; k <= half; k++) {