V21: keep master FX session warm on user stop - no 4s VST reload on replay
- stopAllPlayback(fade=true) giữ master FX session (không teardown) → play kế tiếp FX xử lý ngay, hết cửa sổ dry ~4s khi reload VST - per-track FX vẫn teardown khi user stop (VSTi nhiều track nặng CPU) - idle timeout 120s (FX_RT_WARM_IDLE_MS): ngừng chơi lâu → teardown giải phóng CPU/VST - fxRtStart/fxRtStop/startSubTabPlayback hủy idle timer khi play
This commit is contained in:
+27
-4
@@ -1714,9 +1714,14 @@ const fxRt = { active: false, starting: false, startToken: 0, sessionId: null, w
|
||||
// Loop restart/seek/reschedule: stopAllPlayback giữ session FX realtime (không
|
||||
// teardown) → fxRtStart early-return → KHÔNG reload VST ~4s mỗi pass loop
|
||||
// (hết bypass rồi mới load lại). Chỉ set TRƯỚC nhánh restart/resume; user
|
||||
// stop thật (fade=true) / bridge-down / new-project / export-end KHÔNG set →
|
||||
// teardown bình thường.
|
||||
// stop thật (fade=true) giữ master FX warm + idle timeout (V21); bridge-down /
|
||||
// new-project / export-end → teardown bình thường.
|
||||
let fxRtKeepForRestart = false;
|
||||
// V21: user stop (fade=true) giữ master FX session warm — play kế tiếp có FX
|
||||
// ngay, không chờ reload VST ~4s. Idle timeout: ngừng chơi lâu → teardown
|
||||
// giải phóng CPU/VST (chấp nhận ~4s delay ở play sau khi idle lâu).
|
||||
const FX_RT_WARM_IDLE_MS = 120000;
|
||||
let fxRtWarmIdleTimer = null;
|
||||
// Native VSTi GUI open/reload đang chạy (C++ reloadForGUI mute 1-3s khi mở
|
||||
// lại GUI sau khi đóng) → master-silence watchdog (750ms) sẽ false-positive →
|
||||
// rebuild + fxRtStop → dry→wet vài giây. Exempt watchdog trong cửa sổ này.
|
||||
@@ -1797,6 +1802,9 @@ async function fxRtSetChain(chain) {
|
||||
}
|
||||
}
|
||||
async function fxRtStart() {
|
||||
// V21: mọi play/chain-change gọi đây — hủy idle timer của lần stop trước
|
||||
// (không để session warm bị teardown giữa lúc đang chơi).
|
||||
if (fxRtWarmIdleTimer) { clearTimeout(fxRtWarmIdleTimer); fxRtWarmIdleTimer = null; }
|
||||
const chain = fxRtChain();
|
||||
const ck = fxRtChainKey(chain);
|
||||
if (fxRt.active) {
|
||||
@@ -1970,6 +1978,7 @@ async function fxRtStart() {
|
||||
}
|
||||
}
|
||||
function fxRtStop(silent) {
|
||||
if (fxRtWarmIdleTimer) { clearTimeout(fxRtWarmIdleTimer); fxRtWarmIdleTimer = null; }
|
||||
// Phải bump token TRƯỚC guard early-return: lúc fxRtStart đang in-flight thì
|
||||
// active/ws/node/sessionId đều chưa có → guard sẽ return, nhưng start vẫn
|
||||
// phải bị hủy (token mismatch ở checkpoint).
|
||||
@@ -23645,6 +23654,9 @@ const App = () => {
|
||||
const startSubTabPlayback = (st, offsetWallTime) => {
|
||||
const context = getAudioContext();
|
||||
_nativePlayEpoch++; // new play — vô hiệu doHardStop đang fade
|
||||
// V21: section play không gọi fxRtStart — hủy idle timer thủ công (không
|
||||
// để master FX bị teardown giữa lúc section đang phát).
|
||||
if (fxRtWarmIdleTimer) { clearTimeout(fxRtWarmIdleTimer); fxRtWarmIdleTimer = null; }
|
||||
restorePendingFadeSession(); // V17: huy fade dang treo — replay khong bi dip gain
|
||||
if (!st.buffer) {
|
||||
st.buffer = context.createBuffer(1, 128, context.sampleRate);
|
||||
@@ -25679,13 +25691,24 @@ const App = () => {
|
||||
// Realtime VST FX: dừng session + khôi phục output→analyser. Nhánh restart
|
||||
// (loop/seek/reschedule/solo...) set fxRtKeepForRestart=true → GIỮ session
|
||||
// (fxRtStart early-return khi active + chain khớp) → hết bypass+reload ~4s
|
||||
// mỗi pass loop. User stop thật (fade=true) → teardown bình thường.
|
||||
const _keepFx = fxRtKeepForRestart;
|
||||
// mỗi pass loop. User stop thật (fade=true) → V21 giữ master FX warm (idle
|
||||
// timeout FX_RT_WARM_IDLE_MS) — play kế tiếp FX ngay; per-track teardown.
|
||||
const _keepFx = fxRtKeepForRestart || !!fade;
|
||||
fxRtKeepForRestart = false;
|
||||
if (!_keepFx) {
|
||||
try { fxRtStop(); } catch (e) { console.warn('[FX RT] stop error:', e); }
|
||||
// Realtime VST FX per-track: dừng mọi session track + restore chain trực tiếp.
|
||||
try { fxRtTrackStopAll(); } catch (e) { console.warn('[FX RT track] stop error:', e); }
|
||||
} else if (fade) {
|
||||
// V21: user stop — GIỮ master FX session warm (play kế tiếp có FX ngay,
|
||||
// không chờ reload VST ~4s). Per-track vẫn teardown (VSTi nhiều track nặng).
|
||||
// Idle timeout (FX_RT_WARM_IDLE_MS) giải phóng CPU khi ngừng chơi lâu.
|
||||
try { fxRtTrackStopAll(); } catch (e) { console.warn('[FX RT track] stop error:', e); }
|
||||
clearTimeout(fxRtWarmIdleTimer);
|
||||
fxRtWarmIdleTimer = setTimeout(() => {
|
||||
fxRtWarmIdleTimer = null;
|
||||
try { fxRtStop(); } catch (e) { console.warn('[FX RT] idle stop error:', e); }
|
||||
}, FX_RT_WARM_IDLE_MS);
|
||||
}
|
||||
_nativePlayEpoch++; // hủy mọi render/decode pending của lần play cũ
|
||||
// V11: hủy mọi note timer của lần play cũ (stop/seek/loop restart) — timer
|
||||
|
||||
Reference in New Issue
Block a user