diff --git a/app/static/js/app.jsx b/app/static/js/app.jsx index da87ae7..2ba3c4c 100644 --- a/app/static/js/app.jsx +++ b/app/static/js/app.jsx @@ -2161,11 +2161,11 @@ function fxRtStop(silent) { // qua worklet → lệch pha với mastered. fxRtApplyPdc trễ dry path đúng lượng // để align. FX_RT_ROUNDTRIP_SAMPLES là ước lượng — ponytail: đo RTT thật // (tag seq trên block) khi cần sample-accurate. -// V43: FILL 8→16 (sf-fx-realtime.js) → RTT = batching 4 block (~7 block @48k -// ≈ 1792) + FILL buffer 16 block (4096) = 23 block ≈ 5888 (~123ms @48k). Giữ +// V45: FILL 24→48 (sf-fx-realtime.js) → RTT = batching 4 block (~7 block @48k +// ≈ 1792) + FILL buffer 48 block (12288) = 55 block ≈ 14080 (~293ms @48k). Giữ // đồng bộ với sf-fx-realtime.js. FX_RT_START_EST_MS: ước lượng khởi đầu khi // chưa có phép đo (fx_play_first) — dùng cho freeze playhead thay V39 0.31s. -const FX_RT_ROUNDTRIP_SAMPLES = 7936; +const FX_RT_ROUNDTRIP_SAMPLES = 14080; const FX_RT_START_EST_MS = 450; // G3: anchor processed — playhead = startOffset + (processed - anchor - latency)/sr // (da tru latency -> bam vi tri mau NGHE DUOC; pre-roll tu giu tai startOffset — diff --git a/app/static/js/sf-fx-realtime.js b/app/static/js/sf-fx-realtime.js index c3fa205..2b90b7f 100644 --- a/app/static/js/sf-fx-realtime.js +++ b/app/static/js/sf-fx-realtime.js @@ -29,10 +29,10 @@ class SfFxRealtimeProcessor extends AudioWorkletProcessor { super(); this.BLOCK = 256; // FXRT_BLOCK this.BURST = 4; // số block gom 1 frame (bridge batch) - this.FILL = 24; // V44: 24 block ~128ms @48k: buffer khởi đầu — hấp thụ jitter main-thread + stall deschedule bridge 68-138ms. PDC 7936 = (7+24)*256 (fxRtApplyPdc). V43 16 -> cushion ~9 (q 3-9) chua du: stall 68-82ms van gay underrun. V44 len 24 -> cushion ~17 (~90ms). + this.FILL = 48; // V45: 48 block ~256ms @48k: hấp thụ stall OS-level ~200ms (V44 21:17:37.9: engine pump 198ms + main 196ms cùng lúc → u=2 underrun → lag 20-30s). PDC 14080 = (7+48)*256 (fxRtApplyPdc). V44 24 -> cushion 128ms < stall 196ms -> underrun. V45 48 -> cushion 256ms (margin ~60ms). this.RESUME_FILL = 24; // V26: re-buffer khi resume SAU STOP (flush_for_stop) — 16 block ~85ms (V43: = FILL) → play kế tiếp bắt đầu nhanh; underrun-stall vẫn dùng FILL (crackle/wobble). this.resumeFill = this.FILL; // mức re-buffer khi resume sau flush — stop: RESUME_FILL, underrun-stall: FILL - this.CAP = 32; // V40: cap queue chặn overflow (~170ms) + this.CAP = 56; // V45: = FILL+8: cap queue chặn overflow (~300ms) this.HOLD_FADE = 4; // 4 block ~21ms: fade 1→0 sau HOLD hết (hết click cắt cứng) this.holdFadeLeft = 0; // mẫu còn lại của fade-out khi underrun this.silenced = false; // đã fade về 0 → im lặng; resume phải fade-in, không hold lại