From 31cc5540e14d043244c63b9657a5780d429d21e5 Mon Sep 17 00:00:00 2001 From: Matiq Date: Mon, 24 Aug 2026 20:33:40 +0300 Subject: [PATCH] =?UTF-8?q?24n-2:=20Delta-branch=20implemented=20(peak+nei?= =?UTF-8?q?ghbourhood,=20two-pass);=20dual=20end-to-end=209.32/11.58=20vs?= =?UTF-8?q?=20ref=2010.32/11.82;=20VLAW=20corpus:=20dual=200.708=20(was=20?= =?UTF-8?q?3.264)=20but=20single-band=20groups=20regress=20=E2=80=94=20con?= =?UTF-8?q?stants=20are=20dual-family-specific=20(q/fc=20dependence=20open?= =?UTF-8?q?);=20canon=20default=20verified=202.286?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dsp/framed_model.cpp | 42 +++++++++++++++++++++++++++--------------- handoff/NOTES_LEVEL.md | 31 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/dsp/framed_model.cpp b/dsp/framed_model.cpp index 88978fe..edc4fd9 100644 --- a/dsp/framed_model.cpp +++ b/dsp/framed_model.cpp @@ -142,26 +142,38 @@ static void process_band_structural( } // RT_VLAW=1 (NOTES 24m): decoded two-stage detector law. - // cutS(b) = 1.7436*ln(1 + lvl_raw/0.3824) [stage-S, center form] + // cutS(b) = 1.729*ln(1 + lvl_raw/0.3824) + Delta(b) [stage-S] // applied gain = 10^(-gamma0*cutS/20), gamma0 = 1.79 + // Delta-branch: neighbourhoods of off-center content peaks get +4.18 dB. // Bypasses LUT/exp2/blend/warp/IIR3 entirely. static const int vlaw = getenv("RT_VLAW") ? atoi(getenv("RT_VLAW")) : 0; static int frame_dbg_ctr = 0; - for (size_t k = 0; k < nbin; k++) { - double res_k = std::max(static_cast(res[k]), 1e-12); - double lvl = raw_level[k]; - if (vlaw) { - double cutS = 1.7436 * std::log1p(lvl / 0.3824); - double g = std::pow(10.0, -1.79 * cutS / 20.0); - if (getenv("RT_VDBG") && (k == 43 || k == 171) && (frame_dbg_ctr < 2)) - fprintf(stderr, "[VLAW] k=%zu lvl=%.5f cutS=%.5f g=%.5f\n", - k, lvl, cutS, g); - band_level[k] = static_cast(g); - } else { - band_level[k] = static_cast(lvl); + if (vlaw) { + double kfc = static_cast(band.fc) / (sample_rate / 2.0) * (nbin - 1); + static thread_local std::vector delta_mark; + delta_mark.assign(nbin, 0.0f); + for (size_t k2 = 1; k2 + 1 < nbin; k2++) { + if (raw_level[k2] <= 0.25) continue; + if (std::fabs((double)k2 - kfc) <= 8.0) continue; + bool lmax = true; + for (int d = -5; d <= 5 && lmax; d++) { + int kk = (int)k2 + d; + if (kk < 0 || kk >= (int)nbin || d == 0) continue; + if (raw_level[kk] > raw_level[k2]) lmax = false; + } + if (!lmax) continue; + for (int d = -3; d <= 3; d++) { + int kk = (int)k2 + d; + if (kk >= 0 && kk < (int)nbin) delta_mark[kk] = 1.0f; + } } - } - if (!vlaw) + for (size_t k2 = 0; k2 < nbin; k2++) { + double cs = 1.729 * std::log1p(raw_level[k2] / 0.3824) + + (delta_mark[k2] ? 4.177 : 0.0); + band_level[k2] = static_cast(std::pow(10.0, -1.79 * cs / 20.0)); + } + frame_dbg_ctr++; + } else for (size_t k = 0; k < nbin; k++) { double res_k = std::max(static_cast(res[k]), 1e-12); double lvl = raw_level[k]; diff --git a/handoff/NOTES_LEVEL.md b/handoff/NOTES_LEVEL.md index 3d667a1..6a7e233 100644 --- a/handoff/NOTES_LEVEL.md +++ b/handoff/NOTES_LEVEL.md @@ -3119,3 +3119,34 @@ cut@2000=4.14 (реф 11.82 — Δ-ветка ещё не реализована калибровка α/γ₀. Следующие шаги: (а) реализовать Δ-ветку (правило второго пика); (б) разобрать слой применения до сходимости; (в) источник γ₀/стадий в декомпе; (г) корпус с полным флаг-набором. + +## ============ ДОПОЛНЕНИЕ 24n-2: Δ-ветка в коде; dual 0.708 (было 3.264); константы НЕ универсальны ============ + +### Реализовано (framed_model.cpp, vlaw-ветка v2) +Δ-правило: локальные максимумы lvl_raw>0.25 вне ±8 бинов от fc помечают +окрестность ±3 бина → +4.177 дБ. Двухпроходно (без O(n²)). +dual_b1q_0.5 end-to-end: **9.32 / 11.58** vs реф 10.32 / 11.82 +(скирт −0.24 дБ!, центр −1.0). + +### Корпус с флагами (62 случая): +| group | canon | VLAW | +|-------|-------|------| +| t1kq | 0.768 | 3.633 | +| t1k | 2.114 | 3.296 | +| al | 0.986 | 2.620 | +| res | 0.437 | 3.896 | +| **dual** | 3.264 | **0.708** | +| comb | 6.116 | 4.014 | +| TOTAL | 2.286 | 2.515 | + +### Диагноз регресса одноканальных групп +t1kq-диагностика (тон@1000, fc∈{500,1000,2000}): +- fc=500 (тон вне центра): реф 5.45, VLAW 10.37 ⇒ Δ НЕ должен применяться к + этому случаю (реф = shallow-уровень!); при q≈1 и отступе 500 Гц офсета нет, + а в dual (q=0.5, отступ 1500 Гц) был +4.18 ⇒ правило Δ зависит от q/дистанции. +- fc=1000 (тон в центре): реф 8.70 vs dual-центр 10.32 при близком lvl ⇒ + глубина зависит от q/fc — константы α_eff/γ₀_dual не универсальны. +Вывод: закон верен В СЕМЕЙСТВЕ калибровки (dual_b1q_0.5: q=0.5, sens=12). +Параметризация (α, γ₀, Δ-правило) по (q, fc, sens) — следующая большая задача; +методика (rendersnap2+зонды+рампа) готова, датасеты расширяются механически. +Канон не тронут: default-корпус воспроизведён (TOTAL 2.286 ✓).