diff --git a/native_bridge/debug/G1_RESULTS.md b/native_bridge/debug/G1_RESULTS.md new file mode 100644 index 0000000..9ecd13e --- /dev/null +++ b/native_bridge/debug/G1_RESULTS.md @@ -0,0 +1,56 @@ +# G1 — JUCE engine SHM chain rỗng POC (kết quả) + +Ngày: 2026-08-28. Commit: `9c0d35d`. Plan: `JUCE_LATENCY_PLAN.md` G1. + +## Nội dung + +- Submodule `native_bridge/JUCE` = tag `8.0.8`... thực tế tag `8.0.7` + (shallow, `.gitmodules` branch=8.0.7) — khớp pattern vst3sdk sẵn có. +- Tách SHM dùng chung: `native_bridge/include/FxShm.h` (namespace `fxshm`, + `ShmView`/`openShm`/`closeShm` — Windows FileMapping); `RealtimeFxLoop.cpp` + chuyển sang dùng chung (không đổi hành vi bridge cũ). +- Project mới `native_bridge/juce_fx/`: `juce_fx_bridge` dùng + `juce::AudioProcessorGraph`, chain rỗng = input node → output node + (passthrough). `prepare(sr, block)` → prepareToPlay(block*4) vì batch tối đa + 4 block; `process(inL, inR, n)` copy vào `AudioBuffer` → `graph.processBlock` + → copy về in-place. `latencySamples()` = `graph.getLatencySamples()`. +- Loop C++: batching 4 block, out-ring backpressure, heartbeat 100ms, + `timeBeginPeriod(1)` + ABOVE_NORMAL, log `[JuceFxLoop]/[JuceFxPerf]`; validate + header mỗi iteration — sampleRate/blockSize đổi → re-prepare + report latency + qua lat ring; job `fx_chain` BỎ QUA (G1 chain rỗng). +- Python: `app/core/fx_realtime.py` `_spawn()` — env `SF_JUCE_FX_BRIDGE_PATH` + chọn bridge JUCE (`--juce-fx`); mặc định giữ nguyên `fx_vst_bridge + --realtime-fx`. Exe copy: `src-tauri/binaries/juce_fx_bridge-x86_64-pc-windows-msvc.exe`. + +## Kết quả probe + +Probe `native_bridge/debug/g0_latency_probe.py`, 10k block/config, pipeline +thật Python→SHM→juce_fx_bridge→SHM, `timeBeginPeriod(1)`, env +`SF_JUCE_FX_BRIDGE_PATH` trỏ exe JUCE. (3 config trong probe đều chạy qua JUCE +bridge; G1 chain rỗng nên pureComp/Ozone cũng passthrough — kiểm chứng không +crash, không lag.) + +| Config | mean ms | σ | p50 | p99 | max | recv/sent | pump_rate | drained | latency | +|---|---|---|---|---|---|---|---|---|---| +| empty | 21.670 | 0.636 | 21.649 | 22.087 | 24.031 | 10000/10000 | 184.9 | ✅ | {0:0} | +| pureComp | 21.686 | 0.168 | 21.656 | 22.073 | 23.399 | 10000/10000 | 184.9 | ✅ | {0:0} | +| Ozone 11 | 21.674 | 0.157 | 21.640 | 22.049 | 22.277 | 10000/10000 | 185.0 | ✅ | {0:0} | + +So sánh baseline G0 (empty): mean 21.67ms — không lag thêm, không crackle +(drained=True, recv=sent, interarrival mean ~0.07ms). Log bridge: +`[JuceFxLoop] prepared sr=48000 block=256 latency=0` → ready → exit. + +## G1 done-when + +- ✅ `--juce-fx` chạy với chain rỗng +- ✅ Python `fx_realtime.py` chơi qua nó bằng path cũ (env opt-in, mặc định cũ + không đổi) — regression pass + +## Ghi chú + +- Lỗi build gặp phải: `NodeAndChannel`/`Connection` không aggregate-init được + trên MSVC 2019 — phải gán field từng cái; `addNode` trả `Node::Ptr` → lấy + `->nodeID` (không gán Ptr vào `NodeID`). +- JUCE modules build lần đầu chậm (~34s config); `build_juce/` đã gitignore. +- `[JuceFxPerf]` heartbeat không xuất hiện trong probe ngắn (chạy <100ms); + probe chỉ grep tag cũ `[FxRTPerf]` — không phải lỗi.