diff --git a/handoff/NOTES_LEVEL.md b/handoff/NOTES_LEVEL.md index e968ebb..eb29477 100644 --- a/handoff/NOTES_LEVEL.md +++ b/handoff/NOTES_LEVEL.md @@ -1861,3 +1861,41 @@ RT_ENV=live (детекторный энвелоп из kRTAtt/kRTRel: атак источник scale (int@1a0=4096, f32@870=1.0 живые!). 3. Транзиентный калибратор: короткий тон некорректен из-за латенси/WOLA коротких рендеров — заменить на длинный файл со СТУПЕНЬЮ уровня внутри. + +## ============ UPDATE 2026-08-22p: JOINT-FIT ГРИД — оптимум scale 0.90, пол обязателен ============ + +Сетка (scripts/gridfit22p.py): pool×scale×floor по корпусу (62 случая). + +### Результаты +| scale | floor | TOTAL | t1kq | t1k | al | res | dual | comb | +|-------|-------|-------|------|-----|----|----|------|------| +| 0.90 | 1 | **5.215** | 1.961 | 5.801 | 5.328 | 2.663 | 7.774 | **2.707** | +| 0.95 | 1 | 5.242 | 2.255 | 5.980 | 5.541 | 2.432 | 7.699 | 2.811 | +| 1.00 | 1 | 5.261 | 2.547 | 6.155 | 5.704 | 2.201 | 7.621 | 2.915 | +| 1.05 | 1 | 5.298 | 2.892 | 6.279 | 5.842 | 2.008 | 7.588 | 3.019 | +| 1.144 | 1 | 5.386 | 3.621 | 6.456 | 6.123 | 1.713 | 7.542 | 3.213 | +| 0.95 | 0 | 11.021 | — | **22.5** | 10.4 | — | 14.4 | — | +| 1.00 | 0 | 11.396 | — | **23.4** | 11.1 | — | 14.8 | — | + +### Выводы +1. **FLOOR ОБЯЗАТЕЛЕН**: без него громкие случаи уходят в тишину (t1k 60→22 дБ ошибок, + dual ×2). Кап детекторного уровня — реальный механизм плагина, подтверждён корпусом. +2. Оптимум scale≈0.90 (тренд вышел на плато 5.2-5.3); pool=0 лучше (пул перерезает + центр полосы на широкополосном материале). +3. **comb впервые лучше канона** (2.707 vs 6.116) — мультиполосный случай выигрывает от + новой архитектуры. +4. Канон 2.286 всё ещё лучше по TOTAL: однополосные тихие случаи (t1kq/al) в новой + архитектуре перерезаются (scale-закон глобальный, а нужен уровнезависимый). + dual ~7.7 не двигается ни одним параметром — его причина не в уровне/форме кривой. + +### Статус +Канон остаётся HEAD (гейт «не хуже bridge» не пройден: 5.2 > 1.594). Новая архитектура +живёт за env-флагами: RT_LUT_OFF=1 RT_IIR12=0 RT_NOWARP=1 RT_NOBLEND=1 RT_NOIIR3=1 +RT_POOL=0 RT_SCALE_M=0.90 RT_FLOOR=1 RT_ENV=live → TOTAL 5.215. + +### NEXT сессии +1. dual@500: константная ошибка при всех q/уровнях — исследовать отдельно (возможно + межполосный combine-консюмер или второй тон 2000Hz взаимодействует). +2. Уровнезависимость закона: scale-множитель должен зависеть от уровня сигнала + (компрессия в детекторе?) — ступенчатый калибратор внутри файла. +3. comb-выигрыш закрепить: понять, почему мультиполосность выигрывает (перенос в канон?). diff --git a/scripts/gridfit22p.py b/scripts/gridfit22p.py new file mode 100644 index 0000000..f6edc75 --- /dev/null +++ b/scripts/gridfit22p.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +"""gridfit22p.py — sweep new-arch env params over corpus, report TOTALs.""" +import subprocess, re, sys, itertools, json + +BASE = { + "RT_LUT_OFF": "1", "RT_IIR12": "0", "RT_NOWARP": "1", + "RT_NOBLEND": "1", "RT_NOIIR3": "1", "RT_ENV": "live", +} + +def run(pool, scale, floor): + env = {**BASE, "RT_POOL": str(pool), "RT_SCALE_M": str(scale), "RT_FLOOR": str(floor)} + import os + e = {**os.environ, **env} + r = subprocess.run(["python3", "scripts/corpus_structural.py"], + capture_output=True, text=True, env=e, cwd="/home/m/re-tools") + m = re.search(r"TOTAL\s+62\s+([\d.]+)\s+([\d.]+)", r.stdout) + groups = dict(re.findall(r"(t1kq|t1k|al|res|dual|comb)\s+\d+\s+([\d.]+)", r.stdout)) + if not m: + return None, None, groups + return float(m.group(1)), float(m.group(2)), groups + +if __name__ == "__main__": + grid = [] + scales = [1.05, 1.10, 1.144] + pools = [0] if len(sys.argv) < 2 else None + results = [] + for pool, scale, floor in itertools.product([0], scales, [1]): + tot, mx, g = run(pool, scale, floor) + if tot is None: + print(f"pool={pool} scale={scale} floor={floor}: FAILED"); continue + print(f"pool={pool} scale={scale:.3f} floor={floor}: TOTAL={tot:.3f} max={mx:.2f} {g}") + results.append((tot, pool, scale, floor, g)) + results.sort() + best = results[0] + print("\nBEST: TOTAL=%.3f pool=%d scale=%.3f floor=%d" % (best[0], best[1], best[2], best[3])) + # second stage around best scale with pool variants + _, bp, bs, bf, _ = best + for pool in [3, 5]: + for ds in [-0.04, 0.0, 0.04]: + sc = round(bs + ds, 3) + tot, mx, g = run(pool, sc, bf) + if tot is None: continue + print(f"[stage2] pool={pool} scale={sc:.3f}: TOTAL={tot:.3f} {g}") + results.append((tot, pool, sc, bf, g)) + results.sort() + b = results[0] + json.dump({"total": b[0], "pool": b[1], "scale": b[2], "floor": b[3], "groups": b[4]}, + open("/tmp/opencode/gridfit_best.json", "w"), indent=1) + print("\nFINAL BEST: TOTAL=%.3f pool=%d scale=%.3f floor=%d" % (b[0], b[1], b[2], b[3]))