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:
+24
-1
@@ -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);
|
||||||
|
|||||||
@@ -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, нулевая цена).
|
||||||
|
|||||||
Reference in New Issue
Block a user