Matiq cea562b511 P4: F0 GATE PASSED — output is byte-deterministic; re-renders reproduce committed refs exactly
Two test RPPs (res_only1_500 4s, t1kq_only1_1000 6s) rendered twice each via
reaper -nosplash CLI. Data chunks identical across runs AND byte-identical to the
committed reference wavs. Whole-file differs only in the bext render-timestamp.
=> bit-exact (bytes) is REACHABLE; the per-run-dithrandization blocker is closed.
Next: exact structural chain + kernels + internal 48000/4096 geometry + live A/B/gamma.
2026-08-20 20:03:58 +03:00

soothe2-re

Обратный инжиниринг DSP-ядра oeksound soothe2 (VST3, Windows x64) → проверяемая реконструкция на C++ с bit-exact целью.

Цель — понять, как именно плагин считает подавление резонансов (уровневый детектор, маска, фильтр), и воспроизвести это дословно. Текущий активный канон — C++ FramedDetector (dsp/framed_model.cpp): real mask-apply цепь с live-таблицами. Канонные команды и метрика — в AGENTS.md.


Статус (P4, 2026-08-20)

Цель — bit-exact реверс. Декомпиляция DSP-ядра закрыта (~95%): twin-резонатор, генератор case8, level-path, LUT-кривая (FUN_180563440/563a60), mask-apply (FUN_180529fe0), FFT-conv — всё расшифровано; дизассемблы в handoff/nls_dasm/.

Активный канон — C++ FramedDetector (dsp/framed_model.cpp): точная mask-apply цепь (не эмпирическая подгонка):

level=am*res*scale -> IIR1/IIR2 leaky -> mask=exp2(-mask)*blend -> combine/acc
-> warp(mask*=0x540768, *=warp) -> IIR3x2 -> dry/wet -> FFT-conv
  • bigkernel 0x26b820 = векторизованный exp2; семантика залочена (mask=exp2(-level)*blend).
  • Level-tracker = би-направленный leaky-IIR y=A[i]·acc+B[i]·x (B=1A), live-таблицы в dsp/rt_mask_tables.{hpp,cpp}, dsp/rt_weights.{hpp,cpp}.
  • Результаты: t1kq err 0.43 dB (level_scale=600); comb per-tone err ≤6.4 dB.
# Канон сборки и рендера:
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; самодостаточен как справочник, но не канон.

Было (B.15 — историческая численная модель)

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=(1C)·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/.
python3 framed_render.py dual   # (исторический канон B.15)

Структура репозитория

re-tools/
├── README.md                 ← вы здесь
├── AGENTS.md                 ← гайд для агентов: сборка, метрика, bit-exact пробелы
├── roadmap.md                ← журнал всех результатов/гипотез (B.1…B.15, P4)
├── framed_render.py          ← историческая численная модель (B.15, не канон)
├── render_parity.py          ← dB-parity харнесс (Goertzel steady-state замер)
├── model_lut.py, model_dual.py ← исторические модели B.10/B.11 (collapse-фиты)
├── model_fir.py              ← bridge-модель B.12 (C=g·LUT+w·warp^a)
│
├── handoff/                  ← журнал сессий
│   ├── SESSION_HANDOFF.md    ← инвентарь декомпа, трансляция, Phase-5 план
│   ├── NOTES_TWIN.md         ← twin-резонатор + caller + grid
│   ├── NOTES_LEVEL.md        ← level-path, mask-цепь, live-таблицы (САМЫЙ АКТУАЛЬНЫЙ)
│   ├── NOTES_CAPTURE.md      ← live-захват таблиц (registry heartbeat)
│   └── nls_dasm/             ← 134 дизассембла декомпа (f_563440, f_563a60, f529fe0, twin, fft…)
│
├── 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)
│   ├── 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-обработчик
│   ├── fft*.cpp, twiddle_*.cpp/hpp, phase_table.*  ← FFT-планы/твилдлы
│   ├── ms.hpp                ← encode/decode mid/side
│   ├── cody_waite.hpp        ← быстрый sin/cos (FUN_1801de760/1e3f20)
│   ├── soothe_constants.hpp  ← константы из дампа
│   ├── harness.cpp           ← CLI: input.wav → output.wav (24-bit)
│   └── CMakeLists.txt
│
├── *.java                    ← Ghidra-скрипты (analyzeHeadless, пост-скрипты)
├── ghidra-proj/              ← Ghidra-проект (soothe2.gpr/.rep), вне git
├── soothe_mem.bin            ← дамп памяти плагина, вне git
├── rwin_{A0,A1,B0,C0}.npy, r_freqaxis.npy ← живые таблицы (48k) из runtime-снимков
│
├── Измерение и фиты полосы: measure.py, probe.py, bandshape.py, fit_*.py,
│   model_lut.py, notch.py                        (исторические, B-модели)
├── Поведенческие симуляторы: sim.py, sim_v5.py, verify_sim.py   (исторические)
├── Инструменты REAPER-рендеров: sweep.py, run_sweep.py, tt_sweep.py,
│   patchparam.py, addfx.lua
├── Живая трассировка (yabridge-host + Frida): dump_soothe.py, rtall/rtscan/
│   rtsig/rttbl/rtver/rtone/rtwin/rtdeep*.py, probe.py, procdump.py
└── summary.md, notes_giant_fft.md

Документация

Документ Содержание
AGENTS.md Старт для агента: сборка, метрика, bit-exact пробелы, структура
roadmap.md Журнал всех результатов/гипотез (B.1…B.15, P4), статус по фазам, риски
handoff/SESSION_HANDOFF.md Инвентарь декомпа (§0), трансляция/ключевые адреса (§2), Phase-5 план (§6)
handoff/NOTES_LEVEL.md Level-path/mask-цепь, live-таблицы, bit-exact протокол (самый актуальный)
handoff/NOTES_TWIN.md Twin-резонатор (FUN_180535880/536f90), caller, grid/oversample
handoff/NOTES_CAPTURE.md Live-захват таблиц (registry heartbeat, SR 48000)
handoff/nls_dasm/ 134 дизассембла (f_563440, f_563a60, f529fe0, twin, iface, fft)
notes_giant_fft.md FFT-планировщики/ядра/twiddle/Cody-Waite
summary.md Историческая сводка поведенческой модели (v4, sim.py)

Тестовый корпус /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, см. выше)

# 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.pysoothe_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)

Текущий фокус — C++ FramedDetector (dsp/framed_model.cpp). Открытое (см. AGENTS.md, NOTES_LEVEL.md §2026-08-20m):

  • PRNG-пролог FUN_180529fe0 (LCG+LUT → fVar30) — per-frame рандомизация scale/dry-wet.
  • FFT-conv (0x535a70) — сглаживание маски перед FIR.
  • Бит-экзактный exp2 (0x26b820) вместо std::exp2.
  • Точная обратная связь combine/аккумулятора 0x5407c8.
  • 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.
S
Description
Reverse engineering of oeksound soothe2 VST3 DSP core → bit-exact buildable C++
Readme
12 MiB
Languages
C++ 59.3%
Python 36.7%
Java 3.7%
Lua 0.2%
CMake 0.1%