docs: sync BITEXACT_PLAN/roadmap/AGENTS to 2026-08-21 state
BITEXACT_PLAN: structural column in S0 table; Step 2 re-scoped (combine thunk semantics, acc has no single-band consumer; FUN_1805316e0 is a coefficient writer NOT a mask combiner — fixed in Steps 2/8); Step 4 FFT-conv downgraded to P3 (window near-flat); Step 6 pipeline done (render48k); entry point = saturation hunt then Step 7 capture. roadmap: status 2026-08-21, P4 row + ~80% estimate with dual-canon results. AGENTS: two-canon model description, render48k/corpus_structural commands, stale-binary sweep hazard warning, updated gaps list.
This commit is contained in:
@@ -4,10 +4,11 @@ Bit-exact реверс DSP-ядра oeksound soothe2 (VST3) → транскри
|
|||||||
Полное журналирование — в `handoff/NOTES_LEVEL.md`, `handoff/NOTES_TWIN.md`,
|
Полное журналирование — в `handoff/NOTES_LEVEL.md`, `handoff/NOTES_TWIN.md`,
|
||||||
`handoff/NOTES_CAPTURE.md`, `roadmap.md`.
|
`handoff/NOTES_CAPTURE.md`, `roadmap.md`.
|
||||||
|
|
||||||
> **Текущая фаза: bit-exact НЕ достигнут** — мы на dB-параллели (полный корпус mean 1.594
|
> **Текущая фаза: bit-exact НЕ достигнут** — dB-параллель двумя канонами: bridge
|
||||||
> dB, comb 10 dB). Путь к байтам — в `BITEXACT_PLAN.md` (8 шагов, порядок и критерии).
|
> (корпус mean 1.594 dB, comb 10.1) и структурная цепь FUN_180529fe0 на 48k/4096
|
||||||
> ЭТОТ ФАЙЛ ЧИТАЙ ПЕРВЫМ. Bridge-модель — запасной канон; структурная цепочка
|
> (comb **6.12** — уже лучше bridge; однополосные хуже; разрыв = насыщение кривой
|
||||||
> FUN_180529fe0 (Шаг 1-2 плана) — целевая.
|
> редукции). Путь к байтам — в `BITEXACT_PLAN.md` (8 шагов, пере-скоуп Шага 2).
|
||||||
|
> ЭТОТ ФАЙЛ ЧИТАЙ ПЕРВЫМ. Bridge — запасной канон; структурная цепочка — целевая.
|
||||||
|
|
||||||
## Золотое правило (обязательно)
|
## Золотое правило (обязательно)
|
||||||
1. **Цель — bit-exact реверс кода**, НЕ эмпирическая подгонка кривых. Каждый параметр
|
1. **Цель — bit-exact реверс кода**, НЕ эмпирическая подгонка кривых. Каждый параметр
|
||||||
@@ -20,20 +21,32 @@ Bit-exact реверс DSP-ядра oeksound soothe2 (VST3) → транскри
|
|||||||
|
|
||||||
## Сборка и тесты (канон)
|
## Сборка и тесты (канон)
|
||||||
```bash
|
```bash
|
||||||
# собрать библиотеку + framed_test
|
# собрать библиотеку + framed_test (bridge, 44.1k) + render48k (структурная цепь, 48k/4096)
|
||||||
cmake -S dsp -B dsp/build
|
cmake -S dsp -B dsp/build
|
||||||
cmake --build dsp/build --target framed_test
|
cmake --build dsp/build --target framed_test render48k
|
||||||
|
|
||||||
# рендер через каркас (N=2048, hop=512, SR 44100, sqrt-Hann OLA)
|
# bridge-рендер (N=2048, hop=512, SR 44100, sqrt-Hann OLA)
|
||||||
# формат полосы: fc,q,sens,level_scale (одна полоса в comma-форме)
|
# формат полосы: fc,q,sens,level_scale (одна полоса в comma-форме)
|
||||||
./dsp/build/framed_test /home/m/soothe-bt/tone1kq.wav /tmp/o.wav 678.7611083984375,0.99999785,12,600
|
./dsp/build/framed_test /home/m/soothe-bt/tone1kq.wav /tmp/o.wav 678.7611083984375,0.99999785,12,600
|
||||||
# многополосный: через отдельные аргументы fc q sens scale (см. framed_test.cpp)
|
# многополосный: через отдельные аргументы fc q sens scale (см. framed_test.cpp)
|
||||||
|
|
||||||
|
# структурный рендер (внутренняя сетка 48000/4096: resample -> FUN_180529fe0 chain -> resample)
|
||||||
|
./dsp/build/render48k /home/m/soothe-bt/tone1kq.wav /tmp/o48.wav 1000,0.99999785,12
|
||||||
|
|
||||||
|
# корпусные прогонки (62 случая, честная 24-bit метрика)
|
||||||
|
python3 scripts/corpus.py # bridge + guard --compare
|
||||||
|
python3 scripts/corpus_structural.py # структурная цепь
|
||||||
|
python3 scripts/corpus_structural.py --vs-bridge scripts/baseline_bridge.json
|
||||||
|
|
||||||
# отдельные модули (bit-exact черные проверки)
|
# отдельные модули (bit-exact черные проверки)
|
||||||
cmake --build dsp/build --target twin_check tables_check fftconv_check vlog_check leveltrack_check levelpath_check
|
cmake --build dsp/build --target twin_check tables_check fftconv_check vlog_check leveltrack_check levelpath_check fn529fe0_check exp2_check
|
||||||
./dsp/build/twin_check # float-parity twin-резонатора
|
./dsp/build/twin_check # float-parity twin-резонатора
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **TOOLING HAZARD**: cmake пропускает пересборку при изменении исходника в ту же секунду —
|
||||||
|
> параметрические свипы молча гоняют STALE бинарь. Протокол: `touch` исходника перед сборкой +
|
||||||
|
> проверять свежесть mtime бинаря (пример: /tmp/sweep_fresh.py паттерн в NOTES_LEVEL:21a).
|
||||||
|
|
||||||
### Метрика (tone-cmp, Goertzel stead-state)
|
### Метрика (tone-cmp, Goertzel stead-state)
|
||||||
Сравнивать **тримкнутый** выход (длина = длина входа) с референсом `*_ref.wav` / `t1kq_b1f_*`:
|
Сравнивать **тримкнутый** выход (длина = длина входа) с референсом `*_ref.wav` / `t1kq_b1f_*`:
|
||||||
```python
|
```python
|
||||||
@@ -55,9 +68,11 @@ err = db(ta(out,1000)/ta(ref,1000)) # err в dB, цель <0.1
|
|||||||
Тестовый корпус (`/home/m/soothe-bt/`, вне git): `tone1kq.wav`(вход),
|
Тестовый корпус (`/home/m/soothe-bt/`, вне git): `tone1kq.wav`(вход),
|
||||||
`t1kq_b1f_<fc>.wav` (рефы), `comb.wav`/`comb_ref.wav` (мультиполосный).
|
`t1kq_b1f_<fc>.wav` (рефы), `comb.wav`/`comb_ref.wav` (мультиполосный).
|
||||||
|
|
||||||
## Текущее состояние (2026-08-20, P4)
|
## Текущее состояние (2026-08-21, P4)
|
||||||
|
|
||||||
**Реализованная модель в `dsp/framed_model.cpp`** — BRIDGE-канон (NOTES:147, honest):
|
**ДВА канона в `dsp/framed_model.cpp`:**
|
||||||
|
|
||||||
|
1. **BRIDGE** (эмпирическая погона, путь framed_test 44.1k, NOTES:147):
|
||||||
```
|
```
|
||||||
am_k: smoothed amp (2|X|/wsum, att~11ms/trel~80ms)
|
am_k: smoothed amp (2|X|/wsum, att~11ms/trel~80ms)
|
||||||
xv = log10(am_k / res_k) res_k = |2B/A| twin (min@band centre)
|
xv = log10(am_k / res_k) res_k = |2B/A| twin (min@band centre)
|
||||||
@@ -65,27 +80,43 @@ C = G·LUT(xv) + W·warp(f_k)^A G/W/A = 0.9963/0.3335/0.9807 (f
|
|||||||
gain_k = (1−C) · res_k^rp(Q) rp(Q) = 0.0275·Q^0.2159
|
gain_k = (1−C) · res_k^rp(Q) rp(Q) = 0.0275·Q^0.2159
|
||||||
LUT = monotone cubic (Fritsch–Carlson) через joint-fit узлы (al_* + B.11 anchors)
|
LUT = monotone cubic (Fritsch–Carlson) через joint-fit узлы (al_* + B.11 anchors)
|
||||||
```
|
```
|
||||||
|
2. **СТРУКТУРНАЯ цепь FUN_180529fe0** (`process_band_structural`, внутренняя сетка
|
||||||
|
48000/4096 через `dsp/build/render48k`, NOTES_LEVEL:820-840 + апдейты 20j–21c):
|
||||||
|
```
|
||||||
|
scale → LUT level-domain (t^γ·MULT, γ=0.344 decomp / MULT=4.2 placeholder)
|
||||||
|
→ IIR1 → IIR2 → mirror → blend(0.8)/exp2(−lvl) → combine(acc-update, без консюмера)
|
||||||
|
→ dual-warp(kBand768·kWarp·res^rp) → IIR3 bidirectional ×2 → dry/wet(identity)
|
||||||
|
```
|
||||||
- **METRIC CRITICAL**: рефы 24-bit НЕЛЬЗЯ читать 16-bit кодеком (даёт phantom −53 dB);
|
- **METRIC CRITICAL**: рефы 24-bit НЕЛЬЗЯ читать 16-bit кодеком (даёт phantom −53 dB);
|
||||||
`render_parity.load` (sw handling) + окно 3.5s — канон. dual honest ref = −10.2 dB FLAT.
|
`render_parity.load` (sw handling) + окно 3.5s — канон. dual honest ref = −10.2 dB FLAT.
|
||||||
- **Broadband-hypothesis ОПРОВЕРГНУТА** (NOTES:2026-08-20s): редукция per-bin (tone-бины
|
- **Broadband-hypothesis ОПРОВЕРГНУТА** (NOTES:2026-08-20s): редукция per-bin.
|
||||||
режутся, пустые bin ~1.0);
|
- **Честные результаты**: bridge корпус mean 1.594 (comb 10.15 сломан); структурная цепь:
|
||||||
- **Честные результаты (24-bit метрика, окно 3.5s, trimmed)**: dual (band fc=500,
|
comb **6.12** и res **0.44** — лучше bridge; t1kq 0.77 / t1k 2.11 / al 0.99 / dual 3.26 — хуже.
|
||||||
q-sweep) err ≤0.72; t1kq fc-scan (only1 800..1200) err ≤0.59; al_* lv3-12 err ≤0.43;
|
Полная таблица: BITEXACT_PLAN §0 / NOTES_LEVEL:21c.
|
||||||
полный корпус mean|err| 0.77, max 2.12 (t1k_b1f loud +2.1, al lv18/24 low-level −1.8).
|
- **ГЛАВНЫЙ ОТКРЫТЫЙ РАЗРЫВ**: насыщение кривой редукции — реальная упирается в C_max≈0.70,
|
||||||
- Эмпирика (G/W/A/rp/LUT-узлы) ЯВНО помечена в коде и NOTES; структурные лэкеры ниже.
|
exp2(−lvl) не ограничен (dual@500: константный −6.7 dB при всех q). Лечится Шагом 7
|
||||||
|
(live-захват A/B/γ) или статическим hunt'ом clamp'а в level-пути. Слепая подкрутка
|
||||||
|
γ/MULT исчерпана (свип 21c).
|
||||||
|
|
||||||
### Открытые bit-exact/структурные пробелы (см. NOTES_LEVEL.md)
|
### Открытые bit-exact/структурные пробелы (см. NOTES_LEVEL.md)
|
||||||
1. `combine/аккумулятор 0x5407c8` (аддитивные веса 0x5406c8/6e8) + `FFT-conv 0x535a70`
|
1. Насыщение кривой редукции (см. выше) — приоритет №1.
|
||||||
(сглаживание маски) — НЕ замкнуты в цепь; структурно могут закрыть t1k_b1f/al хвосты.
|
2. `combine/аккумулятор 0x5407c8`: семантика декодирована (21b), но acc/f6f8 НЕ имеют
|
||||||
2. BandConfig `ctx+0x188` A/B/γ (параметрический LUT 0x563a60) — не live-захвачен;
|
однополосного консюмера — искать точку потребления (межполосный каскад). ВНИМАНИЕ:
|
||||||
писатели = JUCE param plumbing (статически исчерпаны).
|
`FUN_1805316e0` = writer коэффициентов, НЕ комбинер масок.
|
||||||
3. PRNG-пролог (LCG+LUT → fVar30) — залочен (fVar30=1 при live state 112), dry/wet rnd импорт.
|
3. BandConfig `ctx+0x188` A/B/γ — противоречие между сессиями (−24/28/1 vs −13.78/68.29/0.344);
|
||||||
4. Бит-экзактный exp2 (0x26b820) вместо std::exp2; SR-mismatch 48000/4096 vs 44100/2048.
|
разрешить при захвате.
|
||||||
|
4. PRNG-пролог (LCG+LUT → fVar30) — залочен (fVar30=1 при live state 112), dry/wet rnd импорт.
|
||||||
|
5. Бит-экзактный exp2 (0x26b820); FFT-conv понижен до P3 (окно near-flat, NOTES:18c);
|
||||||
|
SR-геометрия 48k/4096 сделана (render48k).
|
||||||
|
|
||||||
## Структура ключевых файлов
|
## Структура ключевых файлов
|
||||||
- `dsp/framed_model.{cpp,hpp}` — C++ порт mask-apply цепи (ГЛАВНЫЙ активный файл).
|
- `dsp/framed_model.{cpp,hpp}` — C++ порт mask-apply цепи: bridge-канон + структурная
|
||||||
- `dsp/framed_test.cpp` — CLI рендер входа (3010 метрика см. выше).
|
`process_band_structural` (ГЛАВНЫЙ активный файл).
|
||||||
- `dsp/{twin,levelpath,freqpath,fftconv,vlog,leveltrack}.cpp` — расшифрованные модули.
|
- `dsp/render48k.cpp` — пайплайн внутренней сетки 48000/4096 (resample → структурная цепь → resample).
|
||||||
|
- `dsp/framed_test.cpp` — CLI bridge-рендер входа (метрика см. выше).
|
||||||
|
- `scripts/corpus.py` — корпусный харнесс bridge + guard `--compare baseline_bridge.json`.
|
||||||
|
- `scripts/corpus_structural.py` — тот же корпус через render48k + режим `--vs-bridge`.
|
||||||
|
- `dsp/{twin,levelpath,freqpath,fftconv,vlog,leveltrack,fn529fe0}.cpp` — расшифрованные модули.
|
||||||
- `dsp/rt_mask_tables.{hpp,cpp}`, `rt_weights.{hpp,cpp}` — live-таблицы.
|
- `dsp/rt_mask_tables.{hpp,cpp}`, `rt_weights.{hpp,cpp}` — live-таблицы.
|
||||||
- `handoff/NOTES_LEVEL.md` — полный журнал уровня/маски (самый актуальный).
|
- `handoff/NOTES_LEVEL.md` — полный журнал уровня/маски (самый актуальный).
|
||||||
- `handoff/nls_dasm/` — 134 дизассембла декомпа.
|
- `handoff/nls_dasm/` — 134 дизассембла декомпа.
|
||||||
|
|||||||
+62
-27
@@ -13,22 +13,27 @@ comb 10 dB). Bit-exact ДОСТИЖИМ (F0 gate: плагин байт-дете
|
|||||||
|
|
||||||
## 0. Текущее состояние (честная метрика, 24-bit, trimmed, 62 случая)
|
## 0. Текущее состояние (честная метрика, 24-bit, trimmed, 62 случая)
|
||||||
|
|
||||||
| Группа | mean|err| (dB) | max | Уровень |
|
| Группа | bridge mean|err| | bridge max | struct 48k mean|err| | struct max |
|
||||||
|--------|----------|-----|---------|
|
|--------|----------|-----|----------|---------|
|
||||||
| t1kq (fc-scan) | 0.226 | 0.500 | ✓ ближе всего |
|
| t1kq (fc-scan) | 0.226 | 0.500 | 0.768 | 1.013 |
|
||||||
| t1k (loud 0 dBFS) | 1.801 | 2.227 | ! уровневая |
|
| t1k (loud 0 dBFS) | 1.801 | 2.227 | 2.114 | 2.753 |
|
||||||
| al (level sweep) | 0.638 | 1.596 | ! уровневая |
|
| al (level sweep) | 0.638 | 1.596 | 0.986 | 1.822 |
|
||||||
| res | 0.628 | 1.535 | ! |
|
| res | 0.628 | 1.535 | **0.437** ✓ | 1.252 |
|
||||||
| dual (q-sweep) | 0.726 | 2.252 | ! |
|
| dual (q-sweep) | 0.726 | 2.252 | 3.264 ✗ | 6.455 |
|
||||||
| comb (4-band) | **10.149** | **14.752** | ✗ сломан |
|
| comb (4-band) | **10.149** ✗ | 14.752 | **6.116** ✓ | 9.148 |
|
||||||
| **TOTAL** | **1.594** | **14.752** | |
|
| **TOTAL** | **1.594** | 14.752 | 2.286 | 9.148 |
|
||||||
|
|
||||||
|
(struct = структурная цепь на внутренней сетке 48000/4096 через `dsp/build/render48k`,
|
||||||
|
прогон `scripts/corpus_structural.py`, NOTES_LEVEL:21c. Bridge = `framed_test` 44.1k.)
|
||||||
|
|
||||||
**Корень проблемы**: активный канон — ЭМПИРИЧЕСКАЯ bridge-модель
|
**Корень проблемы**: активный канон — ЭМПИРИЧЕСКАЯ bridge-модель
|
||||||
`C = G·LUT(xv) + W·warp(f)^A; gain = (1−C)·res^rp` (xv=log10(am/res)). Это ПОГОНА, не
|
`C = G·LUT(xv) + W·warp(f)^A; gain = (1−C)·res^rp` (xv=log10(am/res)). Это ПОГОНА, не
|
||||||
транскрипция. Структурная цепочка FUN_180529fe0 (IIR1/2/3 → exp2 → combine/acc → warp →
|
транскрипция. Структурная цепочка FUN_180529fe0 перенесена в C++ на внутренней сетке
|
||||||
dry/wet → FFT-conv) расшифрована и live-таблицы извлечены (`dsp/rt_mask_tables`,
|
(коммиты 7bf5a4a..b2cb923): уже ОБГОНЯЕТ bridge на comb (−4 dB) и res, но регрессирует
|
||||||
`dsp/rt_weights`), но при переносе в C++ (Phase B, da63adc) **регрессировала** и откачена
|
на однополосных t1kq/t1k/al и проваливает dual@500 (константный −6.7 dB при всех q —
|
||||||
на bridge. Дальше надо вернуться к структурной цепочке и закрыть её по-настоящему.
|
отсутствие НАСЫЩЕНИЯ редукции: реальная кривая упирается в C_max≈0.70, exp2(−lvl) не
|
||||||
|
ограничен). Свип γ×MULT подтвердил: текущий оптимум (0.344/4.2) лучший, слепая
|
||||||
|
подкрутка исчерпана — проблема в ФОРМЕ кривой, см. Шаг 7 / bigkernel-вход.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -74,12 +79,22 @@ dry/wet → FFT-conv) расшифрована и live-таблицы извле
|
|||||||
домена (пробовали combine в bridge-финале). Здесь combine/exp2 — в ЕГО собственном
|
домена (пробовали combine в bridge-финале). Здесь combine/exp2 — в ЕГО собственном
|
||||||
домене (reduction/exp2), как в декомпе.
|
домене (reduction/exp2), как в декомпе.
|
||||||
|
|
||||||
### Шаг 2 — combine/аккумулятор 0x5407c8 (закрывает comb + negative-sens)
|
### Шаг 2 — combine/аккумулятор 0x5407c8 (ПЕРЕ-СКОУП 2026-08-21)
|
||||||
Точные веса `kRTAtt`/`kRTRel` (0x5406c8/6e8) уже в `dsp/rt_weights.cpp`. Реализовать
|
Семантика декодирована на уровне thunk'ов (NOTES_LEVEL:21b, consumers_out.txt:833-885):
|
||||||
combine строго по декомпу: `acc = band − f6f8; += w_att·upper; += w_rel·lower; += band`
|
```
|
||||||
в exp2/REDUCTION-домене (не в bridge-final-gain). Ожидается: comb перестаёт пережимать,
|
f6f8 = mask − acc (0x8d60, dst=3-й аргумент; acc НЕ перезаписывается)
|
||||||
negative-sens (band2 sens=−12) даёт компенсацию. Критерий: comb mean ≤ 2-3 dB (с −15 до
|
mirror f6f8
|
||||||
нейтрали), и MB-ваимодействие (comb_all ≈ 0) воспроизводится.
|
f6f8_upper += kRTAtt·acc_upper ; f6f8_lower += kRTRel·acc_lower (0x3c40)
|
||||||
|
acc += mask (0x5a20, персистентный per-band аккумулятор)
|
||||||
|
```
|
||||||
|
**КРИТИЧЕСКОЕ**: в online однополосном пути обновлённые f6f8/acc НЕ имеют консюмера до
|
||||||
|
warp/IIR3/dry-wet (проверено исчерпывающим grep). Combine НЕ может влиять на single-band
|
||||||
|
вывод сам по себе. Ожидалось, что combine закроет comb — частично закрыл уже сам
|
||||||
|
структурный каркас (comb 6.1 vs bridge 10.1 без wiring). ДАЛЬНЕЙШИЙ ШАГ: найти точку
|
||||||
|
потребления acc/f6f8 (межполосный уровень или FFT-conv каскад) и только потом wire.
|
||||||
|
НЕ изобретать track→mask feedback (эмпирика, запрещено золотым правилом).
|
||||||
|
ВНИМАНИЕ: `FUN_1805316e0` — это WRITER КОЭФФИЦИЕНТОВ полос (17 case), НЕ масковый
|
||||||
|
комбинер (ошибка в старой редакции этого плана и в Шаге 8).
|
||||||
|
|
||||||
### Шаг 3 — Bit-exact exp2 (F5b)
|
### Шаг 3 — Bit-exact exp2 (F5b)
|
||||||
Заменить `std::exp2`/`exp2d::exp2_dsp` на точную табличную реализацию `0x26b820`:
|
Заменить `std::exp2`/`exp2d::exp2_dsp` на точную табличную реализацию `0x26b820`:
|
||||||
@@ -88,11 +103,15 @@ negative-sens (band2 sens=−12) даёт компенсацию. Критери
|
|||||||
overflow). Пока не bit-exact — оставить `exp2d::exp2_dsp` (численно = std::exp2).
|
overflow). Пока не bit-exact — оставить `exp2d::exp2_dsp` (численно = std::exp2).
|
||||||
Критерий: `exp2_check` сравнивает протв захваченных пар точка-в-точку.
|
Критерий: `exp2_check` сравнивает протв захваченных пар точка-в-точку.
|
||||||
|
|
||||||
### Шаг 4 — FFT-conv 0x535a70 + FIR
|
### Шаг 4 — FFT-conv 0x535a70 + FIR (ПРИОРИТЕТ ПОНИЖЕН 2026-08-21)
|
||||||
FFT-conv сглаживает маску перед FIR (0x540658 window / freqaxis). Это последний этап
|
FFT-conv сглаживает маску перед FIR (0x540658 window / freqaxis). Это последний этап
|
||||||
mono-цепи. `dsp/fftconv.cpp` есть, но нужна точная блоковая обработка (overlap-save как
|
mono-цепи. `dsp/fftconv.cpp` есть, но нужна точная блоковая обработка (overlap-save как
|
||||||
в декомпе 0x52b550-0x52b8b5), не текущий stand-in. Критерий: маска-гейн после conv
|
в декомпе 0x52b550-0x52b8b5), не текущий stand-in. Критерий: маска-гейн после conv
|
||||||
совпадает по форме с реальным ref (сглаживание нотча, двусторонний хвост).
|
совпадает по форме с реальным ref (сглаживание нотча, двусторонний хвост).
|
||||||
|
**ПОНИЖЕНО до P3**: NOTES_LEVEL:18c — окно 0x540658 near-flat (0.8→1.0 plateau при
|
||||||
|
N/2≥2048), эффект построения FIR на форму маски минимален при N=4096. Последовательность
|
||||||
|
уже размечена (fwd → kill mirror → fill xmm13/xmm9 → inv → complex op → fwd → window
|
||||||
|
copy → inv → FIR[0]=1.0); остались неизвестные скаляры xmm13/xmm9 и complex-op шага 4.
|
||||||
|
|
||||||
### Шаг 5 — Bit-exact DSP-FFT 0x140a70 (multi-week, P3)
|
### Шаг 5 — Bit-exact DSP-FFT 0x140a70 (multi-week, P3)
|
||||||
Заменить `dsp/fft.cpp` (std::cos radix-2) на точный split-radix 2/4/8 по плану из
|
Заменить `dsp/fft.cpp` (std::cos radix-2) на точный split-radix 2/4/8 по плану из
|
||||||
@@ -103,12 +122,17 @@ NOTES_LEVEL:1107-1116:
|
|||||||
Это НЕ блокирует Шаги 1-4 (bridge/структурная цепь рендерят и с численным FFT), нужен
|
Это НЕ блокирует Шаги 1-4 (bridge/структурная цепь рендерят и с численным FFT), нужен
|
||||||
только для побайтовой парности FFT-conv-пути.
|
только для побайтовой парности FFT-conv-пути.
|
||||||
|
|
||||||
### Шаг 6 — Внутренняя геометрия 48000/4096 vs 44100/2048
|
### Шаг 6 — Внутренняя геометрия 48000/4096 vs 44100/2048 — ✅ ПАЙПЛАЙН СДЕЛАН (2026-08-21)
|
||||||
Внутренний DSP SR=48000/N=4096 (freqaxis spacing 11.713 Hz). Хост рендера 44100/2048.
|
Внутренний DSP SR=48000/N=4096 (freqaxis spacing 11.713 Hz). Хост рендера 44100/2048.
|
||||||
F4-тест показал, что простая resample_poly НЕ закрывает (даже хуже). Нужно: детектор
|
F4-тест показал, что простая resample_poly НЕ закрывает (даже хуже). Нужно: детектор
|
||||||
гнать на 48000/4096 (IIR-таблицы индексированы 0..2048 = N/2+1 при N=4096), затем
|
гнать на 48000/4096 (IIR-таблицы индексированы 0..2048 = N/2+1 при N=4096), затем
|
||||||
свести к 44100. Ожидается закрытие хвостов t1k_b1f/al (+2.2/−1.6) — именно уровневой
|
свести к 44100. Ожидается закрытие хвостов t1k_b1f/al (+2.2/−1.6) — именно уровневой
|
||||||
зависимости. Критерий: корректное выравнивание бина и окна между двумя сетками.
|
зависимости. Критерий: корректное выравнивание бина и окна между двумя сетками.
|
||||||
|
**Статус**: пайплайн `dsp/render48k.cpp` (resample 44.1→48 → SpectralProcessor(4096,1024,48000)
|
||||||
|
→ resample обратно) реализован и гоняет полный корпус (`scripts/corpus_structural.py`,
|
||||||
|
коммиты 7659eb0/6924e53). Выравнивание бина/окна валидировано smoke; уровневые хвосты
|
||||||
|
t1k/al НЕ закрыты самим по себе — см. §0 и Шаг 7. Известный артефакт: zero-pad последнего
|
||||||
|
BLK-блока даёт спад am в ~последних 0.06s (косметика, на метрику почти не влияет).
|
||||||
|
|
||||||
### Шаг 7 — BandConfig A/B/γ (level-path ctx+0x188) live-захват под конкретные конфиги
|
### Шаг 7 — BandConfig A/B/γ (level-path ctx+0x188) live-захват под конкретные конфиги
|
||||||
Структурная LUT-кривая `FUN_180563a60` (A/B/γ). Снято для render_long (A=−24/B=28/γ=1)
|
Структурная LUT-кривая `FUN_180563a60` (A/B/γ). Снято для render_long (A=−24/B=28/γ=1)
|
||||||
@@ -118,8 +142,10 @@ F4-тест показал, что простая resample_poly НЕ закры
|
|||||||
mean кап-нагрузки al/t1k ≤ 0.3 dB.
|
mean кап-нагрузки al/t1k ≤ 0.3 dB.
|
||||||
|
|
||||||
### Шаг 8 — Стерео M8 + полный pipeline (P4/P5)
|
### Шаг 8 — Стерео M8 + полный pipeline (P4/P5)
|
||||||
Финальный рендер stereo (link/balance/LR-vs-MS) по M8 и multiband combine 0x5316e0.
|
Финальный рендер stereo (link/balance/LR-vs-MS) по M8 и межполосное суммирование.
|
||||||
Все текущие рендеры mono. Для bit-exact графа нужны стерео-рендеры как мишены.
|
Все текущие рендеры mono. Для bit-exact графа нужны стерео-рендеры как мишени.
|
||||||
|
ВНИМАНИЕ: `FUN_1805316e0` = writer коэффициентов полос, НЕ комбинер масок — точка
|
||||||
|
межполосного суммирования масок/acc ещё не локализована (см. пере-скоуп Шага 2).
|
||||||
Критерий: `verify_bit_exact.py` — побайтовое совпадение данных-чанка WAV.
|
Критерий: `verify_bit_exact.py` — побайтовое совпадение данных-чанка WAV.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -148,7 +174,16 @@ mean кап-нагрузки al/t1k ≤ 0.3 dB.
|
|||||||
## 4. Точка входа для следующей сессии
|
## 4. Точка входа для следующей сессии
|
||||||
|
|
||||||
1. Прочитать `AGENTS.md`, этот `BITEXACT_PLAN.md`, `handoff/NOTES_LEVEL.md:820-840`
|
1. Прочитать `AGENTS.md`, этот `BITEXACT_PLAN.md`, `handoff/NOTES_LEVEL.md:820-840`
|
||||||
(точная цепочка) и `dsp/rt_mask_tables.hpp` / `dsp/rt_weights.hpp` (live-таблицы).
|
(точная цепочка) + апдейты 20j/21a/21b/21c (IIR3 bidi, combine-семантика,
|
||||||
2. Собрать: `cd dsp && cmake --build build --target framed_test`.
|
структурный корпус) и `dsp/rt_mask_tables.hpp` / `dsp/rt_weights.hpp` (live-таблицы).
|
||||||
3. Бейзлайн: `TAG=base python3 /tmp/full_corpus.py` (62 случая, см. таблицу §0).
|
2. Собрать: `cmake --build dsp/build --target render48k framed_test`.
|
||||||
4. Шаг 1: вынести структурную цепочку в `dsp/fn529fe0.cpp`, валидировать IIR1-шаг на t1kq.
|
3. Бейзлайны: `python3 scripts/corpus.py` (bridge, 62 случая, §0) и
|
||||||
|
`python3 scripts/corpus_structural.py --vs-bridge scripts/baseline_bridge.json`
|
||||||
|
(структурная цепь на внутренней сетке).
|
||||||
|
4. ПРИОРИТЕТ (закрытие разрыва формы кривой редукции):
|
||||||
|
a. СТАТИКА: hunt clamp/насыщения в level-пути — `vminpd/vmaxpd/minsd/maxsd` в
|
||||||
|
FUN_18052d650 (IIR1), инлайн IIR2, scale-шаг; семантика FUN_180323f20 и
|
||||||
|
depth-скаляра 0x540888. Если clamp найден — транскрибировать, smoke + корпус.
|
||||||
|
b. Если статика исчерпана — Шаг 7: live-захват BandConfig ctx+0x188 по
|
||||||
|
NOTES_CAPTURE.md; сначала разрешить противоречие A/B/γ между сессиями
|
||||||
|
(render_long/t1kq: −24/28/1 vs fit по точкам рефов: −13.78/68.29/0.344).
|
||||||
|
|||||||
+24
-16
@@ -10,21 +10,27 @@
|
|||||||
(WAV16 → рендер → WAV24), `dsp_notes.md` (карта функция↔смысл, константы, LUT),
|
(WAV16 → рендер → WAV24), `dsp_notes.md` (карта функция↔смысл, константы, LUT),
|
||||||
`verify_bit_exact.py` (прогон всех свипов, побайтовое сравнение).
|
`verify_bit_exact.py` (прогон всех свипов, побайтовое сравнение).
|
||||||
|
|
||||||
## Текущий статус (2026-08-20, P4)
|
## Текущий статус (2026-08-21, P4)
|
||||||
|
|
||||||
> **2026-08-21: bit-exact НЕ достигнут** — честная dB-параллель (корпус mean 1.594 dB,
|
> **2026-08-21: bit-exact НЕ достигнут** — честная dB-параллель. Два канона:
|
||||||
> comb 10 dB). Активный канон — bridge (эмпирическая погона). Путь к байтам — в
|
> bridge (эмпирическая погона, корпус mean 1.594 dB, comb 10.1) и СТРУКТУРНАЯ цепь
|
||||||
> `BITEXACT_PLAN.md` (8 шагов: структурная цепочка → combine/acc → bit-exact exp2/FFT →
|
> FUN_180529fe0 на внутренней сетке 48000/4096 (`dsp/build/render48k`, корпус mean
|
||||||
> геометрия 48000/4096 → A/B/γ → стерео). См. также итог comb-экспериментов в
|
> 2.286 dB, comb **6.12** — уже лучше bridge на мультиполосе, res тоже лучше; хуже на
|
||||||
> `handoff/NOTES_LEVEL.md`.
|
> однополосных). Разрыв формы кривой редукции: реальная насыщается (C_max≈0.70),
|
||||||
|
> exp2(−lvl) нет → Шаг 7 захват A/B/γ или статический hunt clamp'а в level-пути.
|
||||||
|
> Путь к байтам — `BITEXACT_PLAN.md` (8 шагов, пере-скоуп Шага 2: acc не имеет
|
||||||
|
> однополосного консюмера; FUN_1805316e0 = writer коэффициентов, НЕ комбинер).
|
||||||
|
> Полный журнал — `handoff/NOTES_LEVEL.md` (апдейты 20j–21c).
|
||||||
|
|
||||||
- **Статический декомп DSP-ядра — закрыт (~95%)**: twin-резонатор, генератор case8,
|
- **Статический декомп DSP-ядра — закрыт (~95%)**: twin-резонатор, генератор case8,
|
||||||
level-path (0x529fe0/0x563440/0x563a60), mask-apply (FUN_180529fe0 mono-path), IIR-трекеры,
|
level-path (0x529fe0/0x563440/0x563a60), mask-apply (FUN_180529fe0 mono-path), IIR-трекеры,
|
||||||
FFT-conv (0x535a70), main render-loop (FUN_18052e260) декодированы; `.dis` в `handoff/nls_dasm/`.
|
FFT-conv (0x535a70), main render-loop (FUN_18052e260) декодированы; `.dis` в `handoff/nls_dasm/`.
|
||||||
- **Канон — C++ `FramedDetector`** (`dsp/framed_model.cpp`), реальная mask-цепь отвоевана от
|
- **Структурная цепь в C++** (`dsp/framed_model.cpp::process_band_structural`, сетка 48k/4096):
|
||||||
эмпирики: `level→scale→IIR1/2 leaky→exp2(-mask)·blend→combine/acc→dual-warp→IIR3×2→dry/wet→FFT-conv`.
|
`scale→LUT(level-domain)→IIR1→IIR2→mirror→blend/exp2→combine(acc-update)→dual-warp→IIR3 bidirectional×2→dry/wet`;
|
||||||
Live-таблицы в `dsp/rt_mask_tables.{hpp,cpp}`, `rt_weights.{hpp,cpp}`.
|
live-таблицы в `dsp/rt_mask_tables.{hpp,cpp}`, `rt_weights.{hpp,cpp}`. Прогон:
|
||||||
- **Результаты**: t1kq err **−0.43 dB** (level_scale=600); comb per-tone err ≤6.4 dB.
|
`scripts/corpus_structural.py`. IIR3 = [fwd+bwd]×2 по декомпу (коммит 1a616e1).
|
||||||
|
- **Результаты структурной цепи (62 кейса)**: comb 6.12 (bridge 10.15), res 0.44 (0.63),
|
||||||
|
t1kq 0.77 / t1k 2.11 / al 0.99 / dual 3.26 (хуже bridge). Детали: NOTES_LEVEL:21c.
|
||||||
- **Честная тримнутая метрика** (длина выхода = длина входа) — см. AGENTS.md.
|
- **Честная тримнутая метрика** (длина выхода = длина входа) — см. AGENTS.md.
|
||||||
- **Цель bit-exact (Phase C) — в работе**: twin-транскрипция в `dsp/` готова и проходит
|
- **Цель bit-exact (Phase C) — в работе**: twin-транскрипция в `dsp/` готова и проходит
|
||||||
- **Бит-экзактная C++ транскрипция (Phase C)**: twin (float-parity 1.27e-5, tables_check ALL OK),
|
- **Бит-экзактная C++ транскрипция (Phase C)**: twin (float-parity 1.27e-5, tables_check ALL OK),
|
||||||
@@ -76,14 +82,16 @@ gain = max(1 - C, eps) * res_k**rp # rp = rp0 * Q**drp (res_power)
|
|||||||
| P2 | mask-accumulator combine kernels (8d60/5a20/3c40) | ✅ DONE (levelpath.cpp combine_sub/acc_add/acc_fma) |
|
| P2 | mask-accumulator combine kernels (8d60/5a20/3c40) | ✅ DONE (levelpath.cpp combine_sub/acc_add/acc_fma) |
|
||||||
| P2.5 | twin-mask factory (56e3e0) + band LUT apply (563a60) | ✅ DONE (levelpath.cpp) |
|
| P2.5 | twin-mask factory (56e3e0) + band LUT apply (563a60) | ✅ DONE (levelpath.cpp) |
|
||||||
| P3 | бит-экзактная base-CRT FFT | ⚠️ partial: архитектура размечена, vlog(ln) транскрибирован; butterfly+shuffle+plan-gen осталось |
|
| P3 | бит-экзактная base-CRT FFT | ⚠️ partial: архитектура размечена, vlog(ln) транскрибирован; butterfly+shuffle+plan-gen осталось |
|
||||||
| P4 | render-loop 52e260 + связка mask→FFT-conv + full pipeline | ✅ **существенно продвинут (2026-08-20)**: mono-path FUN_180529fe0 декодирован, реальная mask-цепь транскрибирована в `framed_model.cpp` (IIR1/2/3 leaky + exp2-bigkernel + dual warp + dry/wet), live-таблицы извлечены (`rt_mask_tables`); t1kq −0.43 dB, comb ≤6.4 dB. Остаток: PRNG-пролог, FFT-conv, бит-экзактный exp2, combine-фидбек, SR-mismatch |
|
| P4 | render-loop 52e260 + связка mask→FFT-conv + full pipeline | ✅ **существенно продвинут (2026-08-21)**: mono-path FUN_180529fe0 декодирован и транскрибирован на внутренней сетке 48k/4096 (`render48k`, LUT в level-домене, IIR3 bidirectional по декомпу); полный структурный корпус: comb **6.12** (bridge 10.15), res 0.44; однополосные хуже bridge — нужен шаг насыщения кривой редукции. Combine-семантика декодирована до thunk'ов; acc не имеет однополосного консюмера (пере-скоуп). Остаток: точка потребления acc/f6f8, PRNG-пролог, бит-экзактный exp2, FFT-conv (P3), SR-хвосты |
|
||||||
| P5 | стерео M8 (link/balance/LR-vs-MS) + multiband combine 5316e0 | TODO (в скоупе, не начат) |
|
| P5 | стерео M8 (link/balance/LR-vs-MS) + multiband combine 5316e0 | TODO (в скоупе, не начат) |
|
||||||
|
|
||||||
Обновлённая оценка (2026-08-20): структурно ~75% готово — mask-apply цепь FUN_180529fe0
|
Обновлённая оценка (2026-08-21): структурно ~80% готово — mask-apply цепь FUN_180529fe0
|
||||||
полностью декодирована (scale→IIR1/2→exp2→combine→warp→IIR3→dry/wet→FFT-conv) и перенесена
|
декодирована (scale→LUT→IIR1/2→exp2→combine→warp→IIR3-bidi→dry/wet→FFT-conv) и перенесена
|
||||||
в C++, live-таблицы (IIR A/B, warp, band768, PRNG LUT) извлечены. Осталось: (а) полная
|
в C++ на внутренней сетке, live-таблицы (IIR A/B, warp, band768, PRNG LUT) извлечены,
|
||||||
бит-экзактная FFT (butterfly+shuffle+plan-gen — недели), (б) PRNG-пролог + FFT-conv +
|
полный корпус гоняется. Осталось: (а) полная бит-экзактная FFT (butterfly+shuffle+plan-gen
|
||||||
бит-экзактный exp2 для bit-exact калибровки, (в) стерео M8 (P5).
|
— недели), (б) насыщение кривой редукции (Шаг 7 захват A/B/γ или clamp-hunt в level-пути),
|
||||||
|
(в) точка потребления combine acc/f6f8, (г) PRNG-пролог + FFT-conv + бит-экзактный exp2,
|
||||||
|
(д) стерео M8 (P5).
|
||||||
|
|
||||||
## Ключевые находки (итог)
|
## Ключевые находки (итог)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user