Matiq 803c100091 k-mapping opt-in RT_KMAP, keep canon 0.732
- k(sens,q) fitted from 24x table: sens 6->0.44 12->1.0 24->22, q 0.5->1.0 2.0->0.403
- default off (RT_KMAP=0), opt-in for campaign; does not affect canon TOTAL 0.732
- next: campaign sens/q series for precise fit, Δ STATE-dependent
2026-08-29 10:36:41 +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.


Статус (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).
# Сборка и канонные команды (см. 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 Runbook: сборка, метрика, env-флаги, tooling hazard
BITEXACT_PLAN.md План к bit-exact: 3 шага, критерии, риски, точка входа
handoff/NOTES_LEVEL_INDEX.md Оглавление журнала по датам/темам → NOTES_LEVEL.md / archive/
handoff/NOTES_LEVEL.md Живой журнал (голова 24mm5+; хвост → archive/)
handoff/BLOCKMAP_529fe0.md Карта метода FUN_180529fe0 (актуальна)
handoff/nls_dasm/ 134 дизассембла декомпа
roadmap.md Журнал B-фаз (свёрнут, детали → archive)
handoff/NOTES_TWIN.md Twin краткая справка (детали → dsp/twin.cpp)
handoff/NOTES_CAPTURE.md Registry heartbeat, live-таблицы (сжато)
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, см. выше)

# 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) → BITEXACT_PLAN.md

  1. Каскадный симулятор шагов 9–19 (приоритет №1) — см. BITEXACT_PLAN.md:1.
  2. k-маппинг фронтенда twin/am (приоритет №2).
  3. Δ-правило вторых пиков (приоритет №3).
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%