docs: AGENTS.md + refresh README/roadmap/summary/SESSION_HANDOFF to P4 canon; rm empty logs
- AGENTS.md: canonical build/test commands, honest trimmed tone metric, current bit-exact state (mask-apply chain), open gaps (PRNG/FFT-conv/exp2/SR-mismatch). - README.md: status moved to P4 (C++ FramedDetector canon, framed_test), historical B.1..B.15 numerical model demoted to <details>; structure/doc table updated. - roadmap.md: P4 phase marked progress, P4.1/P4.2/P4.3 milestones, top status refresh. - summary.md: marked historical (behavioral v4). - SESSION_HANDOFF.md: fixed stale "NOT DECODED" (now decoded), copy note done. - Removed empty tmp_spec.txt/giant3.txt and untracked .log/__pycache__ clutter.
This commit is contained in:
@@ -0,0 +1,93 @@
|
|||||||
|
# AGENTS.md — guide for AI agents working in this repo
|
||||||
|
|
||||||
|
Bit-exact реверс DSP-ядра oeksound soothe2 (VST3) → транскрипция на C++18 в `dsp/`.
|
||||||
|
Полное журналирование — в `handoff/NOTES_LEVEL.md`, `handoff/NOTES_TWIN.md`,
|
||||||
|
`handoff/NOTES_CAPTURE.md`, `roadmap.md`.
|
||||||
|
|
||||||
|
## Золотое правило (обязательно)
|
||||||
|
1. **Цель — bit-exact реверс кода**, НЕ эмпирическая подгонка кривых. Каждый параметр
|
||||||
|
должен иметь источник (decomp адрес / live-таблица), а не быть подогнанным числом.
|
||||||
|
Если берёшь эмпирику — явно пометь и занеси в «осталось».
|
||||||
|
2. Источник истины — **декомпиляция** (`decomp_funs.txt`, `decomp_funs2.txt`,
|
||||||
|
`handoff/nls_dasm/*.dis`) и **live-снимки** (`/tmp/snap_rt.bin`). Обновлять заметки
|
||||||
|
при любом новом декоде.
|
||||||
|
3. Команды через `rtk` (токен-фильтр), включая цепочки `&&`.
|
||||||
|
|
||||||
|
## Сборка и тесты (канон)
|
||||||
|
```bash
|
||||||
|
# собрать библиотеку + framed_test
|
||||||
|
cmake -S dsp -B dsp/build
|
||||||
|
cmake --build dsp/build --target framed_test
|
||||||
|
|
||||||
|
# рендер через каркас (N=2048, hop=512, SR 44100, sqrt-Hann OLA)
|
||||||
|
# формат полосы: 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
|
||||||
|
# многополосный: через отдельные аргументы fc q sens scale (см. framed_test.cpp)
|
||||||
|
|
||||||
|
# отдельные модули (bit-exact черные проверки)
|
||||||
|
cmake --build dsp/build --target twin_check tables_check fftconv_check vlog_check leveltrack_check levelpath_check
|
||||||
|
./dsp/build/twin_check # float-parity twin-резонатора
|
||||||
|
```
|
||||||
|
|
||||||
|
### Метрика (tone-cmp, Goertzel stead-state)
|
||||||
|
Сравнивать **тримкнутый** выход (длина = длина входа) с референсом `*_ref.wav` / `t1kq_b1f_*`:
|
||||||
|
```python
|
||||||
|
# ref: t1kq_b1f_678.7611083984375.wav (или t1kq_b1f_1000.wav и т.д. по fc полосы)
|
||||||
|
# вход: tone1kq.wav (тон 1000 Гц)
|
||||||
|
import wave, numpy as np
|
||||||
|
def load(p):
|
||||||
|
w=wave.open(p,'rb'); n=w.getnframes(); d=w.readframes(n)
|
||||||
|
return np.frombuffer(d,dtype=np.int16).astype(np.float64).reshape(-1,w.getnchannels()).mean(1)/32768
|
||||||
|
def ta(x,f,sr=44100):
|
||||||
|
x=x[-int(0.75*sr):]; t=np.arange(len(x))/sr; w=2*np.pi*f
|
||||||
|
return np.hypot(2*np.sum(x*np.cos(w*t))/len(x), 2*np.sum(x*np.sin(w*t))/len(x))
|
||||||
|
def db(a): return 20*np.log10(max(a,1e-9))
|
||||||
|
inp=load('/home/m/soothe-bt/tone1kq.wav')
|
||||||
|
out=load('/tmp/o.wav')
|
||||||
|
ref=load('/home/m/soothe-bt/t1kq_b1f_678.7611083984375.wav') # fc полосы = 678.76
|
||||||
|
err = db(ta(out,1000)/ta(ref,1000)) # err в dB, цель <0.1
|
||||||
|
```
|
||||||
|
Тестовый корпус (`/home/m/soothe-bt/`, вне git): `tone1kq.wav`(вход),
|
||||||
|
`t1kq_b1f_<fc>.wav` (рефы), `comb.wav`/`comb_ref.wav` (мультиполосный).
|
||||||
|
|
||||||
|
## Текущее состояние (2026-08-20, P4)
|
||||||
|
|
||||||
|
**Декодировано и транскрибировано в `dsp/framed_model.cpp`** (mask-apply цепь
|
||||||
|
`FUN_180529fe0`, mono-path 0x5408b8==0):
|
||||||
|
```
|
||||||
|
level=am*res*level_scale -> scale(0x540870*0x54088c/0x1a0)
|
||||||
|
-> IIR1 leaky(A1/B1) -> IIR2(A2/B2) -> mask=exp2(-mask)*blend (bigkernel 0x26b820)
|
||||||
|
-> combine/acc(0x5407c8) -> warp(mask*=0x540768, *=warp) -> IIR3(A3/B3)x2
|
||||||
|
-> dry/wet(mask*(fVar30*0x540888)+(1-fVar30)) -> [FFT-conv]
|
||||||
|
```
|
||||||
|
- **bigkernel 0x26b820 = векторизованный exp2** (log2e=1.4424, floor −708.9, N-таблицы);
|
||||||
|
семантика залочена: `mask = exp2(-level) * blend`, blend=0.8 при mix=1.0.
|
||||||
|
- **Level-tracker = би-направленный leaky-IIR** `y=A[i]*acc+B[i]*x`, B=1−A
|
||||||
|
(НЕ per-bin независимый трекер).
|
||||||
|
- **Live-таблицы** в `dsp/rt_mask_tables.{hpp,cpp}`: kIIR_A1/B1..A3/B3 (2049 doubles),
|
||||||
|
kWarp (8193), kBand768, kPRNGLut. `dsp/rt_weights.{hpp,cpp}` = acc коды весов.
|
||||||
|
- **Результаты**: t1kq err −0.43 dB (scale=600); comb per-tone err ≤6.4 dB.
|
||||||
|
|
||||||
|
### Открытые bit-exact пробелы (см. NOTES_LEVEL.md)
|
||||||
|
1. PRNG-пролог (LCG+LUT → fVar30), per-frame рандомизация scale/dry-wet.
|
||||||
|
2. FFT-conv (0x535a70) сглаживание маски перед FIR.
|
||||||
|
3. Бит-экзактный exp2 (0x26b820) вместо std::exp2.
|
||||||
|
4. combine/аккумулятор 0x5407c8 точная обратная связь.
|
||||||
|
5. **SR-mismatch**: внутренний DSP SR=48000/N=4096 (спейс 11.713 Гц) против
|
||||||
|
хоста 44100/2048; twin per-bin IIR статически невидим (FUN_180535880 tail-call).
|
||||||
|
|
||||||
|
## Структура ключевых файлов
|
||||||
|
- `dsp/framed_model.{cpp,hpp}` — C++ порт mask-apply цепи (ГЛАВНЫЙ активный файл).
|
||||||
|
- `dsp/framed_test.cpp` — CLI рендер входа (3010 метрика см. выше).
|
||||||
|
- `dsp/{twin,levelpath,freqpath,fftconv,vlog,leveltrack}.cpp` — расшифрованные модули.
|
||||||
|
- `dsp/rt_mask_tables.{hpp,cpp}`, `rt_weights.{hpp,cpp}` — live-таблицы.
|
||||||
|
- `handoff/NOTES_LEVEL.md` — полный журнал уровня/маски (самый актуальный).
|
||||||
|
- `handoff/nls_dasm/` — 134 дизассембла декомпа.
|
||||||
|
- `/tmp/consumers_out.txt` — полный decomp `FUN_180529fe0` (уникален, вне git).
|
||||||
|
- `/tmp/snap_rt.bin` — live-снимок (ctx 0x2370040, SR 48000).
|
||||||
|
|
||||||
|
## Чистая работа
|
||||||
|
- Не коммитить: `*.bin`(дампы 112М), `*.wav/rpp`, `*.log`, `dsp/build/`, `ghidra-proj/`,
|
||||||
|
`dl/lib/bin/include/`, `regions*/`. См. `.gitignore`.
|
||||||
|
- После правки C++ — собрать (`cmake --build dsp/build --target framed_test`) и обновить
|
||||||
|
`handoff/NOTES_LEVEL.md`. Fasta метрику держать честной (тримнутая длина).
|
||||||
@@ -9,27 +9,49 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Статус (B.15, август 2026)
|
## Статус (P4, 2026-08-20)
|
||||||
|
|
||||||
**Полный STFT-рендер** пайплайна работает в `framed_render.py` (N=2048, hop=512,
|
**Цель — bit-exact реверс.** Декомпиляция DSP-ядра закрыта (~95%): twin-резонатор,
|
||||||
sqrt-Hann, per-bin twin-envelope tatt=11ms/trel=80ms). Модель:
|
генератор case8, level-path, LUT-кривая (FUN_180563440/563a60), mask-apply
|
||||||
`C(f_k)=g·LUT(log10(A_k/res_k)) + w·warp(f_k)^a`, `gain=(1−C)·res^(rp0·Q^drp)`.
|
(FUN_180529fe0), FFT-conv — всё расшифровано; дизассемблы в `handoff/nls_dasm/`.
|
||||||
|
|
||||||
- **Честная (trimmed) метрика** — длина выхода = длина входа (не-тримнутые замеры
|
**Активный канон — C++ `FramedDetector`** (`dsp/framed_model.cpp`): точная mask-apply
|
||||||
давали ложный сдвиг ~0.2 dB, исправлено в B.14). Базлайн для scalar-rp = 0.280 dB.
|
цепь (не эмпирическая подгонка):
|
||||||
- **Q-dependent rp** `rp(Q)=rp0·Q^drp` (rp0=0.0275, drp=0.2159) → **mean=0.175 dB**:
|
```
|
||||||
q0.1 и q10 почти идеальны, боттлнек q1@2000 (−0.71 dB).
|
level=am*res*scale -> IIR1/IIR2 leaky -> mask=exp2(-mask)*blend -> combine/acc
|
||||||
- **JOINT free-knot LUT** (8 узлов Pchip, G/W/A/rp0/drp) → **dual mean≈0.027 dB**,
|
-> warp(mask*=0x540768, *=warp) -> IIR3x2 -> dry/wet -> FFT-conv
|
||||||
q1@2000 закрыт до 0.000; остаток al_* lv24 dC=+0.10 (зона xv<−0.3).
|
```
|
||||||
- **Декомп DSP-ядра в основном закрыт**: twin-резонатор, генератор case8, level-weight
|
- **bigkernel 0x26b820 = векторизованный exp2**; семантика залочена (`mask=exp2(-level)*blend`).
|
||||||
(0x530d30 — численно НЕ create tilt, подтверждено при N=2048), LUT-кривая FUN_180563440
|
- **Level-tracker = би-направленный leaky-IIR** `y=A[i]·acc+B[i]·x` (B=1−A), live-таблицы
|
||||||
(linear/power-law по флагу), IIR-трекеры FUN_180563ce0, FFT-conv 0x535a70 —
|
в `dsp/rt_mask_tables.{hpp,cpp}`, `dsp/rt_weights.{hpp,cpp}`.
|
||||||
всё размаплено, `.dis` в `handoff/nls_dasm/`.
|
- **Результаты**: t1kq err **−0.43 dB** (level_scale=600); comb per-tone err ≤6.4 dB.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Текущий канон (Q-dep rp, trimmed):
|
# Канон сборки и рендера:
|
||||||
python3 framed_render.py dual
|
cmake -S dsp -B dsp/build && cmake --build dsp/build --target framed_test
|
||||||
|
./dsp/build/framed_test /home/m/soothe-bt/tone1kq.wav /tmp/o.wav 678.7611083984375,0.99999785,12,600
|
||||||
```
|
```
|
||||||
|
Детальная метрика и история — в `AGENTS.md`, `roadmap.md`, `handoff/NOTES_LEVEL.md`.
|
||||||
|
|
||||||
|
### Открытые bit-exact пробелы
|
||||||
|
PRNG-пролог (LCG→fVar30), FFT-conv сглаживание, бит-экзактный exp2, точная обратная
|
||||||
|
связь combine/acc `0x5407c8`, и SR-mismatch (внутренний DSP 48000/N=4096 против
|
||||||
|
хоста 44100/2048). Полный список — в `AGENTS.md` и `NOTES_LEVEL.md`.
|
||||||
|
|
||||||
|
> Исторический блок (поведенческая/численная модель B.1…B.15, `framed_render.py`,
|
||||||
|
> Pchip LUT, res_power) — см. `roadmap.md`; самодостаточен как справочник, но не канон.
|
||||||
|
|
||||||
|
<details><summary>Было (B.15 — историческая численная модель)</summary>
|
||||||
|
|
||||||
|
`framed_render.py` (N=2048, hop=512, sqrt-Hann, twin-env tatt=11ms/trel=80ms):
|
||||||
|
`C(f_k)=g·LUT(log10(A_k/res_k)) + w·warp(f_k)^a`, `gain=(1−C)·res^(rp0·Q^drp)`.
|
||||||
|
- Честная (trimmed) метрика: Q-dep rp → mean 0.175 dB; B.15 joint free-knot LUT → dual 0.027 dB.
|
||||||
|
- Декомп DSP-ядра закрыт, `.dis` в `handoff/nls_dasm/`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 framed_render.py dual # (исторический канон B.15)
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -38,23 +60,29 @@ python3 framed_render.py dual
|
|||||||
```
|
```
|
||||||
re-tools/
|
re-tools/
|
||||||
├── README.md ← вы здесь
|
├── README.md ← вы здесь
|
||||||
├── roadmap.md ← журнал всех результатов/гипотез (B.1…B.15)
|
├── AGENTS.md ← гайд для агентов: сборка, метрика, bit-exact пробелы
|
||||||
├── framed_render.py ← КАНОНИЧЕСКИЙ frame-рендер (STFT+LUT+warp+res_power)
|
├── roadmap.md ← журнал всех результатов/гипотез (B.1…B.15, P4)
|
||||||
|
├── framed_render.py ← историческая численная модель (B.15, не канон)
|
||||||
├── render_parity.py ← dB-parity харнесс (Goertzel steady-state замер)
|
├── render_parity.py ← dB-parity харнесс (Goertzel steady-state замер)
|
||||||
├── model_lut.py, model_dual.py ← исторические модели B.10/B.11 (collapse-фиты)
|
├── model_lut.py, model_dual.py ← исторические модели B.10/B.11 (collapse-фиты)
|
||||||
├── model_fir.py ← bridge-модель B.12 (C=g·LUT+w·warp^a)
|
├── model_fir.py ← bridge-модель B.12 (C=g·LUT+w·warp^a)
|
||||||
│
|
│
|
||||||
├── handoff/ ← перекидка между сессиями
|
├── handoff/ ← журнал сессий
|
||||||
│ ├── SESSION_HANDOFF.md ← инвентарь декомпа, трансляция, Phase-5 план
|
│ ├── SESSION_HANDOFF.md ← инвентарь декомпа, трансляция, Phase-5 план
|
||||||
│ ├── NOTES_TWIN.md ← twin-резонатор + caller + grid
|
│ ├── NOTES_TWIN.md ← twin-резонатор + caller + grid
|
||||||
│ ├── NOTES_LEVEL.md ← level-path, LUT-нога, res_power протокол
|
│ ├── NOTES_LEVEL.md ← level-path, mask-цепь, live-таблицы (САМЫЙ АКТУАЛЬНЫЙ)
|
||||||
│ └── nls_dasm/ ← 120+ дизассемблей (f_563440, f_563ce0, f529fe0, twin…)
|
│ ├── NOTES_CAPTURE.md ← live-захват таблиц (registry heartbeat)
|
||||||
|
│ └── nls_dasm/ ← 134 дизассембла декомпа (f_563440, f_563a60, f529fe0, twin, fft…)
|
||||||
│
|
│
|
||||||
├── dsp/ ← реконструкция DSP-пайплайна на C++17
|
├── dsp/ ← реконструкция DSP-пайплайна на C++17
|
||||||
|
│ ├── framed_model{.cpp,.hpp} ← ГЛАВНЫЙ: mask-apply цепь (P4, активный канон)
|
||||||
|
│ ├── framed_test.cpp ← CLI рендер входа (N=2048, SR 44100) + метрика
|
||||||
|
│ ├── rt_mask_tables{.hpp,.cpp}, rt_weights{.hpp,.cpp} ← live-таблицы (IIR A/B, warp…)
|
||||||
│ ├── twin{.hpp,.cpp} ← бит-точный twin-резонатор (FUN_180535880)
|
│ ├── twin{.hpp,.cpp} ← бит-точный twin-резонатор (FUN_180535880)
|
||||||
|
│ ├── levelpath.cpp/.hpp ← LUT-кривая FUN_180563440/563a60 + combine-ядра
|
||||||
|
│ ├── freqpath.cpp/.hpp ← warp FUN_180530850 (0.87·x/(1+x/K))
|
||||||
|
│ ├── fftconv.cpp/.hpp ← FFT-conv (0x535a70)
|
||||||
│ ├── spectral.cpp/.hpp ← WOLA/STFT-обработчик
|
│ ├── spectral.cpp/.hpp ← WOLA/STFT-обработчик
|
||||||
│ ├── detect.cpp/.hpp ← детектор резонансов
|
|
||||||
│ ├── filter.cpp/.hpp ← биквад-фильтры
|
|
||||||
│ ├── fft*.cpp, twiddle_*.cpp/hpp, phase_table.* ← FFT-планы/твилдлы
|
│ ├── fft*.cpp, twiddle_*.cpp/hpp, phase_table.* ← FFT-планы/твилдлы
|
||||||
│ ├── ms.hpp ← encode/decode mid/side
|
│ ├── ms.hpp ← encode/decode mid/side
|
||||||
│ ├── cody_waite.hpp ← быстрый sin/cos (FUN_1801de760/1e3f20)
|
│ ├── cody_waite.hpp ← быстрый sin/cos (FUN_1801de760/1e3f20)
|
||||||
@@ -64,12 +92,12 @@ re-tools/
|
|||||||
│
|
│
|
||||||
├── *.java ← Ghidra-скрипты (analyzeHeadless, пост-скрипты)
|
├── *.java ← Ghidra-скрипты (analyzeHeadless, пост-скрипты)
|
||||||
├── ghidra-proj/ ← Ghidra-проект (soothe2.gpr/.rep), вне git
|
├── ghidra-proj/ ← Ghidra-проект (soothe2.gpr/.rep), вне git
|
||||||
├── soothe_mem.bin ← дамп памяти плагина (frida), вне git
|
├── soothe_mem.bin ← дамп памяти плагина, вне git
|
||||||
├── rwin_{A0,A1,B0,C0}.npy, r_freqaxis.npy ← живые таблицы (48k) из runtime-снимков
|
├── rwin_{A0,A1,B0,C0}.npy, r_freqaxis.npy ← живые таблицы (48k) из runtime-снимков
|
||||||
│
|
│
|
||||||
├── Измерение и фиты полосы: measure.py, probe.py, bandshape.py, fit_*.py,
|
├── Измерение и фиты полосы: measure.py, probe.py, bandshape.py, fit_*.py,
|
||||||
│ model_lut.py, notch.py
|
│ model_lut.py, notch.py (исторические, B-модели)
|
||||||
├── Поведенческие симуляторы: sim.py, sim_v5.py, verify_sim.py
|
├── Поведенческие симуляторы: sim.py, sim_v5.py, verify_sim.py (исторические)
|
||||||
├── Инструменты REAPER-рендеров: sweep.py, run_sweep.py, tt_sweep.py,
|
├── Инструменты REAPER-рендеров: sweep.py, run_sweep.py, tt_sweep.py,
|
||||||
│ patchparam.py, addfx.lua
|
│ patchparam.py, addfx.lua
|
||||||
├── Живая трассировка (yabridge-host + Frida): dump_soothe.py, rtall/rtscan/
|
├── Живая трассировка (yabridge-host + Frida): dump_soothe.py, rtall/rtscan/
|
||||||
@@ -81,13 +109,15 @@ re-tools/
|
|||||||
|
|
||||||
| Документ | Содержание |
|
| Документ | Содержание |
|
||||||
|---|---|
|
|---|---|
|
||||||
| [roadmap.md](roadmap.md) | Журнал всех результатов/гипотез (B.1…B.15), статус по фазам, риски, открытые вопросы |
|
| [AGENTS.md](AGENTS.md) | **Старт для агента**: сборка, метрика, bit-exact пробелы, структура |
|
||||||
|
| [roadmap.md](roadmap.md) | Журнал всех результатов/гипотез (B.1…B.15, P4), статус по фазам, риски |
|
||||||
| [handoff/SESSION_HANDOFF.md](handoff/SESSION_HANDOFF.md) | Инвентарь декомпа (§0), трансляция/ключевые адреса (§2), Phase-5 план (§6) |
|
| [handoff/SESSION_HANDOFF.md](handoff/SESSION_HANDOFF.md) | Инвентарь декомпа (§0), трансляция/ключевые адреса (§2), Phase-5 план (§6) |
|
||||||
|
| [handoff/NOTES_LEVEL.md](handoff/NOTES_LEVEL.md) | **Level-path/mask-цепь, live-таблицы, bit-exact протокол** (самый актуальный) |
|
||||||
| [handoff/NOTES_TWIN.md](handoff/NOTES_TWIN.md) | Twin-резонатор (FUN_180535880/536f90), caller, grid/oversample |
|
| [handoff/NOTES_TWIN.md](handoff/NOTES_TWIN.md) | Twin-резонатор (FUN_180535880/536f90), caller, grid/oversample |
|
||||||
| [handoff/NOTES_LEVEL.md](handoff/NOTES_LEVEL.md) | Level-path, LUT-нога, res_power протокол, спектральные веса |
|
| [handoff/NOTES_CAPTURE.md](handoff/NOTES_CAPTURE.md) | Live-захват таблиц (registry heartbeat, SR 48000) |
|
||||||
| [handoff/nls_dasm/](handoff/nls_dasm/) | 120+ дизассемблей (f_563440, f_563ce0, f529fe0, twin, iface, fft) |
|
| [handoff/nls_dasm/](handoff/nls_dasm/) | 134 дизассембла (f_563440, f_563a60, f529fe0, twin, iface, fft) |
|
||||||
| [notes_giant_fft.md](notes_giant_fft.md) | FFT-планировщики/ядра/twiddle/Cody-Waite |
|
| [notes_giant_fft.md](notes_giant_fft.md) | FFT-планировщики/ядра/twiddle/Cody-Waite |
|
||||||
| [summary.md](summary.md) | Сводка по реверсу и реконструкции |
|
| [summary.md](summary.md) | **Историческая** сводка поведенческой модели (v4, sim.py) |
|
||||||
|
|
||||||
### Тестовый корпус `/home/m/soothe-bt/` (вне git)
|
### Тестовый корпус `/home/m/soothe-bt/` (вне git)
|
||||||
|
|
||||||
@@ -103,10 +133,10 @@ re-tools/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Модель в трёх строках
|
## Историческая численная модель (B-фазы; канон теперь — C++ FramedDetector, см. выше)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# per-frame, per-bin (framed_render.py — канон)
|
# 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
|
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)
|
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)
|
gain = max(1 - C, eps) * res_k**rp # rp = rp0 * Q**drp (res_power)
|
||||||
@@ -117,8 +147,6 @@ gain = max(1 - C, eps) * res_k**rp # rp = rp0 * Q**drp (res_power)
|
|||||||
- rp(Q)=0.0275·Q^0.2159 (Q-dep rp, B.14);
|
- 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].
|
- B.15: G/W/A/rp0/drp = 0.9752/0.3394/1.0222/0.0254/0.2231; LUT KX=[−0.8..1.0].
|
||||||
|
|
||||||
Проверить: `python3 framed_render.py dual` (mean 0.175 для Q-dep rp).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Как всё это воспроизвести
|
## Как всё это воспроизвести
|
||||||
@@ -134,12 +162,14 @@ gain = max(1 - C, eps) * res_k**rp # rp = rp0 * Q**drp (res_power)
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Чего не хватает / следующие шаги
|
## Чего не хватает / следующие шаги (bit-exact)
|
||||||
|
|
||||||
- **Структурная LUT FUN_180563440** вместо Pchip: закрыть остаток al_* lv24 (dC≈+0.10,
|
Текущий фокус — C++ `FramedDetector` (`dsp/framed_model.cpp`). Открытое (см. AGENTS.md,
|
||||||
зона xv<−0.3) и q1@500 (+0.06).
|
NOTES_LEVEL.md §2026-08-20m):
|
||||||
- **Бит-точная сверка**: собрать `dsp/harness.cpp`, прогнать `burst500_b1.wav`
|
- **PRNG-пролог** FUN_180529fe0 (LCG+LUT → fVar30) — per-frame рандомизация scale/dry-wet.
|
||||||
и сверить байт-в-байт (сейчас модель — численная, rmse 0.03–0.18 dB).
|
- **FFT-conv** (0x535a70) — сглаживание маски перед FIR.
|
||||||
- C++ порт res_power + Q-dep rp + свободных LUT-узлов (тривиально: `gain *= pow(res, rp0·Q^drp)`).
|
- **Бит-экзактный exp2** (0x26b820) вместо `std::exp2`.
|
||||||
- Семантика IAT-хелперов `0x181a14xxx` (exp/log/pow) и AVX-ядер — целевые адреса вне дампа.
|
- Точная обратная связь combine/аккумулятора `0x5407c8`.
|
||||||
- Полный конвейер WOLA/oversample (offline 3×) и sidechain/стерео-путь.
|
- **SR-mismatch**: внутренний DSP 48000/N=4096 против хоста 44100/2048; twin per-bin IIR
|
||||||
|
(FUN_180535880 tail-call) статически невидим.
|
||||||
|
- Стерео-путь M8 (link/balance/LR-vs-MS), multiband combine 5316e0.
|
||||||
@@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
Prepared: 2026-08-18 (checkpoint end-of-session: commits c8f97e4 + 60bf3a2 pushed). Start: READ THIS FIRST.
|
Prepared: 2026-08-18 (checkpoint end-of-session: commits c8f97e4 + 60bf3a2 pushed). Start: READ THIS FIRST.
|
||||||
|
|
||||||
|
> **2026-08-20 UPDATE**: см. актуальный канон — `AGENTS.md` и `handoff/NOTES_LEVEL.md`.
|
||||||
|
> Нижеследующее «NOT DECODED»/«missing body» УСТАРЕЛО: `FUN_180529fe0` mono-path,
|
||||||
|
> `FUN_180563440/563ce0/563a60` — расшифрованы, полные дизассемблы скопированы в
|
||||||
|
> `handoff/nls_dasm/` (134 файла). Этот файл — исторический чекпоинт.
|
||||||
|
|
||||||
## 0. DECOMPILATION INVENTORY (2026-08-19 — what's decoded, where, and what's missing)
|
## 0. DECOMPILATION INVENTORY (2026-08-19 — what's decoded, where, and what's missing)
|
||||||
Goal: bit-exact parity is gated by EXACT tables/window/constants. The chunk-level model hits
|
Goal: bit-exact parity is gated by EXACT tables/window/constants. The chunk-level model hits
|
||||||
err ≤0.62 dB (dual) / ≤0.19 dB (al_*) — to go sample-exact we need precise values from the binary.
|
err ≤0.62 dB (dual) / ≤0.19 dB (al_*) — to go sample-exact we need precise values from the binary.
|
||||||
@@ -27,14 +32,11 @@ DECODED (formula-level, notes at NOTES_TWIN.md / NOTES_LEVEL.md):
|
|||||||
- level-path map: `0x563440` (LUT curve +0x188, 6 band-slots, combine→+0x2198), `0x56e3e0` (twin-mask factory),
|
- level-path map: `0x563440` (LUT curve +0x188, 6 band-slots, combine→+0x2198), `0x56e3e0` (twin-mask factory),
|
||||||
`0x563ce0` (IIR level-tracker INIT only).
|
`0x563ce0` (IIR level-tracker INIT only).
|
||||||
|
|
||||||
NOT DECODED / MISSING FROM decomp_funs.txt (critical):
|
NOT DECODED / MISSING FROM decomp_funs.txt (critical): ⚠️ → РЕШЕНО (2026-08-19/20), см. выше
|
||||||
- `FUN_180529fe0` body — mask/fir apply; only reachable via runtime + vtable slot `180529fe0` in fun_map.txt.
|
- `FUN_180529fe0` body — РЕШЕНО (decomp в `/tmp/consumers_out.txt`, mask-цепь в `dsp/framed_model.cpp`).
|
||||||
- `FUN_180563440` (LUT curve + gamma + combine), `FUN_180563ce0` (IIR level-tracker UPDATE loop).
|
- `FUN_180563440` / `FUN_180563a60` (LUT curve + gamma + combine), `FUN_180563ce0` — РЕШЕНО,
|
||||||
Full disasms exist ONLY in `/tmp/opencode/f_563440.dis`, `f_563ce0.dis`, `f529fe0.dis` — **/tmp is
|
дизассемблы скопированы в `handoff/nls_dasm/` (`f_563440.dis`, `f_563a60.dis`, `f_563ce0.dis`, `f529fe0.dis`).
|
||||||
ephemeral; COPY INTO handoff/nls_dasm/ on next session start.**
|
- Window `0x540658` — РЕШЕНО (live-захват, см. `handoff/NOTES_CAPTURE.md`; `rtwin_freq_44100.npy`).
|
||||||
- Window `0x540658` (single indirect write — statically invisible); live-captured copies saved as
|
|
||||||
`rwin_A0/A1/B0/C0.npy` + `r_freqaxis.npy` (see NOTES_LEVEL.md §2026-08-18h3). Live data at SR=48000
|
|
||||||
(offline renders 44100 → renormalize warp x by actual Nyquist).
|
|
||||||
- sens source: XML 12.0 → runtime sens_dB≈24.65 (host ×2) not found in dump; `IAT\*0x181bab370` outside dump.
|
- sens source: XML 12.0 → runtime sens_dB≈24.65 (host ×2) not found in dump; `IAT\*0x181bab370` outside dump.
|
||||||
|
|
||||||
### Bridge model STATUS (2026-08-19):
|
### Bridge model STATUS (2026-08-19):
|
||||||
|
|||||||
+22
-22
@@ -10,29 +10,25 @@
|
|||||||
(WAV16 → рендер → WAV24), `dsp_notes.md` (карта функция↔смысл, константы, LUT),
|
(WAV16 → рендер → WAV24), `dsp_notes.md` (карта функция↔смысл, константы, LUT),
|
||||||
`verify_bit_exact.py` (прогон всех свипов, побайтовое сравнение).
|
`verify_bit_exact.py` (прогон всех свипов, побайтовое сравнение).
|
||||||
|
|
||||||
## Текущий статус (2026-08-19)
|
## Текущий статус (2026-08-20, P4)
|
||||||
|
|
||||||
- **Статический декомп DSP-ядра — закрыт (~95%)**: twin-резонатор, генератор case8,
|
- **Статический декомп DSP-ядра — закрыт (~95%)**: twin-резонатор, генератор case8,
|
||||||
level-path (0x530d30/0x529fe0), LUT-кривая (FUN_180563440), IIR-трекеры (FUN_180563ce0),
|
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/`.
|
||||||
Остаток — runtime-значения (коэффициенты IIR level-tracker 0x4c0528/0x3c0510/0x2c04f8,
|
- **Канон — C++ `FramedDetector`** (`dsp/framed_model.cpp`), реальная mask-цепь отвоевана от
|
||||||
скаляры 0x540870/874/87c/888/88c из RPP, цель P1.5 live-capture).
|
эмпирики: `level→scale→IIR1/2 leaky→exp2(-mask)·blend→combine/acc→dual-warp→IIR3×2→dry/wet→FFT-conv`.
|
||||||
- **Численная модель = frame-рендер `framed_render.py`** (STFT N=2048, hop=512, sqrt-Hann,
|
Live-таблицы в `dsp/rt_mask_tables.{hpp,cpp}`, `rt_weights.{hpp,cpp}`.
|
||||||
twin-env tatt=11ms/trel=80ms): `C(f)=G·LUT(xv)+W·warp(f)^A`, `gain=(1−C)·res^(rp0·Q^drp)`.
|
- **Результаты**: t1kq err **−0.43 dB** (level_scale=600); comb per-tone err ≤6.4 dB.
|
||||||
- **Честная тримнутая метрика** (длина выхода = длина входа): Q-dep rp → **mean=0.175 dB**
|
- **Честная тримнутая метрика** (длина выхода = длина входа) — см. AGENTS.md.
|
||||||
(q0.1/q10 идеальны, боттлнек q1@2000=−0.71); joint free-knot LUT (B.15) → **dual mean≈0.027 dB**.
|
|
||||||
- **Цель bit-exact (Phase C) — в работе**: twin-транскрипция в `dsp/` готова и проходит
|
- **Цель bit-exact (Phase C) — в работе**: twin-транскрипция в `dsp/` готова и проходит
|
||||||
float-parity (1.27e-5); **живые таблицы встроены** (P1.1, tables_check ALL OK);
|
- **Бит-экзактная C++ транскрипция (Phase C)**: twin (float-parity 1.27e-5, tables_check ALL OK),
|
||||||
**FFT-conv расшифрован** (P1.2: f_52d990 = memcpy, N=4096) и **интегрирован** (P1.3 fftconv.cpp);
|
FFT-conv (P1.2/P1.3 fftconv.cpp), маска-канон (P1.4/P2), level-tracker (P2, leveltrack.cpp),
|
||||||
**маска-канон подтверждена** (P1.4, FUN_180529fe0) и **level-tracker UPDATE реализован** (P2,
|
LUT (P2.5 levelpath.cpp), mask-apply цепь (P4 framed_model.cpp) — в основном готово.
|
||||||
leveltrack.cpp). Остаток кода: twin-mask factory (FUN_18056e3e0), mask-accumulator 0x5407c8,
|
|
||||||
render-loop 52e260, бит-экзактная base-CRT FFT, стерео M8, multiband combine 5316e0,
|
|
||||||
+ live-коэффициенты (P1.5). res_power/Q-dep-rp порт в C++ — ещё TODO.
|
|
||||||
- **ВАЖНО про метрику**: ранние записи "mean=0.160/0.144" считались на выходе НЕтримнутой
|
- **ВАЖНО про метрику**: ранние записи "mean=0.160/0.144" считались на выходе НЕтримнутой
|
||||||
длины (`nfr*HOP+N`) и были артефактом; честный базлайн для scalar `rp=0.0169` = **0.280**.
|
длины (`nfr*HOP+N`) и были артефактом; честный базлайн для scalar `rp=0.0169` = **0.280**.
|
||||||
Все числа в этом файле — на ТРИМНУТОЙ метрике.
|
Все числа в этом файле — на ТРИМНУТОЙ метрике.
|
||||||
|
|
||||||
## Модель в двух строках
|
## Историческая численная модель (B-фазы; канон теперь — C++ FramedDetector)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
xv = log10(A_k / res_k) # A_k = 2|X_k|/wsum (twin-env), res = |2B/A| case8
|
xv = log10(A_k / res_k) # A_k = 2|X_k|/wsum (twin-env), res = |2B/A| case8
|
||||||
@@ -42,8 +38,8 @@ gain = max(1 - C, eps) * res_k**rp # rp = rp0 * Q**drp (res_power)
|
|||||||
|
|
||||||
- LUT — Pchip; warp — `0.87·7.942·x/(7.942+x)`, x=f/2000 (аппроксимация runtime-вычисления FUN_180563440);
|
- LUT — Pchip; warp — `0.87·7.942·x/(7.942+x)`, x=f/2000 (аппроксимация runtime-вычисления FUN_180563440);
|
||||||
- Q-dep rp: `rp0=0.0275, drp=0.2159` (mean 0.175); B.15 joint-free-knot LUT: G/W/A/rp0/drp =
|
- Q-dep rp: `rp0=0.0275, drp=0.2159` (mean 0.175); B.15 joint-free-knot LUT: G/W/A/rp0/drp =
|
||||||
`0.9752/0.3394/1.0222/0.0254/0.2231` (dual mean 0.027).
|
`0.9752/0.3394/1.0222/0.0254/0.2231` (dual mean 0.027);
|
||||||
- Запуск канона: `python3 framed_render.py dual`.
|
- Запуск (историч.): `python3 framed_render.py dual`.
|
||||||
|
|
||||||
## Статус по фазам
|
## Статус по фазам
|
||||||
|
|
||||||
@@ -74,13 +70,14 @@ 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 | TODO (структура известна, компоненты готовы) |
|
| 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 |
|
||||||
| 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): структурно ~65-70% готово — все level-path компоненты
|
Обновлённая оценка (2026-08-20): структурно ~75% готово — mask-apply цепь FUN_180529fe0
|
||||||
(LUT 563440, twin-mask 56e3e0, band LUT 563a60, combine, level-tracker, FFT-conv, vlog)
|
полностью декодирована (scale→IIR1/2→exp2→combine→warp→IIR3→dry/wet→FFT-conv) и перенесена
|
||||||
транскрибированы и проверены *_check. Осталось: (а) полная бит-экзактная FFT (butterfly+shuffle+
|
в C++, live-таблицы (IIR A/B, warp, band768, PRNG LUT) извлечены. Осталось: (а) полная
|
||||||
plan-gen — недели), (б) сборка единого pipeline P4 (render-loop + связка), (в) стерео M8 (P5).
|
бит-экзактная FFT (butterfly+shuffle+plan-gen — недели), (б) PRNG-пролог + FFT-conv +
|
||||||
|
бит-экзактный exp2 для bit-exact калибровки, (в) стерео M8 (P5).
|
||||||
|
|
||||||
## Ключевые находки (итог)
|
## Ключевые находки (итог)
|
||||||
|
|
||||||
@@ -150,6 +147,9 @@ gain = max(1 - C, eps) * res_k**rp # rp = rp0 * Q**drp (res_power)
|
|||||||
| B.13 | 08-19 | res_power `gain=(1−C)·res^rp` (500Hz resid решён); декомп 563440/563ce0/529fe0; константы из дампа |
|
| B.13 | 08-19 | res_power `gain=(1−C)·res^rp` (500Hz resid решён); декомп 563440/563ce0/529fe0; константы из дампа |
|
||||||
| B.14 | 08-19 | **Артефакт-коррекция** (честная тримнутая метрика; базлайн scalar=0.280); Q-dep rp → mean 0.175; 530d30 повторно NEGATIVE (N=2048) |
|
| B.14 | 08-19 | **Артефакт-коррекция** (честная тримнутая метрика; базлайн scalar=0.280); Q-dep rp → mean 0.175; 530d30 повторно NEGATIVE (N=2048) |
|
||||||
| B.15 | 08-19 | Диагноз LUT-немонотонности → joint free-knot LUT (8 узлов, dual+al_*) → **dual mean≈0.027 dB**; остаток al_* lv24 dC=+0.10 |
|
| B.15 | 08-19 | Диагноз LUT-немонотонности → joint free-knot LUT (8 узлов, dual+al_*) → **dual mean≈0.027 dB**; остаток al_* lv24 dC=+0.10 |
|
||||||
|
| P4.1 | 08-20 | Полный декомп mono-path FUN_180529fe0; real mask-цепь в C++ (IIR leaky + acc + live LUT); t1kq err 0.5 dB; `framed_test` |
|
||||||
|
| P4.2 | 08-20 | Live-таблицы извлечены (`rt_mask_tables` IIR A/B, warp, band768, PRNG LUT); bigkernel 0x26b820=exp2 семантика залочена (`exp2(-mask)·blend`) |
|
||||||
|
| P4.3 | 08-20 | Dual-warp шаг 6 транскрибирован (mask·=band768, ·=warp) → comb 500/3000 починены; t1kq −0.43 dB; comb ≤6.4 dB |
|
||||||
|
|
||||||
## Риски
|
## Риски
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
## Objective
|
## Objective
|
||||||
- Реверс-DSP oeksound soothe2 v1.1.2 VST3 → математическая модель (STFT, детектор резонансов, нотич-синтез). Текущая фаза — поведенческий параметр-свип через рендер Reaper RPP + статический декомпил (без декрипты бинарника пока).
|
- Реверс-DSP oeksound soothe2 v1.1.2 VST3 → математическая модель (STFT, детектор резонансов, нотич-синтез). Текущая фаза — поведенческий параметр-свип через рендер Reaper RPP + статический декомпил (без декрипты бинарника пока).
|
||||||
|
|
||||||
|
> **⚠️ ИСТОРИЧЕСКИЙ ДОКУМЕНТ (поведенческая модель v4, sim.py, ок. 2026-08-17)**.
|
||||||
|
> Актуальный канон (bit-exact, P4) — `README.md`, `AGENTS.md`, `handoff/NOTES_LEVEL.md`.
|
||||||
|
> Здесь — ранняя поведенческая фаза реверса, сохранена как справочник.
|
||||||
|
|
||||||
## Key Facts
|
## Key Facts
|
||||||
- Пользователь русскоязычный; sudo нет. Объект: `~/.wine/.../soothe2_x64.vst3` (PE32+, base 0x180000000), yabridge 5.1.1, Reaper 7.78.
|
- Пользователь русскоязычный; sudo нет. Объект: `~/.wine/.../soothe2_x64.vst3` (PE32+, base 0x180000000), yabridge 5.1.1, Reaper 7.78.
|
||||||
- Frida невозможна (Seccomp). Дамп памяти — `pread /proc/pid/mem` от родителя. pkill-ловушки: paths без `harneb`/`reaper` → `pkill -9 -x reaper`, `pkill -9 -f '[y]abridge'`.
|
- Frida невозможна (Seccomp). Дамп памяти — `pread /proc/pid/mem` от родителя. pkill-ловушки: paths без `harneb`/`reaper` → `pkill -9 -x reaper`, `pkill -9 -f '[y]abridge'`.
|
||||||
|
|||||||
Reference in New Issue
Block a user