# G2 — JUCE VST3 hosting + latency thật (FxLatReport) Trạng thái: **DONE** — đã verify qua probe, build pass. ## Thay đổi - `native_bridge/juce_fx/JuceFxEngine.cpp` — `setChain(chainJson)`: parse mảng fx_chain (`sheredom_json.h`), load VST3 qua `juce::VST3PluginFormat::findAllTypesForFile` + `createInstanceFromDescription`; preset_b64 → `setStateFromVSTPresetFile` (deprecated, vẫn dùng được); nối node nối tiếp in→p0→…→out; sau `prepareToPlay`: `slotLatencies[i] = getLatencySamples()` từng plugin, `totalLatency = graph.getLatencySamples()`. `entryLatencies()` trả `std::vector` theo thứ tự slot (skip/bypass/fail = 0). - `JuceFxEngine.h` — khai báo `struct Slot;` + `setChain`/`entryLatencies`. - `JuceFxLoop.cpp` — đọc `chainJson` từ job, gọi `engine.setChain` trước prepare; `reportLatencies` báo từng slot qua FxLatReport (giữ giao thức cũ). - `juce_fx/CMakeLists.txt` — bật `JUCE_PLUGINHOST_VST3=1` (JUCE mặc định 0 → class VST3PluginFormat bị ẩn, gây C3861/C2039). - `src-tauri/binaries/juce_fx_bridge-x86_64-pc-windows-msvc.exe` — build mới (G2). ## Verify (debug/g0_latency_probe.py, exe mới) | config | plugin_latency | drained | recv/sent | roundtrip mean | |---|---|---|---|---| | empty chain | `{}` | True | 10000/10000 | 21.57 ms | | pureComp | `{0: 2108}` | True | 10000/10000 | 21.70 ms | | Ozone 11 | `{0: 0}` | True | 10000/10000 | 21.69 ms | - Latency thật đúng dự đoán: pureComp ~2108 samples @48k, Ozone 11 không delay. - Không crackle, drained=True, recv=sent — benchmark G1 giữ nguyên. ## Ghi chú - `setStateFromVSTPresetFile` là API deprecated nhưng public (bên trong `#ifndef DOXYGEN`), compile được với `JUCE_PLUGINHOST_VST3=1`. - Bỏ hằng `(7+8)*256` trong `fxRtApplyPdc` (app.jsx) là việc của G3 (dùng latencyTotal thật từ WS — hiện `FX_RT_ROUNDTRIP_SAMPLES=3840` là ước lượng RTT pipeline, ponytail).