docs: plan JUCE - phan bien V2: xoa risk buffer toan track (Option B leftover), param queue lock-free SPSC, validate sampleRate/blockSize doi giua chung

This commit is contained in:
2026-08-28 11:49:54 +07:00
parent a10f679c0d
commit ebe17d902b
+2 -2
View File
@@ -73,6 +73,7 @@ Giữ nguyên SHM `FxRealtimeIPC` làm ranh giới (không đổi Python/JS tran
- [ ] Dựng project `native_bridge/juce_fx/` (CMake + JUCE via vcpkg hoặc submodule `JUCE/`).
- [ ] `JuceFxEngine`: mở SHM `FxRealtimeIPC` (reuse openShm/closeShm từ RealtimeFxLoop), audio thread đọc in ring → graph (rỗng) → ghi out ring. Heartbeat 100ms giữ nguyên.
- [ ] job.json format giữ nguyên `{sample_rate, block_size, fx_chain}`.
- [ ] Validate header mỗi iteration: `sampleRate`/`blockSize` đổi giữa chừng (đổi thiết bị audio / session mới khác rate) → teardown graph + `prepareToPlay(rate, block)` lại + report latency mới qua FxLatReport. (WebAudio `AudioContext.sampleRate` bất biến — browser resample khi đổi thiết bị; check này phòng header bị ghi lại.)
- Done khi: `--juce-fx` chạy với chain rỗng, Python `fx_realtime.py` chơi qua nó nghe bằng path cũ (regression: không crackle, không lag thêm).
### G2 — VST3 hosting trong graph + latency thật
@@ -102,12 +103,11 @@ Giữ nguyên SHM `FxRealtimeIPC` làm ranh giới (không đổi Python/JS tran
| Rủi ro | Giảm thiểu |
|---|---|
| JUCE VST3 host khác hành vi VST3 SDK host hiện tại (preset/GUI) | Giữ SandboxVst3Host cho GUI/editor; engine JUCE chỉ xử lí audio path; verify preset_b64 load giống |
| Tăng latency thêm 1 buffer nội bộ (G3 buffer toàn track) | Buffer vòng 2 pass loop + pre-roll; đo lại FILL |
| vcpkg JUCE nặng (build time) | Build riêng `juce_fx` target, không đụng main bridge; giữ main bridge deploy ổn định |
| AudioProcessorGraph PDC delay lớn → playhead lệch nếu chain đổi giữa play | Rebuild graph khi chain đổi (stop/play như cũ); báo latency mới qua SHM |
| WS round-trip vẫn tồn tại (Python trung gian) | Không bỏ — thay phần bridge là đủ cho latency; tối ưu WS sau nếu cần |
| Split-brain 2 clock khi G3 (WebAudio master + engine wrap) | 1 master clock duy nhất (Option A); engine không wrap, không playhead riêng |
| Param GUI (Sandbox instance) không tới processor JUCE | Mở rộng SET_PARAM ring: Sandbox implement IComponentHandler → performEdit/endEdit → `(slot, ParamID, normalizedValue)` → queue JUCE → inputParameterChanges trong processBlock; preset_b64 chỉ bulk/init (reload mỗi knob = chậm + reset state FX → click) |
| Param GUI (Sandbox instance) không tới processor JUCE | Mở rộng SET_PARAM ring: Sandbox implement IComponentHandler → performEdit/endEdit → `(slot, ParamID, normalizedValue)` → queue JUCE → inputParameterChanges trong processBlock; queue = lock-free SPSC (CẤM mutex trong processBlock — priority inversion → crackle); preset_b64 chỉ bulk/init (reload mỗi knob = chậm + reset state FX → click) |
| Jitter WS/Python làm mất ý nghĩa PDC mẫu | G0 đo σ round-trip ≥10k block; gate: σ nhỏ → FILL = mean+k·σ; σ lớn → giảm jitter trước (relay WS→SHM trong bridge process, Python chỉ control) |
## 6. Dependency