Files
SonicForgeStudio/native_bridge/debug/G0_RESULTS.md
T

105 lines
5.5 KiB
Markdown
Raw 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.
# G0 — Baseline đo latency (kết quả)
Ngày: 2026-08-27. Probe: `native_bridge/debug/g0_latency_probe.py` (chạy với
`timeBeginPeriod(1)`, 10k block/config, pipeline thật Python→SHM→fx_vst_bridge→SHM).
Log: `native_bridge/debug/g0_probe_run_full.log`.
## 1. Bảng latency plugin (getLatencySamples, @48kHz)
| Plugin | getLatencySamples | ms @48k | Ghi chú |
|---|---|---|---|
| Sonible pureComp | 2108 | 43.9 | báo latency thật (lookahead) |
| iZotope Ozone 11 | 0 | 0 | không báo latency (realtime mode) |
| empty (passthrough) | — | — | chain rỗng |
Nguồn: probe `plugin_latency` + log app thật `fxrt_bridge.log`
(`[RenderFx] STEP getLatencySamples = 2108/0`).
## 2. Jitter round-trip (10k block, 53.3s/config)
Round-trip = thời gian từ lúc probe gọi `write_input(block j)` đến lúc nhận
`read_output()` block j (FIFO theo index). Đã sửa pacing probe bằng
`timeBeginPeriod(1)` (bridge C++ đã gọi — `RealtimeFxLoop.cpp:160`); lần chạy
trước thiếu nó → Sleep 15.6ms granularity → pump ~22ms/batch ≠ 21.33ms realtime
→ pureComp bị "stall 1.9s" giả. Với pacing chuẩn, stall đó biến mất — là
artifact probe, KHÔNG phải VST stall.
| Config | mean ms | σ | p50 | p99 | max | recv/sent |
|---|---|---|---|---|---|---|
| empty | 21.54 | 1.74 | 21.64 | 22.03 | 25.73 | 9996/10000 |
| pureComp | 21.69 | 0.26 | 21.66 | 22.02 | 28.94 | 9996/10000 |
| Ozone 11 | 21.68 | 0.15 | 21.65 | 22.02 | 23.20 | 9996/10000 |
- Round-trip ≈ 21.5–21.7ms = đúng 1 batch 4 block (21.33ms) + overhead nhỏ
(SHM copy + bridge proc 0.001–0.45ms). Latency plugin KHÔNG nằm trong
round-trip — plugin latency bù bằng PDC (không chặn pipeline).
- σ round-trip: 0.15–0.26ms (pureComp/Ozone) — RẤT nhỏ → **Gate G2 MỞ**: PDC
mẫu có ý nghĩa, không cần giảm jitter trước (không cần relay WS→SHM sớm).
- empty σ=1.74: 1 outlier khởi động (min=0.04ms), p50/p99 vẫn 21.6/22.0.
- recv=9996 < 10000: 4 block cuối chưa drain hết lúc probe kết thúc (bridge
chậm hơn pace probe — xem §4), không phải mất block.
## 3. Inter-arrival deviation
| Config | σ ms | min | max |
|---|---|---|---|
| empty | 9.44 | −5.33 | 38.4 |
| pureComp | 9.36 | −5.33 | 23.5 |
| Ozone 11 | 9.36 | −5.33 | 17.8 |
Block về theo batch 4 (bridge xử lí take=4/lần) → inter-arrival lệch so với
5.33ms lý tưởng là đặc tính batching, không phải jitter ngẫu nhiên. Round-trip
σ (§2) là thước đo đúng cho PDC; inter-arrival dùng cho sizing FILL — xem §5.
## 4. Bridge FxRTPerf
| Nguồn | procAvg | procMax | loopAvg | loopMax | rate blk/s | vs realtime 187.5 |
|---|---|---|---|---|---|---|
| probe empty | 0.001ms | 0.05ms | 22.0ms | 1010ms | 181.7 | −3.1% |
| probe pureComp | 0.45ms | 0.80ms | 22.0ms | 1012ms | 181.6 | −3.1% |
| probe Ozone | 0.14ms | 0.35ms | 22.0ms | 1008ms | 181.7 | −3.1% |
| app thật (master chain đầy) | 3.4ms | 10.0ms | 21.4ms | 156ms | 186.5 | −0.5% |
- **loopMax ≈ 1s ở MỌI config probe kể cả empty** — spike 1s/lần chạy ~53s,
không phải VST (empty cũng có). Không xuất hiện trong log app thật gần nhất
(loopMax 156ms) — nghi Windows scheduler/antivirus/power, cần theo dõi khi
chạy thật. Probe round-trip max vẫn ≤29ms → spike xảy ra lúc bridge idle,
không chặn block đang xử lí.
- **Drift: bridge chậm 0.5–3.1% so realtime** (rate < 187.5). App thật −0.5%
(186.5): mỗi giây thiếu ~1 block → FILL 8 block (42.7ms) cạn sau ~8s nếu
không có cơ chế bù. Probe −3.1% là đo có pace probe riêng (nhịp probe + nhịp
bridge lệch nhau); con số tin cậy cho drift thật là từ app: −0.5%.
## 5. ~0.22s gồm gì (xác nhận)
Latency path thực đo + hằng số app:
| Thành phần | ms | Nguồn |
|---|---|---|
| Batching 4 block (pipeline) | ~21.6 | probe round-trip (§2) |
| FILL buffer worklet 8 block | 42.7 | `sf-fx-realtime.js` FILL=8 |
| Plugin latency (pureComp) | 43.9 | `getLatencySamples=2108` @48k |
| WS/main-thread jitter (warm, p50) | ~101 | dbg.log `fx_play_first` sincePlay 38–160ms |
| **Tổng nghe thấy (warm)** | **~210ms ≈ 0.21s** | khớp ~0.22s quan sát |
- PDC hiện tại `FX_RT_ROUNDTRIP_SAMPLES=3840` (80ms) = batching ~7 block +
FILL 8 block — khớp thực đo (21.6 + 42.7 ≈ 64ms + WS jitter margin). Giữ
nguyên; `latencyTotal` (plugin thật qua `{cmd:'latency'}`) cộng thêm đúng
(pureComp +43.9ms).
- Cold start VST load: 8–17s (dbg.log sincePlay 8111–17211ms), warm sau đó
38–160ms — là plugin init, không phải latency pipeline; không nằm trong PDC.
- fx_stats app thật (session master): u=3 h=3 f=13 s=13 cap=1 fi=13 q=5–11 —
underrun hiếm, queue duy trì 5–11 block → FILL đủ hấp thụ jitter thường.
## 6. Kết luận cho G2+
1. **Gate G2: MỞ.** σ round-trip 0.15–0.26ms → PDC mẫu có nghĩa; không cần
relay WS→SHM trước G2.
2. **Drift bridge −0.5% là phát hiện mới** (không có trong plan §1–§8): FILL
cạn dần trên session dài → cần quyết định: (a) chấp nhận (underrun hiếm, có
resume), (b) bù/resync định kỳ, (c) thêm giám sát rate. **Báo user để review
trước khi đưa vào plan.**
3. **loopMax ~1s spike** (probe, cả empty): theo dõi, chưa thấy ở app thật.
4. Plugin latency bảng §1 đủ cho G2: `graph.getLatencySamples()` sẽ thay hằng
số; dữ liệu hiện tại xác nhận pureComp là plugin duy nhất có latency thật.