Files
soothe2-re/README.md
T
Matiq f73724fee7 docs: archive 4024стр NOTES_LEVEL, единый источник TOTAL README, runbook AGENTS, 3-шаг план
- handoff/NOTES_LEVEL.md 4413→397 (голова 24mm5+), хвост → handoff/archive/NOTES_LEVEL_2026-08-18_2026-08-23.md
- handoff/NOTES_LEVEL_INDEX.md NEW навигатор, handoff/archive/ whitelist .gitignore
- SESSION_HANDOFF/summary → archive + редиректы, NOTES_TWIN/NOTES_CAPTURE сжаты
- README.md:13 единственный источник TOTAL 1.594/dual 0.193, AGENTS runbook, BITEXACT_PLAN 9→3 шага (каскад 9-19/k-маппинг/Δ)
2026-08-29 03:15:42 +03:00

157 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# soothe2-re
Обратный инжиниринг DSP-ядра **oeksound soothe2** (VST3, Windows x64) → проверяемая
реконструкция на C++ с **bit-exact** целью.
Цель — понять, как именно плагин считает подавление резонансов (уровневый детектор,
маска, фильтр), и воспроизвести это дословно. Текущий активный канон — C++
`FramedDetector` (`dsp/framed_model.cpp`): real mask-apply цепь с live-таблицами.
Канонные команды и метрика — в [`AGENTS.md`](AGENTS.md).
---
## Статус (24mm14, 2026-08-28) — ЕДИНСТВЕННЫЙ ИСТОЧНИК TOTAL
**Канон (bridge, `framed_test` 44.1k): TOTAL 2.286 dB** — честная 24-bit trimmed метрика, 62 случая (`scripts/baseline_bridge.json`). Guard: `python3 scripts/corpus.py --compare scripts/baseline_bridge.json --tol 0.25`. Детали — `handoff/NOTES_LEVEL_INDEX.md`.
**Цель — bit-exact** (гейт смены канона = все параметры прослежены до декомпа + корпус в шумовой пол). Декомп DSP-ядра ~95%, `handoff/nls_dasm/` ~140 `.dis`.
**Применение декодировано до формул** (сессии 24j…24mm14, журнал — `handoff/NOTES_LEVEL.md` живая голова + `handoff/archive/`):
```
mask(b) = 10^(cut_D(b)/20) ← вещественная, per-bin multiply кадра
cut_D(b) = α·ln(1+lvl_raw(b)/β)+c [+Δ у вторых пиков]
lvl_raw = am/res·scale (наш детектор-фронтенд, float-parity ✓)
слой = STFT БЕЗ синтез-окна (RT_SYN=1)
```
Калибровки (три независимых семейства, rms ≤0.016 дБ): α/β/c зависят от контента (α удваивается с числом тонов — частотное смешение шаблонно-локальное), q НЕ влияет на закон (`24kk`), sens линейно через lvl_raw (`24kk`).
- **dual-семейство решено (env-gated)**: 22 случая **mean 0.193 / max 0.438 dB** (канон 3.264). Флаги `RT_VLAW=1 RT_SYN=1 RT_NOWARP=1 RT_NOIIR3=1 RT_IIR12=0`. Канон не тронут.
- **Буфер FIR@540668** — промежуточное мин.-фазовое `exp(si·H(s))`; аудио = `exp(scratch)` напрямую.
- **Тела bigkernel'ов** (рантайм IAT): `1803a06a0 / 180296c80 / 180323f20 / 1802dc0e0` — x87 exp-семейство (`handoff/BLOCKMAP_529fe0.md:540`).
### Главное за 2026-08-24…28 (24j24mm14)
1. **Применение = побиновный multiply** на вещественную маску; «×1.805» = `0.984×1.8345` (экспоненты стадий).
2. **Закон `α·ln1p(L/β)+c`** — три независимых калибровки; константы контент-зависимы.
3. **Слой STFT без синтез-окна** (`RT_SYN=1`); `WIN_WINDOW` 0.5→0.8 за 2049 сэмплов.
4. **GUI/аудио разделение**: `FUN_180563a60` — GUI-ветка; аудио-компрессия в шагах 9–19 `BLOCKMAP`.
5. **Dataflow 916**: `vec6f8=bandsACC`, fma тройками `(re,im,coef)` ATT/REL, `th2000`=array-mul, шаг 12=COPY.
6. **Детекторный каскад `180529c60` (vt+0x28)**: `|z| → Haar [0.25,0.5,0.25]×2 → peak/sin → w=1/inner → blend 5407a8`.
7. **RFFT до df0 бит-точна** (`th1a90/th2180` + `buf548` scale 2^-12, `24mm9` 0.0065 dB).
```bash
# Сборка и канонные команды (см. AGENTS.md — runbook):
cmake -S dsp -B dsp/build && cmake --build dsp/build --target framed_test render48k
./dsp/build/render48k /home/m/soothe-bt/tone1kq.wav /tmp/o48.wav 1000,0.99999785,12
python3 scripts/corpus.py --compare scripts/baseline_bridge.json --tol 0.25
python3 scripts/corpus_structural.py --vs-bridge scripts/baseline_bridge.json
```
### Открытые bit-exact пробелы (приоритет → `BITEXACT_PLAN.md`)
1. **Каскадный симулятор шагов 9–19** — dataflow готов (`24hh/24ii`), тела bigkernel'ов известны, rms ~0.42 на угаданных формах → оп-за-оп транскрипция + `sc_*` датасеты.
2. **k-маппинг фронтенда** (twin/am, `k=0.403 ∀q≥2`, `24x`).
3. **Δ-правило вторых пиков** из pre-combine.
> Исторический блок B.1…B.15 (`framed_render.py`, Pchip, `res_power`) — см. `handoff/archive/NOTES_LEVEL_2026-08-18_2026-08-23.md` и `roadmap.md`; не канон.
---
## Структура репозитория
```
re-tools/
├── README.md ← вы здесь (ЕДИНСТВЕННЫЙ источник TOTAL)
├── AGENTS.md ← runbook: сборка, метрика, env-флаги, tooling hazard
├── BITEXACT_PLAN.md ← план к bit-exact (3 шага, критерии, риски)
├── roadmap.md ← журнал B-фаз (B.1…B.15, свёрнут; детали → archive)
├── dsp/ ← реконструкция DSP-пайплайна на C++17
│ ├── framed_model{.cpp,.hpp} ← ГЛАВНЫЙ: mask-apply цепь (канон)
│ ├── framed_test.cpp ← CLI bridge-рендер (N=2048, SR 44100)
│ ├── render48k.cpp ← структурная цепь 48k/4096 (resample → chain → resample)
│ ├── rt_mask_tables{.hpp,.cpp}, rt_weights{.hpp,.cpp} ← live-таблицы (IIR A/B, warp)
│ ├── twin{.hpp,.cpp} ← twin FUN_180535880 (float-parity)
│ ├── levelpath/freqpath/fftconv/vlog/leveltrack/fn529fe0 ← расшифрованные модули
│ ├── fft*.cpp, twiddle_*.cpp/hpp, phase_table.*, cody_waite.hpp
│ └── CMakeLists.txt
├── handoff/
│ ├── NOTES_LEVEL.md ← живой журнал (голова 24mm5+; хвост → archive/)
│ ├── NOTES_LEVEL_INDEX.md ← оглавление журнала по датам/темам
│ ├── BLOCKMAP_529fe0.md ← карта метода FUN_180529fe0 (актуальна)
│ ├── NOTES_TWIN.md ← twin краткая справка (детали → dsp/twin.cpp)
│ ├── NOTES_CAPTURE.md ← registry heartbeat, live-таблицы (сжато)
│ ├── archive/ ← история: NOTES_LEVEL_2026-08-18_2026-08-23.md,
│ │ SESSION_HANDOFF_2026-08-18.md, summary_v4.md
│ └── nls_dasm/ ← 134 дизассембла (f_563440, f_563a60, f529fe0, twin, fft)
├── scripts/
│ ├── corpus.py / corpus_structural.py ← харнессы (guard --compare)
│ ├── rendersnap2.py, campaign.py, disasm_func.py, iat_name.py ← инструменты 24j+
│ └── lawfit22r.py, resalpha.py, cascade_sim.py, wine_*trace.py
├── *.java ← Ghidra-скрипты (DumpFuns, ImportRtti …)
├── soothe_mem.bin ← дамп памяти (вне git, VA0x180000000)
├── rwin_{A0,A1,B0,C0}.npy, r_freqaxis.npy ← живые таблицы (48k)
└── framed_render.py, model_*.py, sim.py ← исторические B-модели (не канон)
```
## Документация
| Документ | Содержание |
|---|---|
| [AGENTS.md](AGENTS.md) | **Runbook**: сборка, метрика, env-флаги, tooling hazard |
| [BITEXACT_PLAN.md](BITEXACT_PLAN.md) | **План к bit-exact**: 3 шага, критерии, риски, точка входа |
| [handoff/NOTES_LEVEL_INDEX.md](handoff/NOTES_LEVEL_INDEX.md) | **Оглавление журнала** по датам/темам → `NOTES_LEVEL.md` / `archive/` |
| [handoff/NOTES_LEVEL.md](handoff/NOTES_LEVEL.md) | Живой журнал (голова 24mm5+; хвост → `archive/`) |
| [handoff/BLOCKMAP_529fe0.md](handoff/BLOCKMAP_529fe0.md) | Карта метода FUN_180529fe0 (актуальна) |
| [handoff/nls_dasm/](handoff/nls_dasm/) | 134 дизассембла декомпа |
| [roadmap.md](roadmap.md) | Журнал B-фаз (свёрнут, детали → archive) |
| [handoff/NOTES_TWIN.md](handoff/NOTES_TWIN.md) | Twin краткая справка (детали → `dsp/twin.cpp`) |
| [handoff/NOTES_CAPTURE.md](handoff/NOTES_CAPTURE.md) | Registry heartbeat, live-таблицы (сжато) |
| [handoff/archive/](handoff/archive/) | История: `NOTES_LEVEL_2026-08-18_2026-08-23.md`, `SESSION_HANDOFF_…`, `summary_v4.md` |
### Тестовый корпус `/home/m/soothe-bt/` (вне git)
~600 рендеров REAPER (`.rpp` + `.wav`). Ключевые наборы:
| Префикс | Что измеряет |
|---------|-------------|
| `dual_b1q_*` | 2 тона (500+2000), q 0.1…10 → **парадокс red2000>red500** (решён: аддитивный warp) |
| `al_*` | уровневой свип (fc=1000) → прямое измерение LUT-кривой |
| `t1kq_*`, `t1k_*` | 1 тон, fc-скан, уровни −18/0 dBFS → форма полосы |
| `burst500_b1` | основной эталон: burst 500 Гц, band1 fc=500 mode=1 sens=12 |
| `tone1k`, `tone1kq`, `dual` | входные тоны (0 / 18 / 7.1 dBFS) |
---
## Историческая численная модель (B-фазы; канон теперь — C++ FramedDetector, см. выше)
```python
# per-frame, per-bin (framed_render.py — исторический канон B.15)
xv = log10(A_k / res_k) # A_k = 2|X_k|/wsum (twin-env), res = |2B/A| case8
C = G * LUT(xv) + W * warp(f_k)**A # additive mask (НЕ мультипликация warp·LUT)
gain = max(1 - C, eps) * res_k**rp # rp = rp0 * Q**drp (res_power)
```
- LUT — Pchip, узлы из joint-фита (dual+al_*) **или** свободные 8 узлов (B.15 → mean 0.027);
- warp — эмпирический `0.87·7.942·x/(7.942+x)`, x=f/2000 (аппроксимация runtime-вычисления FUN_180563440);
- rp(Q)=0.0275·Q^0.2159 (Q-dep rp, B.14);
- B.15: G/W/A/rp0/drp = 0.9752/0.3394/1.0222/0.0254/0.2231; LUT KX=[0.8..1.0].
---
## Как всё это воспроизвести
1. **Достать бинарь**: установить soothe2 (Windows VST3) под yabridge, запустить
`dump_soothe.py``soothe_mem.bin` (или взять `.vst3`, выдернуть секции).
2. **Декомпиляция**: `analyzeHeadless <proj> soothe_x64 -process soothe_mem.bin
-noanalysis -postScript <X>.java` (image_base=0, блок `ram`=[0x180000000,…],
адреса = RVA; смещение в файле = VA0x180000000).
3. **Рендеры**: `sweep.py` генерит `.rpp`, `reaper -renderproject` выдаёт `.wav`.
4. **Анализ**: `render_parity.py` / `framed_render.py` сравнивают модель с реальными
рендерами (steady-state tone-замер, тримнутая метрика).
---
## Чего не хватает / следующие шаги (bit-exact) → `BITEXACT_PLAN.md`
1. **Каскадный симулятор шагов 9–19** (приоритет №1) — см. `BITEXACT_PLAN.md:1`.
2. **k-маппинг фронтенда** twin/am (приоритет №2).
3. **Δ-правило вторых пиков** (приоритет №3).