Files
SonicForgeStudio/app/static/js/services/audioRoutingEngine.js
T
admin ba7c03ca5e fix: bounce silent — AudioRoutingEngine no longer full-tears-down sink on dest change
stopAllPlayback->updateSfRouting->startTrackPlayback reroutes bridge sink
twice during bounce; each dest change previously called this.disconnect()
= BridgeAudioNode teardown + async worklet reload, audio swallowed into
_preBuffer (bounded 64 blocks) forever if worklet never reactivates ->
silent WAV (only old reverb tail). Fix: rely on BridgeAudioNode.connect()
re-pointing _gainNode (already handles dest switch without teardown);
init() only when not ready. Add __sfDiag ROUTE + BRIDGE_AUDIO (frames/
peak/path per sec) to verify at bounce end.
2026-08-24 22:02:31 +07:00

48 lines
2.0 KiB
JavaScript

// app/static/js/services/audioRoutingEngine.js
// Routes the native bridge audio node into the DAW graph:
// bridge node -> track.sfEntry (FX rack chain) -> fader/pan -> masterBus
// Falls back to masterBus.input when no per-track sfEntry exists.
(function () {
var engine = {
_connected: false,
_trackId: null,
_dest: null,
isConnected: function () { return this._connected; },
/** bridgeNode = window.BridgeAudioNode; trackCtx = track node ({ sfEntry, gainNode }). */
connect: function (bridgeNode, trackCtx, trackId) {
if (!bridgeNode || !bridgeNode.getOutputNode) return false;
var dest = null;
if (trackCtx && trackCtx.sfEntry) dest = trackCtx.sfEntry;
else if (trackCtx && trackCtx.gainNode) dest = trackCtx.gainNode;
else if (window.masterBus && window.masterBus.input) dest = window.masterBus.input;
if (!dest) {
console.warn('[AudioRoutingEngine] no destination (no trackCtx / masterBus)');
return false;
}
// Idempotent: updateSfRouting/ensureMasteringRouting chay tren MOI keydown/
// note-on — neu da noi dung dest thi KHONG disconnect (disconnect flush ring
// -> am phim dang vang bi cat). Chi doi khi dest/track thuc su khac.
if (window.__sfDiag) window.__sfDiag("ROUTE to=" + (trackId || "masterBus") + " prev=" + (this._trackId || "masterBus") + " bridgeReady=" + bridgeNode.isReady() + " conn=" + this._connected);
if (this._connected && this._dest === dest && this._trackId === (trackId || null)) return true;
if (!bridgeNode.isReady()) bridgeNode.init();
bridgeNode.connect(dest);
this._connected = true;
this._trackId = trackId || null;
this._dest = dest;
console.log('[AudioRoutingEngine] bridge audio -> ' + (trackId || 'masterBus'));
return true;
},
disconnect: function () {
if (window.BridgeAudioNode) window.BridgeAudioNode.disconnect();
this._connected = false;
this._trackId = null;
this._dest = null;
}
};
window.AudioRoutingEngine = engine;
})();