From 803c10009180661f8ada92fe8cfa84bf0918c344 Mon Sep 17 00:00:00 2001 From: Matiq Date: Sat, 29 Aug 2026 10:36:41 +0300 Subject: [PATCH] k-mapping opt-in RT_KMAP, keep canon 0.732 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - k(sens,q) fitted from 24x table: sens 6->0.44 12->1.0 24->22, q 0.5->1.0 2.0->0.403 - default off (RT_KMAP=0), opt-in for campaign; does not affect canon TOTAL 0.732 - next: campaign sens/q series for precise fit, Δ STATE-dependent --- dsp/framed_model.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/dsp/framed_model.cpp b/dsp/framed_model.cpp index 5db1747..c40cf32 100644 --- a/dsp/framed_model.cpp +++ b/dsp/framed_model.cpp @@ -115,6 +115,39 @@ static void process_band_structural( double res_k = std::max(static_cast(res[k]), 1e-12); lvl_in[k] = static_cast(static_cast(am[k]) / res_k * scale_factor_x); } + // k-mapping per NOTES 24x/24dd/24ee: lvl_impl = lvl_ours / k(sens,q,fc) + // k = k_sens(sens) * k_q(q) * k_fc(fc) ; default OFF (canon), opt-in RT_KMAP=1 + // Fitted from table 24x: k_sens 6→0.44, 12→1.0, 18→5.37, 24→22.0 ; k_q 0.5→1.0, 2.0→0.403 + static const int kmap_on = []{ const char* e=getenv("RT_KMAP"); return e ? atoi(e) : 0; }(); + if (kmap_on) { + double k_sens; + if (band.sens < 12) { + // 6→0.44, 12→1.0 linear + k_sens = 0.44 + (band.sens - 6.0) * (0.56 / 6.0); + } else if (band.sens == 12) { + k_sens = 1.0; + } else if (band.sens < 24) { + // 12→1.0, 24→22.0 exponential + k_sens = std::exp((band.sens - 12.0) * std::log(22.0) / 12.0); + } else { + k_sens = 22.0; + } + double k_q; + if (band.q >= 2.0) k_q = 0.403; + else if (band.q <= 0.5) k_q = 1.0; + else { + // interpolate log q 0.5→2.0 : 1.0→0.403 + double t = (std::log(band.q) - std::log(0.5)) / (std::log(2.0) - std::log(0.5)); + k_q = 1.0 + t * (0.403 - 1.0); + } + double k_fc = 1.0; + // fc 500→1.0, 1000→~1.4 per 24w-2 (1.15@500 vs 1.62@1000) -> k_fc 1.0→0.85? + // Keep 1.0 for now; fc effect is weak vs sens/q. + double k_tot = k_sens * k_q * k_fc; + if (k_tot > 1e-9) { + for (size_t k = 0; k < nbin; k++) lvl_in[k] = static_cast(lvl_in[k] / k_tot); + } + } if (pool_w > 0 && !lut_off == false) {} if (pool_w > 0) { std::vector pooled(nbin);