From ebe17d902b94649b05e146d98e012520085c5964 Mon Sep 17 00:00:00 2001 From: locphamtran Date: Fri, 28 Aug 2026 11:49:54 +0700 Subject: [PATCH] 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 --- JUCE_LATENCY_PLAN.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/JUCE_LATENCY_PLAN.md b/JUCE_LATENCY_PLAN.md index 9f6201d..3cf52f8 100644 --- a/JUCE_LATENCY_PLAN.md +++ b/JUCE_LATENCY_PLAN.md @@ -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