Files

59 lines
3.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# G3 — 1 clock: PDC latency thật + playhead engine-derived (kết quả)
Ngày: 2026-08-28. Plan: `JUCE_LATENCY_PLAN.md` G3. Option A — 1 clock.
## Nội dung
- **Bridge báo processed samples** qua lat ring slot đặc biệt `0xFFFFFFFE`
(`JuceFxLoop.cpp`, mỗi block sau `++processed`): `samples = processed*n`
(n=curBlock). Python `_lat_drain` tách slot này riêng → `self.processed`
(KHÔNG vào `latencies` dict — tổng chain không đổi). Thêm `get_processed()`.
- **WS latency message thêm `processed`** (`plugins.py`): gửi khi `processed`
đổi (mỗi block ~5.33ms), bỏ gate chỉ theo total — total chỉ đổi khi chain đổi.
- **Playhead engine-derived** (`app.jsx`): khi FX active và có anchor,
`position = startOffset + (processed - anchor - latencyTotal)/sr` (đã trừ
latency → bám vị trí mẫu NGHE được; pre-roll tự giữ tại startOffset qua
clamp). Anchor = raw processed tại play/wrap start (`fxRtAnchorProcessed`
gọi từ `__fxRtPlayheadFreeze`, mọi play/resume path đều đi qua). Bỏ
freeze/snap khi active; fallback wall-clock khi không active. Áp dụng 4 chỗ:
bridge position block, sub-tab `_ph`, sub-tab `wallTime`, main branch
`_playheadSec` → `setCurrentTime`.
- **Worklet nhận latency thật** qua port message `{type:'latency', samples}`;
`clear_queue('loop')`: `wrapFadeBlocks = outQueue.length +
ceil(latencySamples/BLOCK)` — align processed-tail, crossfade đúng seam
end→start kể cả khi FX latency (pureComp 2108 mẫu) còn in-flight trong bridge.
## Verify (đã chạy)
1. **Build**: `cmake --build native_bridge/build_juce --config Release --target
juce_fx_bridge` OK. Copy `src-tauri/binaries/juce_fx_bridge-x86_64-pc-windows-msvc.exe`,
SHA256 khớp bản build (`07621b81...`).
2. **Probe SHM thật** (`native_bridge/debug/g3_probe_check.py`, JUCE bridge qua
`SF_JUCE_FX_BRIDGE_PATH`, chain pureComp, SR 48k, 400 block ~2.1s):
- `latencies` dict KHÔNG đổi: `{0: 2108}` trước/sau — processed tách riêng
không làm sai tổng chain.
- `processed` tiến 0 → 102400 (= 400 block × 256 mẫu) — bridge báo đúng.
3. **Cú pháp**: `python -m py_compile` fx_realtime.py + plugins.py OK;
`node --check` worklet OK; `babel` (node_modules) parse app.jsx OK (node
thuần không hiểu JSX — dùng babel, exit 0).
4. **Fake session** (object.__new__, không shm): `get_processed()` → None,
`get_latencies()` → `{0: 2108}` — path không-SHM an toàn.
## Done-when trạng thái
- ✅ processed tách riêng, tổng latency chain không đổi (probe)
- ✅ playhead công thức engine-derived đã cài đủ 4 chỗ; freeze/snap vô hiệu khi
active (code path)
- ⏳ **Chưa verify bằng tai**: 100-pass loop không click với crossfade tối
thiểu; playhead bám vị trí mẫu trong app thật (cần user chạy GUI + nghe).
## Ghi chú
- Probe check script giữ ở `native_bridge/debug/g3_probe_check.py` (chạy lại:
`python native_bridge/debug/g3_probe_check.py`).
- BufferError lúc thoát (`cannot close exported pointers`) là quirk teardown
shared_memory Python 3.13, không ảnh hưởng kết quả.
- Latency WS ~5.33ms/msg = 187 msg/s — nhỏ so với pump audio; nếu cần tiết
kiệm sau này: batch processed 4 block/lần (giảm 4×) — `ponytail: chỉ làm khi
có bằng chứng quá tải`.