// app/static/js/services/bridgeAudioNode.js // Audio sink: consumes 'bridge-audio' PCM frames (native bridge) and plays them // through a ScriptProcessorNode into the WebAudio graph (track FX / master bus). (function () { var RING_DEPTH = 8; // 8 blocks * 256 samples ~= 46ms anti-underrun var SP_BUFFER = 4096; // ScriptProcessor chunk (16 bridge blocks) var _queue = []; var _spn = null; var _gainNode = null; var _ctx = null; var _initialized = false; function _getCtx() { if (_ctx) return _ctx; if (typeof getAudioContext === 'function') _ctx = getAudioContext(); else if (window.__sharedAudioCtx) _ctx = window.__sharedAudioCtx; else _ctx = new (window.AudioContext || window.webkitAudioContext)(); return _ctx; } function init(audioCtx) { if (_initialized) return; _ctx = audioCtx || _getCtx(); _gainNode = _ctx.createGain(); _gainNode.gain.value = 1.0; _spn = _ctx.createScriptProcessor(SP_BUFFER, 0, 2); _spn.onaudioprocess = function (e) { var L = e.outputBuffer.getChannelData(0); var R = e.outputBuffer.getChannelData(1); L.fill(0); R.fill(0); if (!_queue.length) return; var f = _queue.shift(); L.set(f.l); R.set(f.r); }; _spn.connect(_gainNode); _initialized = true; console.log('[BridgeAudioNode] initialized (ring depth ' + RING_DEPTH + ')'); } function onAudio(l, r) { if (!_initialized) init(); _queue.push({ l: new Float32Array(l), r: new Float32Array(r) }); if (_queue.length > RING_DEPTH) _queue.shift(); // drop oldest on overrun } function flush() { _queue = []; } function getOutputNode() { return _gainNode; } function disconnect() { flush(); if (_spn && _gainNode) { try { _spn.disconnect(); } catch (e) {} try { _gainNode.disconnect(); } catch (e) {} } // Reset state so a later init() can rebuild (AudioRoutingEngine re-connect). _initialized = false; _spn = null; _gainNode = null; _ctx = null; } window.BridgeAudioNode = { init: init, onAudio: onAudio, flush: flush, getOutputNode: getOutputNode, connect: function (dest) { if (_gainNode) _gainNode.connect(dest); }, disconnect: disconnect, isReady: function () { return _initialized; } }; })();