24m-2: RT_VLAW=1 two-stage detector law implemented (formula verified in-code g=0.319@43); end-to-end gap traced to STFT application layer (WOLA mainlobe smearing vs narrow dip); stale-build hazard reconfirmed

This commit is contained in:
2026-08-24 20:04:28 +03:00
parent fe01ef5bac
commit b00a8a667e
2 changed files with 53 additions and 1 deletions
+24 -1
View File
@@ -141,6 +141,27 @@ static void process_band_structural(
raw_level[k] = static_cast<float>(static_cast<double>(am[k]) / res_k * scale_factor_x); raw_level[k] = static_cast<float>(static_cast<double>(am[k]) / res_k * scale_factor_x);
} }
// RT_VLAW=1 (NOTES 24m): decoded two-stage detector law.
// cutS(b) = 1.7436*ln(1 + lvl_raw/0.3824) [stage-S, center form]
// applied gain = 10^(-gamma0*cutS/20), gamma0 = 1.79
// 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<double>(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<float>(g);
} else {
band_level[k] = static_cast<float>(lvl);
}
}
if (!vlaw)
for (size_t k = 0; k < nbin; k++) { for (size_t k = 0; k < nbin; k++) {
double res_k = std::max(static_cast<double>(res[k]), 1e-12); double res_k = std::max(static_cast<double>(res[k]), 1e-12);
double lvl = raw_level[k]; double lvl = raw_level[k];
@@ -232,7 +253,9 @@ static void process_band_structural(
// mask = raw^0.984 × hann × 0x540888 // mask = raw^0.984 × hann × 0x540888
// where hann rises from 0→1 (DC→Nyquist) // where hann rises from 0→1 (DC→Nyquist)
static const int firpower = getenv("RT_FIRPOWER") ? atoi(getenv("RT_FIRPOWER")) : 0; static const int firpower = getenv("RT_FIRPOWER") ? atoi(getenv("RT_FIRPOWER")) : 0;
if (firpower) { if (vlaw) {
mm = static_cast<double>(band_level[k]);
} else if (firpower) {
double raw = static_cast<double>(raw_level[k]); double raw = static_cast<double>(raw_level[k]);
if (raw > 1e-12) { if (raw > 1e-12) {
mm = std::pow(raw, 0.984); mm = std::pow(raw, 0.984);
+29
View File
@@ -3058,3 +3058,32 @@ drive 0..30 дБ → s43: 1.143, 1.021, 0.903, 0.791, 0.685
Датасет: /tmp/opencode/scratch_family.pkl (18 кривых) + tract_*. Датасет: /tmp/opencode/scratch_family.pkl (18 кривых) + tract_*.
Инструмент-обновление: rendersnap2 v4 пишет полный набор слотов включая Инструмент-обновление: rendersnap2 v4 пишет полный набор слотов включая
scratch — канал прямого наблюдения кривой детектора БЕЗ инверсии. scratch — канал прямого наблюдения кривой детектора БЕЗ инверсии.
## ============ ДОПОЛНЕНИЕ 24m-2: RT_VLAW=1 внедрён; формула в коде верна; end-to-end разрыв = слой применения ============
### Реализация (framed_model.cpp, env RT_VLAW=1)
Ветка заменяет LUT/exp2/blend: `band_level = 10^(−γ₀·cutS/20)`,
`cutS = 1.7436·ln1p(lvl_raw/0.3824)` (центр-форма глобально), γ₀=1.79.
Проверено stderr-принтом (RT_VDBG): k=43 lvl=8.815→g=0.3189 ✓ формула в коде
даёт точные значения стадии-D. Маска идёт напрямую (exp2/warp/IIR3 отключаемы
RT_NOWARP/RT_NOIIR3).
### Статус end-to-end (dual_b1q_0.5):
```
REF: cut@500=10.32 cut@2000=11.82
VLAW: cut@500= 7.56 cut@2000= 6.41 (+NOWARP+NOIIR3: 5.36 / 1.73)
```
Формула кривой верна (маска@43=0.319 ≈ плагинная B@43=0.320!), но сквозной
результат недобирает ⇒ расхождение живёт В СЛОЕ ПРИМЕНЕНИЯ (STFT/WOLA):
эффективный gain на тоне = усреднение маски по главному лепестку окна;
узкий дип 5-6 бинов размывается. Исторически канон-константы были ПОДГОНЯНЫ
сквозь этот слой (смещение впитано), поэтому старые группы корпуса сходились.
Глубокая симуляция WOLA-нормировок не завершена (следующий раунд): кандидат —
плагин нормирует окно/хоп иначе (cfg {16384,8192} движка?), либо анализ без
окна/с другим окном. Ключевой контрольный эксперимент: прогнать ОДИНАКОВУЮ
кривую через наш слой и измерить эффективную глубину на тоне против плагина.
### Гигиена
TOOLING HAZARD снова сработал (same-second build → stale бинарник дал ложные
5.36/1.73). Протокол touch+mtime-проверка ОБЯЗАТЕЛЕН перед каждым замером.
RT_VDBG stderr-принт оставлен (env-gated, нулевая цена).