V45.22: fix Bug 3 (wobble loop wrap) - wrap restart skipRouting nhu seekPlaybackTo/applyPlayheadDirect: updateSfRouting (AudioRoutingEngine.connect/ disconnect bridge sink + setOutputDestination) chay o MOI wrap trong luc isPlayingRef=false -> stall main thread 122-161ms (pump_gap) > KEEP 16 (~85ms) -> outQueue can -> underrun -> wobble beat 0:0 + playhead desync. skipRouting bo routing khoi critical path wrap -> stall ve duoi KEEP -> het underrun. Them instrument: stop_start log stack caller (xac nhan mystery stop = user Space/Stop, khong phai code) + wrap_timing stop=/start= phan tach stall. v=202608311708

This commit is contained in:
2026-08-31 17:09:28 +07:00
parent 7572d339de
commit 2fe78ddd1b
3 changed files with 18 additions and 11 deletions
+8 -4
View File
@@ -24647,7 +24647,7 @@ const App = () => {
fxRtWrapRestart = true; // V38: loop wrap restart
try { _dbgLog('wrap_info', 'solo=' + (hasAnySolo ? 1 : 0) + ' local=' + (selectionMode === 'local' ? 1 : 0) + ' tracks=' + (tracks ? tracks.length : -1) + ' nl=' + nativeLoopSrcsRef.current.size); } catch (e) {}
fxRtKeepForRestart = true; // restart/resume — giữ session FX realtime
stopAllPlayback();
stopAllPlayback(false, true); // V45.22: wrap restart — skipRouting nhu seekPlaybackTo (het stall updateSfRouting tai seam -> het wobble)
startOffsetTimeRef.current = selLeft;
startAudioTimeRef.current = context.currentTime;
if (hasAnySolo) {
@@ -24662,7 +24662,7 @@ const App = () => {
fxRtWrapRestart = true; // V38: loop wrap restart
try { _dbgLog('wrap_info', 'solo=' + (hasAnySolo ? 1 : 0) + ' local=' + (selectionMode === 'local' ? 1 : 0) + ' tracks=' + (tracks ? tracks.length : -1) + ' nl=' + nativeLoopSrcsRef.current.size); } catch (e) {}
fxRtKeepForRestart = true; // restart/resume — giữ session FX realtime
stopAllPlayback();
stopAllPlayback(false, true); // V45.22: wrap restart — skipRouting nhu seekPlaybackTo (het stall updateSfRouting tai seam -> het wobble)
startOffsetTimeRef.current = selLeft;
startAudioTimeRef.current = context.currentTime;
startTrackPlayback(selLeft);
@@ -24686,12 +24686,16 @@ const App = () => {
fxRtWrapRestart = true; // V38: loop wrap restart
try { _dbgLog('wrap_info', 'solo=' + (hasAnySolo ? 1 : 0) + ' local=' + (selectionMode === 'local' ? 1 : 0) + ' tracks=' + (tracks ? tracks.length : -1) + ' nl=' + nativeLoopSrcsRef.current.size); } catch (e) {}
fxRtKeepForRestart = true; // restart/resume — giữ session FX realtime
stopAllPlayback();
const _wrapT0 = performance.now();
stopAllPlayback(false, true); // V45.22: wrap restart — skipRouting nhu seekPlaybackTo (het stall updateSfRouting tai seam -> het wobble)
const _wrapT1 = performance.now();
startOffsetTimeRef.current = 0;
startAudioTimeRef.current = context.currentTime;
startTrackPlayback(0);
const _wrapT2 = performance.now();
setCurrentTime(0);
setIsPlaying(true);
try { _dbgLog('wrap_timing', 'stop=' + Math.round(_wrapT1 - _wrapT0) + ' start=' + Math.round(_wrapT2 - _wrapT1)); } catch (e) {}
animationFrameIdRef.current = requestAnimationFrame(updatePlayhead);
return;
}
@@ -26322,7 +26326,7 @@ const App = () => {
// xử bằng release mượt (CC123, không CC120 hard-cut — D15) + worklet
// WRAP_FADE 256 (FX path) → không cần che bằng dropout master.
_dbgLog('stop_start', 'fade=' + !!fade + ' ' + _dbgBridgeGain());
_dbgLog('stop_start', 'fade=' + !!fade + ' ' + _dbgBridgeGain() + ' call=' + ((new Error().stack || '').split('\n').slice(2, 4).join('|') || '').trim());
isPlayingRef.current = false;
// Gap 7: xoa automation schedule — tra gain master ve 1.0 (fader rieng).
try { if (masterBus && masterBus.output && masterBus.output.gain) { const _actx = getAudioContext(); masterBus.output.gain.cancelScheduledValues(_actx.currentTime); masterBus.output.gain.setValueAtTime(1, _actx.currentTime); } } catch (e) { }