supersonic-scsynth 0.68.1 → 0.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
package/README.npm.md
CHANGED
package/dist/osc_channel.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function Y(r,t,e){return(e-1-r+t)%e}function G({uint8View:r,dataView:t,bufferStart:e,bufferSize:s,head:o,payload:n,sequence:_,messageMagic:E,headerSize:c,sourceId:u=0,headerScratch:a=null,headerScratchView:S=null}){let i=n.length,d=c+i+3&-4,f=s-o;if(d>f){let l=a||new Uint8Array(c),p=S||new DataView(l.buffer);p.setUint32(0,E,!0),p.setUint32(4,d,!0),p.setUint32(8,_,!0),p.setUint32(12,u,!0);let T=e+o,I=e;if(f>=c){r.set(l,T);let R=f-c;for(let h=0;h<R;h++)r[T+c+h]=n[h];for(let h=R;h<i;h++)r[I+h-R]=n[h]}else{for(let h=0;h<f;h++)r[T+h]=l[h];for(let h=f;h<c;h++)r[I+h-f]=l[h];let R=c-f;r.set(n,I+R)}}else{let l=e+o;t.setUint32(l,E,!0),t.setUint32(l+4,d,!0),t.setUint32(l+8,_,!0),t.setUint32(l+12,u,!0),r.set(n,l+c)}return(o+d)%s}function U({uint8View:r,dataView:t,bufferStart:e,bufferSize:s,head:o,tail:n,messageMagic:_,paddingMagic:E,headerSize:c,maxMessages:u=1/0,onMessage:a,onCorruption:S}){let i=n,A=0,d=f=>{let l=f;if(l+4<=s)return t.getUint32(e+l,!0);let p=0;for(let T=0;T<4;T++)p|=r[e+(l+T)%s]<<T*8;return p};for(;i!==o&&A<u;){let f=s-i,l;if(f>=4?l=t.getUint32(e+i,!0):l=d(i),l===E){i=0;continue}if(l!==_){S&&S(i),i=(i+1)%s;continue}let p=d((i+4)%s),T=d((i+8)%s),I=d((i+12)%s);if(p<c||p>s){S&&S(i),i=(i+1)%s;continue}let R=p-c,h=e+(i+c)%s;a(h,R,T,I),i=(i+p)%s,A++}return{newTail:i,messagesRead:A}}function w(r,t,e=0,s=!1){for(let o=0;o<=e;o++)if(Atomics.compareExchange(r,t,0,1)===0)return!0;if(s){for(let n=0;n<100;n++)if(Atomics.wait(r,t,1,100),Atomics.compareExchange(r,t,0,1)===0)return!0;return console.error("[RingBuffer] Lock acquisition timeout after 10s - possible deadlock"),!1}return!1}function k(r,t){Atomics.store(r,t,0),Atomics.notify(r,t,1)}function P({atomicView:r,dataView:t,uint8View:e,bufferConstants:s,ringBufferBase:o,controlIndices:n,oscMessage:_,sourceId:E=0,maxSpins:c=0,useWait:u=!1,headerScratch:a=null,headerScratchView:S=null}){let i=_.length,A=s.MESSAGE_HEADER_SIZE+i;if(A>s.IN_BUFFER_SIZE-s.MESSAGE_HEADER_SIZE||!w(r,n.IN_WRITE_LOCK,c,u))return!1;try{let d=Atomics.load(r,n.IN_HEAD),f=Atomics.load(r,n.IN_TAIL),l=A+3&-4;if(Y(d,f,s.IN_BUFFER_SIZE)<l)return!1;let T=Atomics.add(r,n.IN_SEQUENCE,1),I=G({uint8View:e,dataView:t,bufferStart:o+s.IN_BUFFER_START,bufferSize:s.IN_BUFFER_SIZE,head:d,payload:_,sequence:T,messageMagic:s.MESSAGE_MAGIC,headerSize:s.MESSAGE_HEADER_SIZE,sourceId:E,headerScratch:a,headerScratchView:S});return Atomics.load(r,n.IN_HEAD),Atomics.store(r,n.IN_HEAD,I),Atomics.notify(r,n.IN_HEAD,1),!0}finally{k(r,n.IN_WRITE_LOCK)}}function B(r,t,e,s){let o=r+t+s*e;return{controlBase:o,headIndex:(o+0)/4,tailIndex:(o+4)/4,activeIndex:(o+8)/4,dropsIndex:(o+12)/4}}function O(r,t){let e=r+t;return{IN_HEAD:(e+0)/4,IN_TAIL:(e+4)/4,IN_SEQUENCE:(e+24)/4,IN_WRITE_LOCK:(e+40)/4,IN_LOG_TAIL:(e+44)/4}}function W(r){return r.length>=8&&r[0]===35&&r[1]===98&&r[2]===117&&r[3]===110&&r[4]===100&&r[5]===108&&r[6]===101&&r[7]===0}var C=.5;function V(r){if(r.length<16)return null;let t=new DataView(r.buffer,r.byteOffset,r.byteLength);return{ntpSeconds:t.getUint32(8,!1),ntpFraction:t.getUint32(12,!1)}}function L(){return(performance.timeOrigin+performance.now())/1e3+2208988800}function x(r,t={}){let{getCurrentNTP:e=L,bypassLookaheadS:s=C}=t;if(!W(r))return"nonBundle";let o=V(r);if(!o)return"nonBundle";let{ntpSeconds:n,ntpFraction:_}=o;if(n===0&&_<=1)return"immediate";let E=e();if(E===null||E===0)return"immediate";let u=n+_/4294967296-E,a=128/48e3;return u<-a?"late":u<s?"nearFuture":"farFuture"}function D(r){return r!=="farFuture"}var K={nonBundle:38,immediate:39,nearFuture:40,late:41},N=class r{#e;#o;#s;#r;#n;#t;#L;#i;#N;#U;#P;#B;#p;#l;#T;#h;#u;#c;#R;#C;#_=-1;#A;#I;#S;#f;#a;#O=[];#x;#d;#E={messagesSent:0,bytesSent:0,nonBundle:0,immediate:0,nearFuture:0,late:0,bypassed:0};constructor(t,e){if(this.#e=t,this.#n=e.preschedulerPort||null,this.#L=e.bypassLookaheadS??C,this.#i=e.sourceId??0,this.#N=e.blocking??this.#i!==0,this.#U=e.getCurrentNTP??L,this.#T=1e3,t==="postMessage")this.#o=e.port;else{if(this.#s={sharedBuffer:e.sharedBuffer,ringBufferBase:e.ringBufferBase,bufferConstants:e.bufferConstants,controlIndices:e.controlIndices},this.#F(),this.#I=e.replyNotifier||null,e.sharedBuffer&&e.bufferConstants){let s=e.ringBufferBase+e.bufferConstants.METRICS_START;this.#t=new Int32Array(e.sharedBuffer,s,e.bufferConstants.METRICS_SIZE/4)}if(e.sharedBuffer&&e.bufferConstants?.NODE_ID_COUNTER_START!==void 0){let s=e.ringBufferBase+e.bufferConstants.NODE_ID_COUNTER_START;this.#P=new Int32Array(e.sharedBuffer,s,1),this.#m()}}e.nodeIdSource&&(this.#h=e.nodeIdSource,this.#m()),e.nodeIdRange&&(this.#B=e.nodeIdRange.from,this.#p=e.nodeIdRange.to,this.#l=e.nodeIdRange.from),e.replyWorkletPort&&(this.#x=e.replyWorkletPort),e.nodeIdPort&&(this.#u=e.nodeIdPort,this.#u.onmessage=s=>{s.data.type==="nodeIdRange"&&(this.#c={from:s.data.from,to:s.data.to})},this.#M())}#F(){let t=this.#s.sharedBuffer,e=this.#s.bufferConstants.MESSAGE_HEADER_SIZE||16,s=new Uint8Array(e);this.#r={atomicView:new Int32Array(t),dataView:new DataView(t),uint8View:new Uint8Array(t),headerScratch:s,headerScratchView:new DataView(s.buffer)}}classify(t){return x(t,{getCurrentNTP:this.#U,bypassLookaheadS:this.#L})}#H(t,e=null){if(this.#e==="sab"&&this.#t){if(Atomics.add(this.#t,24,1),Atomics.add(this.#t,25,t),e){let s=K[e];s!==void 0&&(Atomics.add(this.#t,s,1),Atomics.add(this.#t,22,1))}}else this.#E.messagesSent++,this.#E.bytesSent+=t,e&&e in this.#E&&(this.#E[e]++,this.#E.bypassed++)}getAndResetMetrics(){let t={...this.#E};return this.#E={messagesSent:0,bytesSent:0,nonBundle:0,immediate:0,nearFuture:0,late:0,bypassed:0},t}getMetrics(){return this.#e==="sab"&&this.#t?{messagesSent:Atomics.load(this.#t,24),bytesSent:Atomics.load(this.#t,25),nonBundle:Atomics.load(this.#t,38),immediate:Atomics.load(this.#t,39),nearFuture:Atomics.load(this.#t,40),late:Atomics.load(this.#t,41),bypassed:Atomics.load(this.#t,22)}:{...this.#E}}#D(t,e=null,s=!0){if(this.#e==="postMessage")return this.#o?(this.#o.postMessage({type:"osc",oscData:t,bypassCategory:e,sourceId:this.#i}),!0):!1;{let o=this.#N,n=P({atomicView:this.#r.atomicView,dataView:this.#r.dataView,uint8View:this.#r.uint8View,bufferConstants:this.#s.bufferConstants,ringBufferBase:this.#s.ringBufferBase,controlIndices:this.#s.controlIndices,oscMessage:t,sourceId:this.#i,maxSpins:o?10:0,useWait:o,headerScratch:this.#r.headerScratch,headerScratchView:this.#r.headerScratchView});return!n&&!o&&s&&this.#n?(this.#t&&Atomics.add(this.#t,45,1),this.#n.postMessage({type:"directDispatch",oscData:t,sourceId:this.#i}),!0):n}}#y(t){return this.#n?(this.#n.postMessage({type:"osc",oscData:t,sourceId:this.#i}),!0):(console.error("[OscChannel] No prescheduler port, sending direct"),this.#D(t))}send(t){let e=this.classify(t);if(D(e)){let s=this.#D(t,e);return s&&this.#H(t.length,e),s}else{let s=this.#y(t);return s&&this.#H(t.length,null),s}}sendDirect(t){return this.#D(t)}sendToPrescheduler(t){return this.#y(t)}nextNodeId(){if(this.#P)return Atomics.add(this.#P,0,1);this.#l>=this.#p&&this.#m();let t=this.#l++;return this.#u&&!this.#c&&this.#p-this.#l<=this.#T>>>1&&this.#M(),t}#m(){if(this.#h){let t=this.#h(this.#T);this.#B=t.from,this.#p=t.to,this.#l=t.from}else if(this.#c)this.#B=this.#c.from,this.#p=this.#c.to,this.#l=this.#c.from,this.#c=null,this.#M();else if(this.#u)throw new Error("[OscChannel] Node ID range exhausted before async refill arrived. Yield to the event loop between large batches of nextNodeId() calls.")}#M(){this.#u&&this.#u.postMessage({type:"requestNodeIdRange"})}set getCurrentNTP(t){this.#U=t}get mode(){return this.#e}get replyDrops(){if(!(this.#e!=="sab"||this.#_<0))return Atomics.load(this.#r.atomicView,this.#d.dropsIndex)}get transferable(){let t={mode:this.#e,preschedulerPort:this.#n,bypassLookaheadS:this.#L,sourceId:this.#i,blocking:this.#N};if(this.#e==="postMessage"){let e=this.#T*10,s,o;if(this.#h){let n=this.#h(e);s={from:n.from,to:n.to};let _=new MessageChannel,E=this.#h,c=this.#T;_.port1.onmessage=u=>{if(u.data.type==="requestNodeIdRange"){let a=E(c);_.port1.postMessage({type:"nodeIdRange",from:a.from,to:a.to})}},o=_.port2,this.#R=o}return{...t,port:this.#o,nodeIdRange:s,nodeIdPort:o}}else return{...t,sharedBuffer:this.#s.sharedBuffer,ringBufferBase:this.#s.ringBufferBase,bufferConstants:this.#s.bufferConstants,controlIndices:this.#s.controlIndices}}get transferList(){let t=[];return this.#e==="postMessage"&&this.#o&&t.push(this.#o),this.#n&&t.push(this.#n),this.#R&&(t.push(this.#R),this.#R=null),t}activateReplies(){this.#e==="sab"?this.#g():this.#k()}deactivateReplies(){this.#e==="sab"?this.#Y():this.#X()}setReplyHandler(t){this.#C=t,this.activateReplies(),this.#b()}clearReplyHandler(){this.#C=null,this.deactivateReplies()}pollReplies(t){let e=t||this.#C;return e?this.#e==="sab"?this.#_<0?0:this.#w(e):this.#a?this.#W(e):0:0}#g(){if(this.#_>=0)return;let t=this.#s.bufferConstants;if(!t.REPLY_CHANNEL_COUNT)throw new Error("WASM does not support reply channels");let e=this.#r.atomicView;for(let s=0;s<t.REPLY_CHANNEL_COUNT;s++){let o=B(this.#s.ringBufferBase,t.REPLY_CHANNELS_CONTROL_START,t.REPLY_CHANNEL_CONTROL_SIZE,s);if(Atomics.store(e,o.headIndex,0),Atomics.store(e,o.tailIndex,0),Atomics.store(e,o.dropsIndex,0),Atomics.compareExchange(e,o.activeIndex,0,1)===0){this.#d=o,this.#_=s;return}}throw new Error("All "+t.REPLY_CHANNEL_COUNT+" reply channel slots are in use \u2014 cannot register for replies")}#b(){this.#S||this.#f||this.#A||typeof AudioWorkletGlobalScope<"u"||this.#e==="sab"&&(this.#I?(this.#S=()=>this.pollReplies(),this.#I.subscribe(this.#S)):typeof Atomics<"u"&&typeof Atomics.waitAsync=="function"?this.#G():this.#A=setInterval(()=>this.pollReplies(),5))}#Y(){this.#_<0||(Atomics.store(this.#r.atomicView,this.#d.activeIndex,0),this.#A&&(clearInterval(this.#A),this.#A=null),this.#S&&this.#I&&(this.#I.unsubscribe(this.#S),this.#S=null),this.#f=!1,this.#_=-1,this.#d=null)}#G(){let t=this.#r.atomicView,{headIndex:e,tailIndex:s}=this.#d;this.#f=!0;let o=()=>{if(!this.#f)return;let n=Atomics.load(t,e),_=Atomics.load(t,s);if(n!==_&&this.pollReplies(),!this.#f)return;let E=Atomics.load(t,e),c=Atomics.waitAsync(t,e,E);c.async?c.value.then(()=>{this.#f&&(this.pollReplies(),o())}):(this.pollReplies(),setTimeout(o,0))};o()}#w(t){let e=this.#r.atomicView,{headIndex:s,tailIndex:o}=this.#d,n=Atomics.load(e,s),_=Atomics.load(e,o);if(n===_)return 0;let E=this.#s.bufferConstants,c=this.#s.ringBufferBase+E.REPLY_CHANNELS_BUFFER_START+this.#_*E.REPLY_CHANNEL_BUFFER_SIZE,u=E.REPLY_CHANNEL_BUFFER_SIZE,a=this.#r.uint8View,{newTail:S,messagesRead:i}=U({uint8View:a,dataView:this.#r.dataView,bufferStart:c,bufferSize:u,head:n,tail:_,messageMagic:E.MESSAGE_MAGIC,paddingMagic:E.PADDING_MAGIC,headerSize:E.MESSAGE_HEADER_SIZE||16,maxMessages:64,onMessage:(A,d,f)=>{t(a,A,d,f)}});return i>0&&Atomics.store(e,o,S),i}#k(){if(this.#a)return;let t=this.#x||this.#o;if(!t)throw new Error("No port available for reply registration");let e=new MessageChannel;t.postMessage({type:"addReplyPort",sourceId:this.#i},[e.port1]),this.#a=e.port2;let s=typeof AudioWorkletGlobalScope<"u";this.#a.onmessage=o=>{if(o.data.type!=="oscReplies"||!o.data.count)return;let{count:n,buffer:_,messages:E}=o.data;if(!E||!_)return;let c=new Uint8Array(_);if(s)for(let u=0;u<n;u++){let a=E[u];if(!a)continue;let S=c.slice(a.offset,a.offset+a.length);this.#O.push({oscData:S,sequence:a.sequence})}else{let u=this.#C;if(!u)return;for(let a=0;a<n;a++){let S=E[a];if(!S)continue;let i=c.slice(S.offset,S.offset+S.length);u(i,S.sequence)}}}}#X(){if(this.#a){let t=this.#x||this.#o;t&&t.postMessage({type:"removeReplyPort",sourceId:this.#i}),this.#a.close(),this.#a=null}this.#O.length=0}#W(t){let e=this.#O,s=e.length;if(s===0)return 0;for(let o=0;o<s;o++)t(e[o].oscData,e[o].sequence);return e.length=0,s}close(){this.clearReplyHandler(),this.#e==="postMessage"&&this.#o&&(this.#o.close(),this.#o=null),this.#n&&(this.#n.close(),this.#n=null)}static createPostMessage(t){return t instanceof MessagePort?new r("postMessage",{port:t}):new r("postMessage",t)}static createSAB(t){let e=t.controlIndices;return e||(e=O(t.ringBufferBase,t.bufferConstants.CONTROL_START)),new r("sab",{sharedBuffer:t.sharedBuffer,ringBufferBase:t.ringBufferBase,bufferConstants:t.bufferConstants,controlIndices:e,preschedulerPort:t.preschedulerPort,bypassLookaheadS:t.bypassLookaheadS,sourceId:t.sourceId,blocking:t.blocking,replyNotifier:t.replyNotifier})}static fromTransferable(t){return t.mode==="postMessage"?new r("postMessage",{port:t.port,preschedulerPort:t.preschedulerPort,bypassLookaheadS:t.bypassLookaheadS,sourceId:t.sourceId,blocking:t.blocking,nodeIdRange:t.nodeIdRange,nodeIdPort:t.nodeIdPort}):new r("sab",{sharedBuffer:t.sharedBuffer,ringBufferBase:t.ringBufferBase,bufferConstants:t.bufferConstants,controlIndices:t.controlIndices,preschedulerPort:t.preschedulerPort,bypassLookaheadS:t.bypassLookaheadS,sourceId:t.sourceId,blocking:t.blocking})}};export{N as OscChannel};
|
|
1
|
+
function Y(r,t,e){return(e-1-r+t)%e}function G({uint8View:r,dataView:t,bufferStart:e,bufferSize:s,head:o,payload:n,sequence:_,messageMagic:E,headerSize:c,sourceId:S=0,headerScratch:a=null,headerScratchView:u=null}){let i=n.length,p=c+i+3&-4,f=s-o;if(p>f){let l=a||new Uint8Array(c),A=u||new DataView(l.buffer);A.setUint32(0,E,!0),A.setUint32(4,p,!0),A.setUint32(8,_,!0),A.setUint32(12,S,!0);let d=e+o,I=e;if(f>=c){r.set(l,d);let R=f-c;for(let h=0;h<R;h++)r[d+c+h]=n[h];for(let h=R;h<i;h++)r[I+h-R]=n[h]}else{for(let h=0;h<f;h++)r[d+h]=l[h];for(let h=f;h<c;h++)r[I+h-f]=l[h];let R=c-f;r.set(n,I+R)}}else{let l=e+o;t.setUint32(l,E,!0),t.setUint32(l+4,p,!0),t.setUint32(l+8,_,!0),t.setUint32(l+12,S,!0),r.set(n,l+c)}return(o+p)%s}function U({uint8View:r,dataView:t,bufferStart:e,bufferSize:s,head:o,tail:n,messageMagic:_,paddingMagic:E,headerSize:c,maxMessages:S=1/0,onMessage:a,onCorruption:u}){let i=n,T=0,p=f=>{let l=f;if(l+4<=s)return t.getUint32(e+l,!0);let A=0;for(let d=0;d<4;d++)A|=r[e+(l+d)%s]<<d*8;return A};for(;i!==o&&T<S;){let f=s-i,l;if(f>=4?l=t.getUint32(e+i,!0):l=p(i),l===E){i=0;continue}if(l!==_){u&&u(i),i=(i+1)%s;continue}let A=p((i+4)%s),d=p((i+8)%s),I=p((i+12)%s);if(A<c||A>s){u&&u(i),i=(i+1)%s;continue}let R=A-c,h=e+(i+c)%s;a(h,R,d,I),i=(i+A)%s,T++}return{newTail:i,messagesRead:T}}function w(r,t,e=0,s=!1){for(let o=0;o<=e;o++)if(Atomics.compareExchange(r,t,0,1)===0)return!0;if(s){for(let n=0;n<100;n++)if(Atomics.wait(r,t,1,100),Atomics.compareExchange(r,t,0,1)===0)return!0;return console.error("[RingBuffer] Lock acquisition timeout after 10s - possible deadlock"),!1}return!1}function k(r,t){Atomics.store(r,t,0),Atomics.notify(r,t,1)}function P({atomicView:r,dataView:t,uint8View:e,bufferConstants:s,ringBufferBase:o,controlIndices:n,oscMessage:_,sourceId:E=0,maxSpins:c=0,useWait:S=!1,headerScratch:a=null,headerScratchView:u=null}){let i=_.length,T=s.MESSAGE_HEADER_SIZE+i;if(T>s.IN_BUFFER_SIZE-s.MESSAGE_HEADER_SIZE||!w(r,n.IN_WRITE_LOCK,c,S))return!1;try{let p=Atomics.load(r,n.IN_HEAD),f=Atomics.load(r,n.IN_TAIL),l=T+3&-4;if(Y(p,f,s.IN_BUFFER_SIZE)<l)return!1;let d=Atomics.add(r,n.IN_SEQUENCE,1),I=G({uint8View:e,dataView:t,bufferStart:o+s.IN_BUFFER_START,bufferSize:s.IN_BUFFER_SIZE,head:p,payload:_,sequence:d,messageMagic:s.MESSAGE_MAGIC,headerSize:s.MESSAGE_HEADER_SIZE,sourceId:E,headerScratch:a,headerScratchView:u});return Atomics.load(r,n.IN_HEAD),Atomics.store(r,n.IN_HEAD,I),Atomics.notify(r,n.IN_HEAD,1),!0}finally{k(r,n.IN_WRITE_LOCK)}}function x(r,t,e,s){let o=r+t+s*e;return{controlBase:o,headIndex:(o+0)/4,tailIndex:(o+4)/4,activeIndex:(o+8)/4,dropsIndex:(o+12)/4}}function O(r,t){let e=r+t;return{IN_HEAD:(e+0)/4,IN_TAIL:(e+4)/4,IN_SEQUENCE:(e+24)/4,IN_WRITE_LOCK:(e+40)/4,IN_LOG_TAIL:(e+44)/4}}function X(r){return r.length>=8&&r[0]===35&&r[1]===98&&r[2]===117&&r[3]===110&&r[4]===100&&r[5]===108&&r[6]===101&&r[7]===0}var C=.5;function V(r){if(r.length<16)return null;let t=new DataView(r.buffer,r.byteOffset,r.byteLength);return{ntpSeconds:t.getUint32(8,!1),ntpFraction:t.getUint32(12,!1)}}function N(){return(performance.timeOrigin+performance.now())/1e3+2208988800}function B(r,t={}){let{getCurrentNTP:e=N,bypassLookaheadS:s=C}=t;if(!X(r))return"nonBundle";let o=V(r);if(!o)return"nonBundle";let{ntpSeconds:n,ntpFraction:_}=o;if(n===0&&_<=1)return"immediate";let E=e();if(E===null||E===0)return"immediate";let S=n+_/4294967296-E,a=128/48e3;return S<-a?"late":S<s?"nearFuture":"farFuture"}function D(r){return r!=="farFuture"}var v={nonBundle:38,immediate:39,nearFuture:40,late:41},L=class r{#e;#o;#s;#r;#n;#t;#N;#i;#L;#U;#P;#x;#A;#l;#d;#h;#S;#c;#R;#C;#_=-1;#T;#I;#u;#f;#a;#O=[];#B;#p;#E={messagesSent:0,bytesSent:0,nonBundle:0,immediate:0,nearFuture:0,late:0,bypassed:0};constructor(t,e){if(this.#e=t,this.#n=e.preschedulerPort||null,this.#N=e.bypassLookaheadS??C,this.#i=e.sourceId??0,this.#L=e.blocking??this.#i!==0,this.#U=e.getCurrentNTP??N,this.#d=1e3,t==="postMessage")this.#o=e.port;else{if(this.#s={sharedBuffer:e.sharedBuffer,ringBufferBase:e.ringBufferBase,bufferConstants:e.bufferConstants,controlIndices:e.controlIndices},this.#F(),this.#I=e.replyNotifier||null,e.sharedBuffer&&e.bufferConstants){let s=e.ringBufferBase+e.bufferConstants.METRICS_START;this.#t=new Int32Array(e.sharedBuffer,s,e.bufferConstants.METRICS_SIZE/4)}if(e.sharedBuffer&&e.bufferConstants?.NODE_ID_COUNTER_START!==void 0){let s=e.ringBufferBase+e.bufferConstants.NODE_ID_COUNTER_START;this.#P=new Int32Array(e.sharedBuffer,s,1),this.#m()}}e.nodeIdSource&&(this.#h=e.nodeIdSource,this.#m()),e.nodeIdRange&&(this.#x=e.nodeIdRange.from,this.#A=e.nodeIdRange.to,this.#l=e.nodeIdRange.from),e.replyWorkletPort&&(this.#B=e.replyWorkletPort),e.nodeIdPort&&(this.#S=e.nodeIdPort,this.#S.onmessage=s=>{s.data.type==="nodeIdRange"&&(this.#c={from:s.data.from,to:s.data.to})},this.#M())}#F(){let t=this.#s.sharedBuffer,e=this.#s.bufferConstants.MESSAGE_HEADER_SIZE||16,s=new Uint8Array(e);this.#r={atomicView:new Int32Array(t),dataView:new DataView(t),uint8View:new Uint8Array(t),headerScratch:s,headerScratchView:new DataView(s.buffer)}}classify(t){return B(t,{getCurrentNTP:this.#U,bypassLookaheadS:this.#N})}#H(t,e=null){if(this.#e==="sab"&&this.#t){if(Atomics.add(this.#t,24,1),Atomics.add(this.#t,25,t),e){let s=v[e];s!==void 0&&(Atomics.add(this.#t,s,1),Atomics.add(this.#t,22,1))}}else this.#E.messagesSent++,this.#E.bytesSent+=t,e&&e in this.#E&&(this.#E[e]++,this.#E.bypassed++)}getAndResetMetrics(){let t={...this.#E};return this.#E={messagesSent:0,bytesSent:0,nonBundle:0,immediate:0,nearFuture:0,late:0,bypassed:0},t}getMetrics(){return this.#e==="sab"&&this.#t?{messagesSent:Atomics.load(this.#t,24),bytesSent:Atomics.load(this.#t,25),nonBundle:Atomics.load(this.#t,38),immediate:Atomics.load(this.#t,39),nearFuture:Atomics.load(this.#t,40),late:Atomics.load(this.#t,41),bypassed:Atomics.load(this.#t,22)}:{...this.#E}}#D(t,e=null,s=!0){if(this.#e==="postMessage")return this.#o?(this.#o.postMessage({type:"osc",oscData:t,bypassCategory:e,sourceId:this.#i}),!0):!1;{let o=this.#L,n=P({atomicView:this.#r.atomicView,dataView:this.#r.dataView,uint8View:this.#r.uint8View,bufferConstants:this.#s.bufferConstants,ringBufferBase:this.#s.ringBufferBase,controlIndices:this.#s.controlIndices,oscMessage:t,sourceId:this.#i,maxSpins:o?10:0,useWait:o,headerScratch:this.#r.headerScratch,headerScratchView:this.#r.headerScratchView});return!n&&!o&&s&&this.#n?(this.#t&&Atomics.add(this.#t,45,1),this.#n.postMessage({type:"directDispatch",oscData:t,sourceId:this.#i}),!0):n}}#y(t){return this.#n?(this.#n.postMessage({type:"osc",oscData:t,sourceId:this.#i}),!0):(console.error("[OscChannel] No prescheduler port, sending direct"),this.#D(t))}send(t){let e=this.classify(t);if(D(e)){let s=this.#D(t,e);return s&&this.#H(t.length,e),s}else{let s=this.#y(t);return s&&this.#H(t.length,null),s}}sendDirect(t){return this.#D(t)}sendToPrescheduler(t){return this.#y(t)}nextNodeId(){if(this.#P)return Atomics.add(this.#P,0,1);this.#l>=this.#A&&this.#m();let t=this.#l++;return this.#S&&!this.#c&&this.#A-this.#l<=this.#d>>>1&&this.#M(),t}#m(){if(this.#h){let t=this.#h(this.#d);this.#x=t.from,this.#A=t.to,this.#l=t.from}else if(this.#c)this.#x=this.#c.from,this.#A=this.#c.to,this.#l=this.#c.from,this.#c=null,this.#M();else if(this.#S)throw new Error("[OscChannel] Node ID range exhausted before async refill arrived. Yield to the event loop between large batches of nextNodeId() calls.")}#M(){this.#S&&this.#S.postMessage({type:"requestNodeIdRange"})}set getCurrentNTP(t){this.#U=t}get mode(){return this.#e}get replyDrops(){if(!(this.#e!=="sab"||this.#_<0))return Atomics.load(this.#r.atomicView,this.#p.dropsIndex)}get transferable(){let t={mode:this.#e,preschedulerPort:this.#n,bypassLookaheadS:this.#N,sourceId:this.#i,blocking:this.#L};if(this.#e==="postMessage"){let e=this.#d*10,s,o;if(this.#h){let n=this.#h(e);s={from:n.from,to:n.to};let _=new MessageChannel,E=this.#h,c=this.#d;_.port1.onmessage=S=>{if(S.data.type==="requestNodeIdRange"){let a=E(c);_.port1.postMessage({type:"nodeIdRange",from:a.from,to:a.to})}},o=_.port2,this.#R=o}return{...t,port:this.#o,nodeIdRange:s,nodeIdPort:o}}else return{...t,sharedBuffer:this.#s.sharedBuffer,ringBufferBase:this.#s.ringBufferBase,bufferConstants:this.#s.bufferConstants,controlIndices:this.#s.controlIndices}}get transferList(){let t=[];return this.#e==="postMessage"&&this.#o&&t.push(this.#o),this.#n&&t.push(this.#n),this.#R&&(t.push(this.#R),this.#R=null),t}activateReplies(){this.#e==="sab"?this.#g():this.#k()}deactivateReplies(){this.#e==="sab"?this.#Y():this.#K()}setReplyHandler(t){this.#C=t,this.activateReplies(),this.#b()}clearReplyHandler(){this.#C=null,this.deactivateReplies()}pollReplies(t){let e=t||this.#C;return e?this.#e==="sab"?this.#_<0?0:this.#w(e):this.#a?this.#X(e):0:0}#g(){if(this.#_>=0)return;let t=this.#s.bufferConstants;if(!t.REPLY_CHANNEL_COUNT)throw new Error("WASM does not support reply channels");let e=this.#r.atomicView;for(let s=0;s<t.REPLY_CHANNEL_COUNT;s++){let o=x(this.#s.ringBufferBase,t.REPLY_CHANNELS_CONTROL_START,t.REPLY_CHANNEL_CONTROL_SIZE,s);if(Atomics.store(e,o.headIndex,0),Atomics.store(e,o.tailIndex,0),Atomics.store(e,o.dropsIndex,0),Atomics.compareExchange(e,o.activeIndex,0,1)===0){this.#p=o,this.#_=s;return}}throw new Error("All "+t.REPLY_CHANNEL_COUNT+" reply channel slots are in use \u2014 cannot register for replies")}#b(){this.#u||this.#f||this.#T||typeof AudioWorkletGlobalScope<"u"||this.#e==="sab"&&(this.#I?(this.#u=()=>this.pollReplies(),this.#I.subscribe(this.#u)):typeof Atomics<"u"&&typeof Atomics.waitAsync=="function"?this.#G():this.#T=setInterval(()=>this.pollReplies(),5))}#Y(){this.#_<0||(Atomics.store(this.#r.atomicView,this.#p.activeIndex,0),this.#T&&(clearInterval(this.#T),this.#T=null),this.#u&&this.#I&&(this.#I.unsubscribe(this.#u),this.#u=null),this.#f=!1,this.#_=-1,this.#p=null)}#G(){let t=this.#r.atomicView,{headIndex:e,tailIndex:s}=this.#p;this.#f=!0;let o=()=>{if(!this.#f)return;let n=Atomics.load(t,e),_=Atomics.load(t,s);if(n!==_&&this.pollReplies(),!this.#f)return;let E=Atomics.load(t,e),c=Atomics.waitAsync(t,e,E);c.async?c.value.then(()=>{this.#f&&(this.pollReplies(),o())}):(this.pollReplies(),setTimeout(o,0))};o()}#w(t){let e=this.#r.atomicView,{headIndex:s,tailIndex:o}=this.#p,n=Atomics.load(e,s),_=Atomics.load(e,o);if(n===_)return 0;let E=this.#s.bufferConstants,c=this.#s.ringBufferBase+E.REPLY_CHANNELS_BUFFER_START+this.#_*E.REPLY_CHANNEL_BUFFER_SIZE,S=E.REPLY_CHANNEL_BUFFER_SIZE,a=this.#r.uint8View,{newTail:u,messagesRead:i}=U({uint8View:a,dataView:this.#r.dataView,bufferStart:c,bufferSize:S,head:n,tail:_,messageMagic:E.MESSAGE_MAGIC,paddingMagic:E.PADDING_MAGIC,headerSize:E.MESSAGE_HEADER_SIZE||16,maxMessages:64,onMessage:(T,p,f)=>{t(a,T,p,f)}});return i>0&&Atomics.store(e,o,u),i}#k(){if(this.#a)return;let t=this.#B||this.#o;if(!t)throw new Error("No port available for reply registration");let e=new MessageChannel;t.postMessage({type:"addReplyPort",sourceId:this.#i},[e.port1]),this.#a=e.port2;let s=typeof AudioWorkletGlobalScope<"u";this.#a.onmessage=o=>{if(o.data.type!=="oscReplies"||!o.data.count)return;let{count:n,buffer:_,messages:E}=o.data;if(!E||!_)return;let c=new Uint8Array(_);if(s)for(let S=0;S<n;S++){let a=E[S];if(!a)continue;let u=c.slice(a.offset,a.offset+a.length);this.#O.push({oscData:u,sequence:a.sequence})}else{let S=this.#C;if(!S)return;for(let a=0;a<n;a++){let u=E[a];if(!u)continue;let i=c.slice(u.offset,u.offset+u.length);S(i,u.sequence)}}}}#K(){if(this.#a){let t=this.#B||this.#o;t&&t.postMessage({type:"removeReplyPort",sourceId:this.#i}),this.#a.close(),this.#a=null}this.#O.length=0}#X(t){let e=this.#O,s=e.length;if(s===0)return 0;for(let o=0;o<s;o++)t(e[o].oscData,e[o].sequence);return e.length=0,s}close(){this.clearReplyHandler(),this.#e==="postMessage"&&this.#o&&(this.#o.close(),this.#o=null),this.#n&&(this.#n.close(),this.#n=null)}static createPostMessage(t){return t instanceof MessagePort?new r("postMessage",{port:t}):new r("postMessage",t)}static createSAB(t){let e=t.controlIndices;return e||(e=O(t.ringBufferBase,t.bufferConstants.CONTROL_START)),new r("sab",{sharedBuffer:t.sharedBuffer,ringBufferBase:t.ringBufferBase,bufferConstants:t.bufferConstants,controlIndices:e,preschedulerPort:t.preschedulerPort,bypassLookaheadS:t.bypassLookaheadS,sourceId:t.sourceId,blocking:t.blocking,replyNotifier:t.replyNotifier})}static fromTransferable(t){return t.mode==="postMessage"?new r("postMessage",{port:t.port,preschedulerPort:t.preschedulerPort,bypassLookaheadS:t.bypassLookaheadS,sourceId:t.sourceId,blocking:t.blocking,nodeIdRange:t.nodeIdRange,nodeIdPort:t.nodeIdPort}):new r("sab",{sharedBuffer:t.sharedBuffer,ringBufferBase:t.ringBufferBase,bufferConstants:t.bufferConstants,controlIndices:t.controlIndices,preschedulerPort:t.preschedulerPort,bypassLookaheadS:t.bypassLookaheadS,sourceId:t.sourceId,blocking:t.blocking})}};export{L as OscChannel};
|
package/dist/supersonic.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var R=class i{constructor(e){if(new.target===i)throw new Error("Transport is abstract - use SABTransport or PostMessageTransport");this._config=e,this._disposed=!1}get mode(){return this._config.mode}send(e,t){throw new Error("Abstract method - implement in subclass")}onReply(e){throw new Error("Abstract method - implement in subclass")}onDebug(e){throw new Error("Abstract method - implement in subclass")}onError(e){throw new Error("Abstract method - implement in subclass")}getMetrics(){throw new Error("Abstract method - implement in subclass")}async initialize(){throw new Error("Abstract method - implement in subclass")}createOscChannel(){throw new Error("Abstract method - implement in subclass")}dispose(){this._disposed=!0}get ready(){throw new Error("Abstract method - implement in subclass")}};var ge=new Map;function et(i){try{return new URL(i,window.location.href).origin!==window.location.origin}catch{return!1}}async function tt(i){if(ge.has(i))return ge.get(i);let e=await fetch(i);if(!e.ok)throw new Error(`Failed to fetch ${i}: ${e.status} ${e.statusText}`);let t=await e.text(),s=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(s);return ge.set(i,r),r}async function I(i,e={}){let t=i;return et(i)&&(t=await tt(i)),new Worker(t,e)}async function st(i,e){let t=e;et(e)&&(t=await tt(e)),await i.addModule(t)}function as(i,e,t){return(t-1-i+e)%t}function cs({uint8View:i,dataView:e,bufferStart:t,bufferSize:s,head:r,payload:n,sequence:o,messageMagic:a,headerSize:c,sourceId:u=0,headerScratch:l=null,headerScratchView:f=null}){let h=n.length,p=c+h+3&-4,d=s-r;if(p>d){let m=l||new Uint8Array(c),E=f||new DataView(m.buffer);E.setUint32(0,a,!0),E.setUint32(4,p,!0),E.setUint32(8,o,!0),E.setUint32(12,u,!0);let _=t+r,w=t;if(d>=c){i.set(m,_);let C=d-c;for(let g=0;g<C;g++)i[_+c+g]=n[g];for(let g=C;g<h;g++)i[w+g-C]=n[g]}else{for(let g=0;g<d;g++)i[_+g]=m[g];for(let g=d;g<c;g++)i[w+g-d]=m[g];let C=c-d;i.set(n,w+C)}}else{let m=t+r;e.setUint32(m,a,!0),e.setUint32(m+4,p,!0),e.setUint32(m+8,o,!0),e.setUint32(m+12,u,!0),i.set(n,m+c)}return(r+p)%s}function rt({uint8View:i,dataView:e,bufferStart:t,bufferSize:s,head:r,tail:n,messageMagic:o,paddingMagic:a,headerSize:c,maxMessages:u=1/0,onMessage:l,onCorruption:f}){let h=n,y=0,p=d=>{let m=d;if(m+4<=s)return e.getUint32(t+m,!0);let E=0;for(let _=0;_<4;_++)E|=i[t+(m+_)%s]<<_*8;return E};for(;h!==r&&y<u;){let d=s-h,m;if(d>=4?m=e.getUint32(t+h,!0):m=p(h),m===a){h=0;continue}if(m!==o){f&&f(h),h=(h+1)%s;continue}let E=p((h+4)%s),_=p((h+8)%s),w=p((h+12)%s);if(E<c||E>s){f&&f(h),h=(h+1)%s;continue}let C=E-c,g=t+(h+c)%s;l(g,C,_,w),h=(h+E)%s,y++}return{newTail:h,messagesRead:y}}function ls(i,e,t=0,s=!1){for(let r=0;r<=t;r++)if(Atomics.compareExchange(i,e,0,1)===0)return!0;if(s){for(let n=0;n<100;n++)if(Atomics.wait(i,e,1,100),Atomics.compareExchange(i,e,0,1)===0)return!0;return console.error("[RingBuffer] Lock acquisition timeout after 10s - possible deadlock"),!1}return!1}function us(i,e){Atomics.store(i,e,0),Atomics.notify(i,e,1)}function it({atomicView:i,dataView:e,uint8View:t,bufferConstants:s,ringBufferBase:r,controlIndices:n,oscMessage:o,sourceId:a=0,maxSpins:c=0,useWait:u=!1,headerScratch:l=null,headerScratchView:f=null}){let h=o.length,y=s.MESSAGE_HEADER_SIZE+h;if(y>s.IN_BUFFER_SIZE-s.MESSAGE_HEADER_SIZE||!ls(i,n.IN_WRITE_LOCK,c,u))return!1;try{let p=Atomics.load(i,n.IN_HEAD),d=Atomics.load(i,n.IN_TAIL),m=y+3&-4;if(as(p,d,s.IN_BUFFER_SIZE)<m)return!1;let _=Atomics.add(i,n.IN_SEQUENCE,1),w=cs({uint8View:t,dataView:e,bufferStart:r+s.IN_BUFFER_START,bufferSize:s.IN_BUFFER_SIZE,head:p,payload:o,sequence:_,messageMagic:s.MESSAGE_MAGIC,headerSize:s.MESSAGE_HEADER_SIZE,sourceId:a,headerScratch:l,headerScratchView:f});return Atomics.load(i,n.IN_HEAD),Atomics.store(i,n.IN_HEAD,w),Atomics.notify(i,n.IN_HEAD,1),!0}finally{us(i,n.IN_WRITE_LOCK)}}function ot(i,e,t,s){let r=i+e+s*t;return{controlBase:r,headIndex:(r+0)/4,tailIndex:(r+4)/4,activeIndex:(r+8)/4,dropsIndex:(r+12)/4}}function K(i,e){let t=i+e;return{IN_HEAD:(t+0)/4,IN_TAIL:(t+4)/4,IN_SEQUENCE:(t+24)/4,IN_WRITE_LOCK:(t+40)/4,IN_LOG_TAIL:(t+44)/4}}function at(i,e){let t=i+e;return{IN_HEAD:(t+0)/4,IN_TAIL:(t+4)/4,OUT_HEAD:(t+8)/4,OUT_TAIL:(t+12)/4,DEBUG_HEAD:(t+16)/4,DEBUG_TAIL:(t+20)/4,IN_SEQUENCE:(t+24)/4,OUT_SEQUENCE:(t+28)/4,DEBUG_SEQUENCE:(t+32)/4,STATUS_FLAGS:(t+36)/4,IN_WRITE_LOCK:(t+40)/4,IN_LOG_TAIL:(t+44)/4}}function fs(i){return i.length>=8&&i[0]===35&&i[1]===98&&i[2]===117&&i[3]===110&&i[4]===100&&i[5]===108&&i[6]===101&&i[7]===0}var _e=.5;function be(i){if(i.length<16)return null;let e=new DataView(i.buffer,i.byteOffset,i.byteLength);return{ntpSeconds:e.getUint32(8,!1),ntpFraction:e.getUint32(12,!1)}}function M(){return(performance.timeOrigin+performance.now())/1e3+2208988800}function ct(i,e={}){let{getCurrentNTP:t=M,bypassLookaheadS:s=_e}=e;if(!fs(i))return"nonBundle";let r=be(i);if(!r)return"nonBundle";let{ntpSeconds:n,ntpFraction:o}=r;if(n===0&&o<=1)return"immediate";let a=t();if(a===null||a===0)return"immediate";let u=n+o/4294967296-a,l=128/48e3;return u<-l?"late":u<s?"nearFuture":"farFuture"}function Z(i){return i!=="farFuture"}var hs={nonBundle:38,immediate:39,nearFuture:40,late:41},O=class i{#r;#e;#s;#a;#o;#c;#i;#n;#u;#l;#y;#S;#g;#d;#E;#p;#_;#T;#t;#f;#h=-1;#m;#b;#A;#w;#C;#R=[];#B;#I;#O={messagesSent:0,bytesSent:0,nonBundle:0,immediate:0,nearFuture:0,late:0,bypassed:0};constructor(e,t){if(this.#r=e,this.#o=t.preschedulerPort||null,this.#i=t.bypassLookaheadS??_e,this.#n=t.sourceId??0,this.#u=t.blocking??this.#n!==0,this.#l=t.getCurrentNTP??M,this.#E=1e3,e==="postMessage")this.#e=t.port;else{if(this.#s={sharedBuffer:t.sharedBuffer,ringBufferBase:t.ringBufferBase,bufferConstants:t.bufferConstants,controlIndices:t.controlIndices},this.#P(),this.#b=t.replyNotifier||null,t.sharedBuffer&&t.bufferConstants){let s=t.ringBufferBase+t.bufferConstants.METRICS_START;this.#c=new Int32Array(t.sharedBuffer,s,t.bufferConstants.METRICS_SIZE/4)}if(t.sharedBuffer&&t.bufferConstants?.NODE_ID_COUNTER_START!==void 0){let s=t.ringBufferBase+t.bufferConstants.NODE_ID_COUNTER_START;this.#y=new Int32Array(t.sharedBuffer,s,1),this.#L()}}t.nodeIdSource&&(this.#p=t.nodeIdSource,this.#L()),t.nodeIdRange&&(this.#S=t.nodeIdRange.from,this.#g=t.nodeIdRange.to,this.#d=t.nodeIdRange.from),t.replyWorkletPort&&(this.#B=t.replyWorkletPort),t.nodeIdPort&&(this.#_=t.nodeIdPort,this.#_.onmessage=s=>{s.data.type==="nodeIdRange"&&(this.#T={from:s.data.from,to:s.data.to})},this.#k())}#P(){let e=this.#s.sharedBuffer,t=this.#s.bufferConstants.MESSAGE_HEADER_SIZE||16,s=new Uint8Array(t);this.#a={atomicView:new Int32Array(e),dataView:new DataView(e),uint8View:new Uint8Array(e),headerScratch:s,headerScratchView:new DataView(s.buffer)}}classify(e){return ct(e,{getCurrentNTP:this.#l,bypassLookaheadS:this.#i})}#D(e,t=null){if(this.#r==="sab"&&this.#c){if(Atomics.add(this.#c,24,1),Atomics.add(this.#c,25,e),t){let s=hs[t];s!==void 0&&(Atomics.add(this.#c,s,1),Atomics.add(this.#c,22,1))}}else this.#O.messagesSent++,this.#O.bytesSent+=e,t&&t in this.#O&&(this.#O[t]++,this.#O.bypassed++)}getAndResetMetrics(){let e={...this.#O};return this.#O={messagesSent:0,bytesSent:0,nonBundle:0,immediate:0,nearFuture:0,late:0,bypassed:0},e}getMetrics(){return this.#r==="sab"&&this.#c?{messagesSent:Atomics.load(this.#c,24),bytesSent:Atomics.load(this.#c,25),nonBundle:Atomics.load(this.#c,38),immediate:Atomics.load(this.#c,39),nearFuture:Atomics.load(this.#c,40),late:Atomics.load(this.#c,41),bypassed:Atomics.load(this.#c,22)}:{...this.#O}}#U(e,t=null,s=!0){if(this.#r==="postMessage")return this.#e?(this.#e.postMessage({type:"osc",oscData:e,bypassCategory:t,sourceId:this.#n}),!0):!1;{let r=this.#u,n=it({atomicView:this.#a.atomicView,dataView:this.#a.dataView,uint8View:this.#a.uint8View,bufferConstants:this.#s.bufferConstants,ringBufferBase:this.#s.ringBufferBase,controlIndices:this.#s.controlIndices,oscMessage:e,sourceId:this.#n,maxSpins:r?10:0,useWait:r,headerScratch:this.#a.headerScratch,headerScratchView:this.#a.headerScratchView});return!n&&!r&&s&&this.#o?(this.#c&&Atomics.add(this.#c,45,1),this.#o.postMessage({type:"directDispatch",oscData:e,sourceId:this.#n}),!0):n}}#x(e){return this.#o?(this.#o.postMessage({type:"osc",oscData:e,sourceId:this.#n}),!0):(console.error("[OscChannel] No prescheduler port, sending direct"),this.#U(e))}send(e){let t=this.classify(e);if(Z(t)){let s=this.#U(e,t);return s&&this.#D(e.length,t),s}else{let s=this.#x(e);return s&&this.#D(e.length,null),s}}sendDirect(e){return this.#U(e)}sendToPrescheduler(e){return this.#x(e)}nextNodeId(){if(this.#y)return Atomics.add(this.#y,0,1);this.#d>=this.#g&&this.#L();let e=this.#d++;return this.#_&&!this.#T&&this.#g-this.#d<=this.#E>>>1&&this.#k(),e}#L(){if(this.#p){let e=this.#p(this.#E);this.#S=e.from,this.#g=e.to,this.#d=e.from}else if(this.#T)this.#S=this.#T.from,this.#g=this.#T.to,this.#d=this.#T.from,this.#T=null,this.#k();else if(this.#_)throw new Error("[OscChannel] Node ID range exhausted before async refill arrived. Yield to the event loop between large batches of nextNodeId() calls.")}#k(){this.#_&&this.#_.postMessage({type:"requestNodeIdRange"})}set getCurrentNTP(e){this.#l=e}get mode(){return this.#r}get replyDrops(){if(!(this.#r!=="sab"||this.#h<0))return Atomics.load(this.#a.atomicView,this.#I.dropsIndex)}get transferable(){let e={mode:this.#r,preschedulerPort:this.#o,bypassLookaheadS:this.#i,sourceId:this.#n,blocking:this.#u};if(this.#r==="postMessage"){let t=this.#E*10,s,r;if(this.#p){let n=this.#p(t);s={from:n.from,to:n.to};let o=new MessageChannel,a=this.#p,c=this.#E;o.port1.onmessage=u=>{if(u.data.type==="requestNodeIdRange"){let l=a(c);o.port1.postMessage({type:"nodeIdRange",from:l.from,to:l.to})}},r=o.port2,this.#t=r}return{...e,port:this.#e,nodeIdRange:s,nodeIdPort:r}}else return{...e,sharedBuffer:this.#s.sharedBuffer,ringBufferBase:this.#s.ringBufferBase,bufferConstants:this.#s.bufferConstants,controlIndices:this.#s.controlIndices}}get transferList(){let e=[];return this.#r==="postMessage"&&this.#e&&e.push(this.#e),this.#o&&e.push(this.#o),this.#t&&(e.push(this.#t),this.#t=null),e}activateReplies(){this.#r==="sab"?this.#H():this.#F()}deactivateReplies(){this.#r==="sab"?this.#N():this.#$()}setReplyHandler(e){this.#f=e,this.activateReplies(),this.#G()}clearReplyHandler(){this.#f=null,this.deactivateReplies()}pollReplies(e){let t=e||this.#f;return t?this.#r==="sab"?this.#h<0?0:this.#Y(t):this.#C?this.#v(t):0:0}#H(){if(this.#h>=0)return;let e=this.#s.bufferConstants;if(!e.REPLY_CHANNEL_COUNT)throw new Error("WASM does not support reply channels");let t=this.#a.atomicView;for(let s=0;s<e.REPLY_CHANNEL_COUNT;s++){let r=ot(this.#s.ringBufferBase,e.REPLY_CHANNELS_CONTROL_START,e.REPLY_CHANNEL_CONTROL_SIZE,s);if(Atomics.store(t,r.headIndex,0),Atomics.store(t,r.tailIndex,0),Atomics.store(t,r.dropsIndex,0),Atomics.compareExchange(t,r.activeIndex,0,1)===0){this.#I=r,this.#h=s;return}}throw new Error("All "+e.REPLY_CHANNEL_COUNT+" reply channel slots are in use \u2014 cannot register for replies")}#G(){this.#A||this.#w||this.#m||typeof AudioWorkletGlobalScope<"u"||this.#r==="sab"&&(this.#b?(this.#A=()=>this.pollReplies(),this.#b.subscribe(this.#A)):typeof Atomics<"u"&&typeof Atomics.waitAsync=="function"?this.#z():this.#m=setInterval(()=>this.pollReplies(),5))}#N(){this.#h<0||(Atomics.store(this.#a.atomicView,this.#I.activeIndex,0),this.#m&&(clearInterval(this.#m),this.#m=null),this.#A&&this.#b&&(this.#b.unsubscribe(this.#A),this.#A=null),this.#w=!1,this.#h=-1,this.#I=null)}#z(){let e=this.#a.atomicView,{headIndex:t,tailIndex:s}=this.#I;this.#w=!0;let r=()=>{if(!this.#w)return;let n=Atomics.load(e,t),o=Atomics.load(e,s);if(n!==o&&this.pollReplies(),!this.#w)return;let a=Atomics.load(e,t),c=Atomics.waitAsync(e,t,a);c.async?c.value.then(()=>{this.#w&&(this.pollReplies(),r())}):(this.pollReplies(),setTimeout(r,0))};r()}#Y(e){let t=this.#a.atomicView,{headIndex:s,tailIndex:r}=this.#I,n=Atomics.load(t,s),o=Atomics.load(t,r);if(n===o)return 0;let a=this.#s.bufferConstants,c=this.#s.ringBufferBase+a.REPLY_CHANNELS_BUFFER_START+this.#h*a.REPLY_CHANNEL_BUFFER_SIZE,u=a.REPLY_CHANNEL_BUFFER_SIZE,l=this.#a.uint8View,{newTail:f,messagesRead:h}=rt({uint8View:l,dataView:this.#a.dataView,bufferStart:c,bufferSize:u,head:n,tail:o,messageMagic:a.MESSAGE_MAGIC,paddingMagic:a.PADDING_MAGIC,headerSize:a.MESSAGE_HEADER_SIZE||16,maxMessages:64,onMessage:(y,p,d)=>{e(l,y,p,d)}});return h>0&&Atomics.store(t,r,f),h}#F(){if(this.#C)return;let e=this.#B||this.#e;if(!e)throw new Error("No port available for reply registration");let t=new MessageChannel;e.postMessage({type:"addReplyPort",sourceId:this.#n},[t.port1]),this.#C=t.port2;let s=typeof AudioWorkletGlobalScope<"u";this.#C.onmessage=r=>{if(r.data.type!=="oscReplies"||!r.data.count)return;let{count:n,buffer:o,messages:a}=r.data;if(!a||!o)return;let c=new Uint8Array(o);if(s)for(let u=0;u<n;u++){let l=a[u];if(!l)continue;let f=c.slice(l.offset,l.offset+l.length);this.#R.push({oscData:f,sequence:l.sequence})}else{let u=this.#f;if(!u)return;for(let l=0;l<n;l++){let f=a[l];if(!f)continue;let h=c.slice(f.offset,f.offset+f.length);u(h,f.sequence)}}}}#$(){if(this.#C){let e=this.#B||this.#e;e&&e.postMessage({type:"removeReplyPort",sourceId:this.#n}),this.#C.close(),this.#C=null}this.#R.length=0}#v(e){let t=this.#R,s=t.length;if(s===0)return 0;for(let r=0;r<s;r++)e(t[r].oscData,t[r].sequence);return t.length=0,s}close(){this.clearReplyHandler(),this.#r==="postMessage"&&this.#e&&(this.#e.close(),this.#e=null),this.#o&&(this.#o.close(),this.#o=null)}static createPostMessage(e){return e instanceof MessagePort?new i("postMessage",{port:e}):new i("postMessage",e)}static createSAB(e){let t=e.controlIndices;return t||(t=K(e.ringBufferBase,e.bufferConstants.CONTROL_START)),new i("sab",{sharedBuffer:e.sharedBuffer,ringBufferBase:e.ringBufferBase,bufferConstants:e.bufferConstants,controlIndices:t,preschedulerPort:e.preschedulerPort,bypassLookaheadS:e.bypassLookaheadS,sourceId:e.sourceId,blocking:e.blocking,replyNotifier:e.replyNotifier})}static fromTransferable(e){return e.mode==="postMessage"?new i("postMessage",{port:e.port,preschedulerPort:e.preschedulerPort,bypassLookaheadS:e.bypassLookaheadS,sourceId:e.sourceId,blocking:e.blocking,nodeIdRange:e.nodeIdRange,nodeIdPort:e.nodeIdPort}):new i("sab",{sharedBuffer:e.sharedBuffer,ringBufferBase:e.ringBufferBase,bufferConstants:e.bufferConstants,controlIndices:e.controlIndices,preschedulerPort:e.preschedulerPort,bypassLookaheadS:e.bypassLookaheadS,sourceId:e.sourceId,blocking:e.blocking})}};var G=class extends R{#r;#e;#s;#a;#o;#c;#i;#n;#u;#l;#y;#S;#g;#d=[];#E;#p;#_;#T=1;#t=!1;#f;#h=0;#m=0;#b=0;#A=null;constructor(e){if(super({...e,mode:"sab"}),this.#r=e.sharedBuffer,this.#e=e.ringBufferBase,this.#s=e.bufferConstants,this.#S=e.workerBaseURL,this.#f=e.preschedulerCapacity||65536,!(this.#r instanceof SharedArrayBuffer))throw new Error("SABTransport requires a SharedArrayBuffer");this.#w()}async initialize(){if(this.#t)return;let[e,t,s,r]=await Promise.all([I(this.#S+"osc_out_prescheduler_worker.js",{type:"module"}),I(this.#S+"osc_in_worker.js",{type:"module"}),I(this.#S+"debug_worker.js",{type:"module"}),I(this.#S+"osc_out_log_sab_worker.js",{type:"module"})]);this.#n=e,this.#u=t,this.#l=s,this.#y=r,this.#R(),await Promise.all([this.#C(this.#n,"OSC OUT",{maxPendingMessages:this.#f,bypassLookaheadS:this._config.bypassLookaheadS}),this.#C(this.#u,"OSC IN"),this.#C(this.#l,"DEBUG"),this.#C(this.#y,"OSC OUT LOG")]),this.#u.postMessage({type:"start"}),this.#l.postMessage({type:"start"}),this.#y.postMessage({type:"start"}),this.#t=!0}send(e,t){return!this.#t||this._disposed?!1:(this.#n.postMessage({type:"send",oscData:e,sessionId:0,runTag:"",audioTimeS:null,currentTimeS:null}),this.#h++,this.#b+=e.length,!0)}sendWithOptions(e,t={}){if(!this.#t||this._disposed)return!1;let{sessionId:s=0,runTag:r="",audioTimeS:n=null,currentTimeS:o=null}=t;return this.#n.postMessage({type:"send",oscData:e,sessionId:s,runTag:r,audioTimeS:n,currentTimeS:o}),this.#h++,this.#b+=e.length,!0}sendImmediate(e){return!this.#t||this._disposed?!1:(this.#n.postMessage({type:"sendImmediate",oscData:e}),this.#h++,this.#b+=e.length,!0)}createOscChannel(e={}){if(!this.#t)throw new Error("Transport not initialized");let t=e.sourceId??this.#T++,s=new MessageChannel;this.#n.postMessage({type:"addOscSource"},[s.port1]);let r=this.#d;return O.createSAB({sharedBuffer:this.#r,ringBufferBase:this.#e,bufferConstants:this.#s,controlIndices:this.#i,preschedulerPort:s.port2,bypassLookaheadS:this._config.bypassLookaheadS,sourceId:t,blocking:e.blocking,replyNotifier:{subscribe(n){r.push(n)},unsubscribe(n){let o=r.indexOf(n);o>=0&&r.splice(o,1)}}})}cancelSessionTag(e,t){this.#t&&this.#n.postMessage({type:"cancelSessionTag",sessionId:e,runTag:t})}cancelSession(e){this.#t&&this.#n.postMessage({type:"cancelSession",sessionId:e})}cancelTag(e){this.#t&&this.#n.postMessage({type:"cancelTag",runTag:e})}cancelAll(){this.#t&&this.#n.postMessage({type:"cancelAll"})}cancelAllWithAck(){return this.#t?new Promise(e=>{let t=s=>{s.data.type==="cancelAllAck"&&(this.#n.removeEventListener("message",t),e())};this.#n.addEventListener("message",t),this.#n.postMessage({type:"cancelAll",ack:!0})}):Promise.resolve()}onReply(e){this.#g=e}onDebug(e){this.#E=e}onError(e){this.#p=e}onOscLog(e){this.#_=e}handleOscLog(e){this.#_&&this.#_(e)}getMetrics(){return{oscOutMessagesSent:this.#h,oscOutMessagesDropped:this.#m,oscOutBytesSent:this.#b}}get ready(){return this.#t&&!this._disposed}dispose(){this._disposed||(this.#n&&(this.#n.postMessage({type:"stop"}),this.#n.terminate(),this.#n=null),this.#u&&(this.#u.postMessage({type:"stop"}),this.#u.terminate(),this.#u=null),this.#l&&(this.#l.postMessage({type:"stop"}),this.#l.terminate(),this.#l=null),this.#y&&(this.#y.postMessage({type:"stop"}),this.#y.terminate(),this.#y=null),this.#t=!1,super.dispose())}#w(){this.#a=new Int32Array(this.#r),this.#o=new DataView(this.#r),this.#c=new Uint8Array(this.#r),this.#i=K(this.#e,this.#s.CONTROL_START)}#C(e,t,s={}){return new Promise((r,n)=>{let o=setTimeout(()=>{n(new Error(`${t} worker initialization timeout`))},5e3),a=c=>{c.data.type==="initialized"&&(clearTimeout(o),e.removeEventListener("message",a),r())};e.addEventListener("message",a),e.postMessage({type:"init",sharedBuffer:this.#r,ringBufferBase:this.#e,bufferConstants:this.#s,...s})})}#R(){this.#u.onmessage=e=>{let t=e.data;if(t.type==="messages"){this.#g&&t.messages.forEach(s=>{s.oscData&&this.#g(s.oscData,s.sequence,s.timestamp)});for(let s=0;s<this.#d.length;s++)this.#d[s]()}else t.type==="error"&&(console.error("[SABTransport] OSC IN error:",t.error),this.#p&&this.#p(t.error,"oscIn"))},this.#l.onmessage=e=>{let t=e.data;t.type==="debug"&&this.#E?t.messages.forEach(s=>{this.#E(s)}):t.type==="error"&&(console.error("[SABTransport] DEBUG error:",t.error),this.#p&&this.#p(t.error,"debug"))},this.#n.onmessage=e=>{let t=e.data;t.type==="preschedulerMetrics"?this.#A=t.metrics:t.type==="error"&&(console.error("[SABTransport] OSC OUT error:",t.error),this.#m++,this.#p&&this.#p(t.error,"oscOut"))},this.#y.onmessage=e=>{let t=e.data;t.type==="oscLog"&&this.#_?this.#_(t.entries):t.type==="error"&&(console.error("[SABTransport] OSC OUT LOG error:",t.error),this.#p&&this.#p(t.error,"oscOutLog"))}}getPreschedulerMetrics(){return this.#A}};var z=class extends R{#r;#e;#s;#a;#o;#c;#i;#n=1;#u=null;#l=!1;#y;#S;#g=null;#d=0;#E=0;#p=0;#_=0;#T=0;#t=-1;#f=0;#h=0;#m;#b;constructor(e){super({...e,mode:"postMessage"}),this.#s=e.workerBaseURL,this.#y=e.preschedulerCapacity||65536,this.#S=e.snapshotIntervalMs,this.#m=e.getAudioContextTime,this.#b=e.getNTPStartTime}async initialize(e){if(this.#l)return;if(!e)throw new Error("PostMessageTransport requires workletPort");this.#r=e,this.#r.onmessage=s=>{this.#w(s.data)};let t=new MessageChannel;this.#r.postMessage({type:"addOscPort"},[t.port1]),this.#e=await I(this.#s+"osc_out_prescheduler_worker.js",{type:"module"}),this.#e.onmessage=s=>{this.#C(s.data)},await this.#A(t.port2),this.#l=!0}setBufferConstants(e){this.#g=e}send(e,t){return!this.#l||this._disposed?!1:(this.#e.postMessage({type:"send",oscData:e,sessionId:0,runTag:"",audioTimeS:null,currentTimeS:null}),this.#d++,this.#p+=e.length,!0)}sendWithOptions(e,t={}){if(!this.#l||this._disposed)return!1;let{sessionId:s=0,runTag:r="",audioTimeS:n=null,currentTimeS:o=null}=t;return this.#e.postMessage({type:"send",oscData:e,sessionId:s,runTag:r,audioTimeS:n,currentTimeS:o}),this.#d++,this.#p+=e.length,!0}sendImmediate(e,t){return!this.#l||this._disposed?!1:(this.#r.postMessage({type:"osc",oscData:e,bypassCategory:t}),this.#d++,this.#p+=e.length,!0)}createOscChannel(e={}){if(!this.#l)throw new Error("Transport not initialized");let t=e.sourceId??this.#n++,s=new MessageChannel;this.#r.postMessage({type:"addOscPort",sourceId:t},[s.port1]);let r=new MessageChannel;return this.#e.postMessage({type:"addOscSource"},[r.port1]),O.createPostMessage({port:s.port2,preschedulerPort:r.port2,bypassLookaheadS:this._config.bypassLookaheadS,sourceId:t,blocking:e.blocking,nodeIdSource:this._config.nodeIdSource,replyWorkletPort:this.#r})}cancelSessionTag(e,t){this.#l&&this.#e.postMessage({type:"cancelSessionTag",sessionId:e,runTag:t})}cancelSession(e){this.#l&&this.#e.postMessage({type:"cancelSession",sessionId:e})}cancelTag(e){this.#l&&this.#e.postMessage({type:"cancelTag",runTag:e})}cancelAll(){this.#l&&this.#e.postMessage({type:"cancelAll"})}cancelAllWithAck(){return this.#l?new Promise(e=>{let t=s=>{s.data.type==="cancelAllAck"&&(this.#e.removeEventListener("message",t),e())};this.#e.addEventListener("message",t),this.#e.postMessage({type:"cancelAll",ack:!0})}):Promise.resolve()}onReply(e){this.#a=e}onDebug(e){this.#o=e}onError(e){this.#c=e}onOscLog(e){this.#i=e}handleDebugRaw(e){if(e.messages&&e.count>0&&e.buffer){let t=new TextDecoder("utf-8"),s=new Uint8Array(e.buffer);for(let r=0;r<e.count;r++){let n=e.messages[r];try{let o=s.subarray(n.offset,n.offset+n.length),a=t.decode(o);a.endsWith(`
|
|
2
|
-
`)&&(a=a.slice(0,-1)),this.#f++,this.#h+=n.length,this.#o&&this.#o({text:a,timestamp:performance.now(),sequence:n.sequence})}catch(o){console.error("[PostMessageTransport] Failed to decode debug message:",o)}}}}getPreschedulerMetrics(){return this.#u}getMetrics(){return{oscInMessagesReceived:this.#_,oscInBytesReceived:this.#T,oscInMessagesDropped:this.#E,debugMessagesReceived:this.#f,debugBytesReceived:this.#h}}get ready(){return this.#l&&!this._disposed}dispose(){this._disposed||(this.#e&&(this.#e.postMessage({type:"stop"}),this.#e.terminate(),this.#e=null),this.#r=null,this.#l=!1,super.dispose())}#A(e){return new Promise((t,s)=>{let r=setTimeout(()=>{s(new Error("Prescheduler worker initialization timeout"))},5e3),n=o=>{o.data.type==="initialized"&&(clearTimeout(r),this.#e.removeEventListener("message",n),t())};this.#e.addEventListener("message",n),this.#e.postMessage({type:"init",mode:"postMessage",maxPendingMessages:this.#y,snapshotIntervalMs:this.#S,bypassLookaheadS:this._config.bypassLookaheadS,workletPort:e},[e])})}#w(e){switch(e.type){case"oscReplies":if(e.messages&&e.count>0&&e.buffer){let t=new Uint8Array(e.buffer);for(let s=0;s<e.count;s++){let r=e.messages[s],n=t.subarray(r.offset,r.offset+r.length);if(r.sequence!==void 0&&this.#t>=0){let o=this.#t+1&4294967295;if(r.sequence!==o){let a=r.sequence-o+4294967296&4294967295;a<1e3&&(this.#E+=a)}}r.sequence!==void 0&&(this.#t=r.sequence),this.#_++,this.#T+=r.length,this.#a&&this.#a(n,r.sequence,M())}}break;case"metrics":break;case"bufferLoaded":break;case"debugRawBatch":this.handleDebugRaw(e);break;case"oscLog":if(this.#i&&e.count>0&&e.buffer&&e.entries){let t=new Uint8Array(e.buffer),s=[];for(let r=0;r<e.count;r++){let n=e.entries[r],o=t.subarray(n.offset,n.offset+n.length);s.push({oscData:o,sourceId:n.sourceId,sequence:n.sequence,timestamp:M(),truncated:n.length<n.originalLength,originalLength:n.originalLength})}this.#i(s)}break;case"error":console.error("[PostMessageTransport] Worklet error:",e.error),this.#E++,this.#c&&this.#c(e.error,"worklet");break;case"debug":break}}#C(e){switch(e.type){case"preschedulerMetrics":this.#u=e.metrics;break;case"error":console.error("[PostMessageTransport] Prescheduler error:",e.error),this.#E++,this.#c&&this.#c(e.error,"oscOut");break}}};function lt(i,e){if(i==="sab")return new G(e);if(i==="postMessage")return new z(e);throw new Error(`Unknown transport mode: ${i}. Use 'sab' or 'postMessage'`)}var ds={5120:"i8",5121:"u8",5122:"i16",5123:"u16",5124:"i32",5125:"u32",5126:"f32"};var ut={u8:1,u8c:1,i8:1,u16:2,i16:2,u32:4,i32:4,i64:8,u64:8,f32:4,f64:8};var ps={f32:Float32Array,f64:Float64Array},ms={i8:Int8Array,i16:Int16Array,i32:Int32Array},ys={u8:Uint8Array,u8c:Uint8ClampedArray,u16:Uint16Array,u32:Uint32Array},Ss={i64:BigInt64Array,u64:BigUint64Array},Es={...ps,...ms,...ys},gs=i=>{let e=ds[i];return e!==void 0?e:i};function ft(i,...e){let t=Ss[i];return new(t||Es[gs(i)])(...e)}var Y=(i,e)=>(e--,i+e&~e);var ht=i=>typeof i=="number";var j=(i,e=t=>t!==void 0?": "+t:"")=>class extends Error{origMessage;constructor(t){super(i(t)+e(t)),this.origMessage=t!==void 0?String(t):""}};var _s=j(()=>"Assertion failed"),Te=(typeof process<"u"&&process.env!==void 0?process.env.UMBRELLA_ASSERTS:!import.meta.env||import.meta.env.MODE!=="production"||import.meta.env.UMBRELLA_ASSERTS||import.meta.env.VITE_UMBRELLA_ASSERTS)?(i,e)=>{if(typeof i=="function"&&!i()||!i)throw new _s(typeof e=="function"?e():e)}:()=>{};var bs=j(()=>"illegal argument(s)"),dt=i=>{throw new bs(i)};var pt=0,mt=1,yt=2,St=3,Et=4,v=5,gt=6,we=1,Ce=2,_t=7*4,Me=0,Oe=1,B=2*4,Q=class{buf;start;u8;u32;state;constructor(e={}){if(this.buf=e.buf?e.buf:new ArrayBuffer(e.size||4096),this.start=e.start!=null?Y(Math.max(e.start,0),4):0,this.u8=new Uint8Array(this.buf),this.u32=new Uint32Array(this.buf),this.state=new Uint32Array(this.buf,this.start,_t/4),!e.skipInitialization){let t=e.align||8;Te(t>=8,`invalid alignment: ${t}, must be a pow2 and >= 8`);let s=this.initialTop(t),r=e.end!=null?Math.min(e.end,this.buf.byteLength):this.buf.byteLength;s>=r&&dt(`insufficient address range (0x${this.start.toString(16)} - 0x${r.toString(16)})`),this.align=t,this.doCompact=e.compact!==!1,this.doSplit=e.split!==!1,this.minSplit=e.minSplit||16,this.end=r,this.top=s,this._free=0,this._used=0}}stats(){let e=s=>{let r=0,n=0;for(;s;)r++,n+=this.blockSize(s),s=this.blockNext(s);return{count:r,size:n}},t=e(this._free);return{free:t,used:e(this._used),top:this.top,available:this.end-this.top+t.size,total:this.buf.byteLength}}callocAs(e,t,s=0){let r=this.mallocAs(e,t);return r?.fill(s),r}mallocAs(e,t){let s=this.malloc(t*ut[e]);return s?ft(e,this.buf,s,t):void 0}calloc(e,t=0){let s=this.malloc(e);return s&&this.u8.fill(t,s,s+e),s}malloc(e){if(e<=0)return 0;let t=Y(e+B,this.align),s=this.end,r=this.top,n=this._free,o=0;for(;n;){let a=this.blockSize(n),c=n+a>=r;if(c||a>=t)return this.mallocTop(n,o,a,t,c);o=n,n=this.blockNext(n)}return n=r,r=n+t,r<=s?(this.initBlock(n,t,this._used),this._used=n,this.top=r,$(n)):0}mallocTop(e,t,s,r,n){if(n&&e+r>this.end)return 0;if(t?this.unlinkBlock(t,e):this._free=this.blockNext(e),this.setBlockNext(e,this._used),this._used=e,n)this.top=e+this.setBlockSize(e,r);else if(this.doSplit){let o=s-r;o>=this.minSplit&&this.splitBlock(e,r,o)}return $(e)}realloc(e,t){if(t<=0)return 0;let s=Be(e),r=0,n=this._used,o=0;for(;n;){if(n===s){[r,o]=this.reallocBlock(n,t);break}n=this.blockNext(n)}return r&&r!==s&&this.u8.copyWithin($(r),$(s),o),$(r)}reallocBlock(e,t){let s=this.blockSize(e),r=e+s,n=r>=this.top,o=Y(t+B,this.align);if(o<=s){if(this.doSplit){let a=s-o;a>=this.minSplit?this.splitBlock(e,o,a):n&&(this.top=e+o)}else n&&(this.top=e+o);return[e,r]}return n&&e+o<this.end?(this.top=e+this.setBlockSize(e,o),[e,r]):(this.free(e),[Be(this.malloc(t)),r])}reallocArray(e,t){if(e.buffer!==this.buf)return;let s=this.realloc(e.byteOffset,t*e.BYTES_PER_ELEMENT);return s?new e.constructor(this.buf,s,t):void 0}free(e){let t;if(ht(e))t=e;else{if(e.buffer!==this.buf)return!1;t=e.byteOffset}t=Be(t);let s=this._used,r=0;for(;s;){if(s===t)return r?this.unlinkBlock(r,s):this._used=this.blockNext(s),this.insert(s),this.doCompact&&this.compact(),!0;r=s,s=this.blockNext(s)}return!1}freeAll(){this._free=0,this._used=0,this.top=this.initialTop()}release(){return delete this.u8,delete this.u32,delete this.state,delete this.buf,!0}get align(){return this.state[Et]}set align(e){this.state[Et]=e}get end(){return this.state[St]}set end(e){this.state[St]=e}get top(){return this.state[yt]}set top(e){this.state[yt]=e}get _free(){return this.state[pt]}set _free(e){this.state[pt]=e}get _used(){return this.state[mt]}set _used(e){this.state[mt]=e}get doCompact(){return!!(this.state[v]&we)}set doCompact(e){e?this.state[v]|=1<<we-1:this.state[v]&=~we}get doSplit(){return!!(this.state[v]&Ce)}set doSplit(e){e?this.state[v]|=1<<Ce-1:this.state[v]&=~Ce}get minSplit(){return this.state[gt]}set minSplit(e){Te(e>B,`illegal min split threshold: ${e}, require at least ${B+1}`),this.state[gt]=e}blockSize(e){return this.u32[(e>>2)+Me]}setBlockSize(e,t){return this.u32[(e>>2)+Me]=t,t}blockNext(e){return this.u32[(e>>2)+Oe]}setBlockNext(e,t){this.u32[(e>>2)+Oe]=t}initBlock(e,t,s){let r=e>>>2;return this.u32[r+Me]=t,this.u32[r+Oe]=s,e}unlinkBlock(e,t){this.setBlockNext(e,this.blockNext(t))}splitBlock(e,t,s){this.insert(this.initBlock(e+this.setBlockSize(e,t),s,0)),this.doCompact&&this.compact()}initialTop(e=this.align){return Y(this.start+_t+B,e)-B}compact(){let e=this._free,t=0,s=0,r,n=!1;for(;e;){for(r=e,s=this.blockNext(e);s&&r+this.blockSize(r)===s;)r=s,s=this.blockNext(s);if(r!==e){let o=r-e+this.blockSize(r);this.setBlockSize(e,o);let a=this.blockNext(r),c=this.blockNext(e);for(;c&&c!==a;){let u=this.blockNext(c);this.setBlockNext(c,0),c=u}this.setBlockNext(e,a),n=!0}e+this.blockSize(e)>=this.top&&(this.top=e,t?this.unlinkBlock(t,e):this._free=this.blockNext(e)),t=e,e=this.blockNext(e)}return n}insert(e){let t=this._free,s=0;for(;t&&!(e<=t);)s=t,t=this.blockNext(t);s?this.setBlockNext(s,e):this._free=e,this.setBlockNext(e,t)}},$=i=>i>0?i+B:0,Be=i=>i>0?i-B:0;var Re=8,bt=65536,J=class{#r=[];#e;#s;#a=0;#o=!1;#c;#i;#n;#u;constructor({buf:e,start:t,size:s,wasmMemory:r=null,maxSize:n,growIncrement:o=32*1024*1024,growFn:a=null,onGrowth:c=null}){this.#e=r,this.#s=o,this.#c=a,this.#i=c,this.#n=t+s,this.#u=t+n,this.#l(e,t,s,0)}malloc(e){for(let t=this.#r.length-1;t>=0;t--){let s=this.#r[t],r=s.pool.malloc(e);if(r!==0)return r+s.baseOffset}return 0}free(e){for(let t of this.#r)if(e>=t.start&&e<t.end)return t.pool.free(e-t.baseOffset);return!1}stats(){let e=0,t=0,s=0,r=0,n=0,o=0,a=0;for(let c of this.#r){let u=c.pool.stats();e+=u.free?.count||0,t+=u.free?.size||0,s+=u.used?.count||0,r+=u.used?.size||0,n+=u.available||0,o+=u.total||0,u.top>a&&(a=u.top)}return{free:{count:e,size:t},used:{count:s,size:r},top:a,available:n,total:o}}canGrow(){return this.#n+Re<this.#u}async grow(e=0){if(this.#o||!this.canGrow())return!1;this.#o=!0;try{let t=this.#u-this.#n,s=Math.min(Math.max(this.#s,e),t);if(s<Re)return!1;let r=Math.ceil(s/bt),n=this.#n,o=Math.min(r*bt,this.#u-n),a;if(this.#e){if(this.#e.grow(r)===-1)return!1;a=this.#e.buffer}else if(this.#c){if(!await this.#c(r))return!1;a=new ArrayBuffer(o)}else return!1;let c=this.#e?0:n,u=this.#e?n:0;return this.#l(a,u,o,c),this.#n=n+o,this.#a++,this.#i&&this.#i({poolIndex:this.#r.length-1,newBytes:o,totalCapacity:this.totalCapacity}),!0}finally{this.#o=!1}}get poolCount(){return this.#r.length}get growthCount(){return this.#a}get totalCapacity(){let e=0;for(let t of this.#r)e+=t.end-t.start;return e}get maxCapacity(){return this.#u-this.#r[0].start}#l(e,t,s,r){let n=new Q({buf:e,start:t,size:s,align:Re}),o=t+r;this.#r.push({pool:n,start:o,end:o+s,baseOffset:r})}};function At(i){if(i.byteLength<12)return!1;let e=new Uint8Array(i,0,12),t=String.fromCharCode(e[0],e[1],e[2],e[3]),s=String.fromCharCode(e[8],e[9],e[10],e[11]);return t==="FORM"&&(s==="AIFF"||s==="AIFC")}function As(i){let e=i[0]>>7&1,t=(i[0]&127)<<8|i[1],s=0;for(let n=2;n<10;n++)s=s*256+i[n];if(t===0)return 0;let r=s*Math.pow(2,t-16383-63);return e?-r:r}function Tt(i,e){let t=12;for(;t<i.byteLength-8;){let s=String.fromCharCode(i.getUint8(t),i.getUint8(t+1),i.getUint8(t+2),i.getUint8(t+3)),r=i.getUint32(t+4,!1);if(s===e)return{offset:t+8,size:r};t+=8+r+r%2}return null}function wt(i){let e=new DataView(i),t=String.fromCharCode(e.getUint8(8),e.getUint8(9),e.getUint8(10),e.getUint8(11)),s=Tt(e,"COMM");if(!s)throw new Error("AIFF file missing COMM chunk");let r=e.getUint16(s.offset,!1),n=e.getUint32(s.offset+2,!1),o=e.getUint16(s.offset+6,!1),a=new Uint8Array(i,s.offset+8,10),c=As(a);if(t==="AIFC"&&s.size>=22){let d=String.fromCharCode(e.getUint8(s.offset+18),e.getUint8(s.offset+19),e.getUint8(s.offset+20),e.getUint8(s.offset+21));if(d!=="NONE"&&d!=="sowt")throw new Error(`AIFC compression type '${d}' is not supported. Only uncompressed AIFF/AIFC files are supported.`);if(d==="sowt")return Ts(i,r,n,o,c)}let{wavBuffer:u,wavBytes:l,srcBytes:f,audioDataSize:h,bytesPerSample:y,wavHeaderSize:p}=Ct(i,r,n,o,c);if(y===1)for(let d=0;d<h;d++)l[p+d]=f[d]+128;else if(y===2)for(let d=0;d<h;d+=2)l[p+d]=f[d+1],l[p+d+1]=f[d];else if(y===3)for(let d=0;d<h;d+=3)l[p+d]=f[d+2],l[p+d+1]=f[d+1],l[p+d+2]=f[d];else if(y===4)for(let d=0;d<h;d+=4)l[p+d]=f[d+3],l[p+d+1]=f[d+2],l[p+d+2]=f[d+1],l[p+d+3]=f[d];else throw new Error(`Unsupported bit depth: ${o}`);return u}function Ct(i,e,t,s,r){let n=new DataView(i),o=Tt(n,"SSND");if(!o)throw new Error("AIFF file missing SSND chunk");let a=n.getUint32(o.offset,!1),c=o.offset+8+a,u=s/8,l=t*e*u;if(c+l>i.byteLength)throw new Error("AIFF file truncated: not enough audio data");let f=44,h=new ArrayBuffer(f+l),y=new DataView(h),p=new Uint8Array(h);ws(y,{numChannels:e,sampleRate:Math.round(r),bitsPerSample:s,dataSize:l});let d=new Uint8Array(i,c,l);return{wavBuffer:h,wavBytes:p,srcBytes:d,audioDataSize:l,bytesPerSample:u,wavHeaderSize:f}}function Ts(i,e,t,s,r){let{wavBuffer:n,wavBytes:o,srcBytes:a,audioDataSize:c,bytesPerSample:u,wavHeaderSize:l}=Ct(i,e,t,s,r);if(u===1)for(let f=0;f<c;f++)o[l+f]=a[f]+128;else o.set(a,l);return n}function ws(i,{numChannels:e,sampleRate:t,bitsPerSample:s,dataSize:r}){let n=t*e*(s/8),o=e*(s/8);i.setUint8(0,82),i.setUint8(1,73),i.setUint8(2,70),i.setUint8(3,70),i.setUint32(4,36+r,!0),i.setUint8(8,87),i.setUint8(9,65),i.setUint8(10,86),i.setUint8(11,69),i.setUint8(12,102),i.setUint8(13,109),i.setUint8(14,116),i.setUint8(15,32),i.setUint32(16,16,!0),i.setUint16(20,1,!0),i.setUint16(22,e,!0),i.setUint32(24,t,!0),i.setUint32(28,n,!0),i.setUint16(32,o,!0),i.setUint16(34,s,!0),i.setUint8(36,100),i.setUint8(37,97),i.setUint8(38,116),i.setUint8(39,97),i.setUint32(40,r,!0)}var ee=class{#r;#e;#s;#a;#o;#c;#i;#n;#u;#l;#y;constructor(e){let{mode:t="sab",audioContext:s,sharedBuffer:r,bufferPoolConfig:n,sampleBaseURL:o,maxBuffers:a=1024,assetLoader:c=null,workletPort:u=null,wasmMemory:l=null,maxBufferMemory:f=null,bufferGrowIncrement:h=32*1024*1024,onBufferPoolGrowth:y=null,growFn:p=null}=e;if(this.#r=t,!s)throw new Error("BufferManager requires audioContext");if(t==="sab"){if(!r||!(r instanceof SharedArrayBuffer))throw new Error("BufferManager requires sharedBuffer (SharedArrayBuffer) in SAB mode");if(!n||typeof n!="object")throw new Error("BufferManager requires bufferPoolConfig (object with start, size, align)");if(!Number.isFinite(n.start)||n.start<0)throw new Error("bufferPoolConfig.start must be a non-negative number");if(!Number.isFinite(n.size)||n.size<=0)throw new Error("bufferPoolConfig.size must be a positive number")}if(t==="postMessage"&&(!n||typeof n!="object"))throw new Error("BufferManager requires bufferPoolConfig in postMessage mode");if(!Number.isInteger(a)||a<=0)throw new Error("maxBuffers must be a positive integer");this.#a=s,this.#o=r,this.#c=l,this.#e=o,this.#s=c,this.#y=u;let d=f||n.maxSize||n.size,m=t==="sab"?r:new ArrayBuffer(n.start+n.size);this.#i=new J({buf:m,start:n.start,size:n.size,wasmMemory:t==="sab"?l:null,maxSize:d,growIncrement:h,growFn:t==="postMessage"?p:null,onGrowth:y}),this.#n=new Map,this.#u=new Map,this.#l=new Map,this.GUARD_BEFORE=3,this.GUARD_AFTER=1,this.MAX_BUFFERS=a;let E=(n.size/(1024*1024)).toFixed(0),_=(n.start/(1024*1024)).toFixed(0)}async#S(e){let t=e.byteOffset===0&&e.byteLength===e.buffer.byteLength?e.buffer:e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),s=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(s)).map(r=>r.toString(16).padStart(2,"0")).join("")}async#g({source:e,startFrame:t=0,numFrames:s=0,channels:r=null}){let n,o;if(typeof e=="string"){let m=this.#_(e),E=e.split("/").pop();n=await this.#s.fetch(m,{type:"sample",name:E}),o={type:"file",path:e,startFrame:t,numFrames:s,channels:r}}else n=e instanceof ArrayBuffer?e:e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),o=null;let a=await this.#p(n),c=Math.max(0,Math.floor(t||0)),u=a.length-c,l=s&&s>0?Math.min(Math.floor(s),u):u;if(l<=0)throw new Error("No audio frames available");let f=this.#f(r,a.numberOfChannels),h=f.length,y=l*h+(this.GUARD_BEFORE+this.GUARD_AFTER)*h,p=new Float32Array(y),d=this.GUARD_BEFORE*h;for(let m=0;m<l;m++)for(let E=0;E<h;E++){let _=a.getChannelData(f[E]);p[d+m*h+E]=_[c+m]}return{interleaved:p,numFrames:l,numChannels:h,sampleRate:a.sampleRate,sourceInfo:o}}async#d(e){let t=await this.#m(e.length);return await this.#b(t,e),t}async#E(e,t,s,r){let n,o=await this.#t(e,t,async()=>{let[c,u]=await Promise.all([this.#S(s.interleaved),this.#d(s.interleaved)]);return n=c,{ptr:u,sizeBytes:s.interleaved.length*4,numFrames:s.numFrames,numChannels:s.numChannels,sampleRate:s.sampleRate,source:r||null}}),a=this.#n.get(e);return a&&(a.hash=n),{...o,hash:n}}async#p(e){return At(e)&&(e=wt(e)),this.#a.decodeAudioData(e)}setWorkletPort(e){if(this.#r==="postMessage"){if(!e)throw new Error("BufferManager.setWorkletPort() requires a valid port");this.#y=e}}#_(e){if(typeof e!="string"||e.length===0)throw new Error("Invalid audio path: must be a non-empty string");if(e.includes(".."))throw new Error(`Invalid audio path: path cannot contain '..' (got: ${e})`);if(e.includes("%2e")||e.includes("%2E"))throw new Error(`Invalid audio path: path cannot contain URL-encoded characters (got: ${e})`);if(e.includes("\\"))throw new Error(`Invalid audio path: use forward slashes only (got: ${e})`);if(e.includes("://")||e.startsWith("/")||e.startsWith("./"))return e;if(!this.#e)throw new Error(`sampleBaseURL not configured. Please set it in SuperSonic constructor options.
|
|
1
|
+
var R=class i{constructor(e){if(new.target===i)throw new Error("Transport is abstract - use SABTransport or PostMessageTransport");this._config=e,this._disposed=!1}get mode(){return this._config.mode}send(e,t){throw new Error("Abstract method - implement in subclass")}onReply(e){throw new Error("Abstract method - implement in subclass")}onDebug(e){throw new Error("Abstract method - implement in subclass")}onError(e){throw new Error("Abstract method - implement in subclass")}getMetrics(){throw new Error("Abstract method - implement in subclass")}async initialize(){throw new Error("Abstract method - implement in subclass")}createOscChannel(){throw new Error("Abstract method - implement in subclass")}dispose(){this._disposed=!0}get ready(){throw new Error("Abstract method - implement in subclass")}};var _e=new Map;function et(i){try{return new URL(i,window.location.href).origin!==window.location.origin}catch{return!1}}async function tt(i){if(_e.has(i))return _e.get(i);let e=await fetch(i);if(!e.ok)throw new Error(`Failed to fetch ${i}: ${e.status} ${e.statusText}`);let t=await e.text(),s=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(s);return _e.set(i,r),r}async function I(i,e={}){let t=i;return et(i)&&(t=await tt(i)),new Worker(t,e)}async function st(i,e){let t=e;et(e)&&(t=await tt(e)),await i.addModule(t)}function as(i,e,t){return(t-1-i+e)%t}function cs({uint8View:i,dataView:e,bufferStart:t,bufferSize:s,head:r,payload:n,sequence:o,messageMagic:a,headerSize:c,sourceId:u=0,headerScratch:l=null,headerScratchView:f=null}){let h=n.length,p=c+h+3&-4,d=s-r;if(p>d){let m=l||new Uint8Array(c),E=f||new DataView(m.buffer);E.setUint32(0,a,!0),E.setUint32(4,p,!0),E.setUint32(8,o,!0),E.setUint32(12,u,!0);let g=t+r,w=t;if(d>=c){i.set(m,g);let C=d-c;for(let _=0;_<C;_++)i[g+c+_]=n[_];for(let _=C;_<h;_++)i[w+_-C]=n[_]}else{for(let _=0;_<d;_++)i[g+_]=m[_];for(let _=d;_<c;_++)i[w+_-d]=m[_];let C=c-d;i.set(n,w+C)}}else{let m=t+r;e.setUint32(m,a,!0),e.setUint32(m+4,p,!0),e.setUint32(m+8,o,!0),e.setUint32(m+12,u,!0),i.set(n,m+c)}return(r+p)%s}function rt({uint8View:i,dataView:e,bufferStart:t,bufferSize:s,head:r,tail:n,messageMagic:o,paddingMagic:a,headerSize:c,maxMessages:u=1/0,onMessage:l,onCorruption:f}){let h=n,y=0,p=d=>{let m=d;if(m+4<=s)return e.getUint32(t+m,!0);let E=0;for(let g=0;g<4;g++)E|=i[t+(m+g)%s]<<g*8;return E};for(;h!==r&&y<u;){let d=s-h,m;if(d>=4?m=e.getUint32(t+h,!0):m=p(h),m===a){h=0;continue}if(m!==o){f&&f(h),h=(h+1)%s;continue}let E=p((h+4)%s),g=p((h+8)%s),w=p((h+12)%s);if(E<c||E>s){f&&f(h),h=(h+1)%s;continue}let C=E-c,_=t+(h+c)%s;l(_,C,g,w),h=(h+E)%s,y++}return{newTail:h,messagesRead:y}}function ls(i,e,t=0,s=!1){for(let r=0;r<=t;r++)if(Atomics.compareExchange(i,e,0,1)===0)return!0;if(s){for(let n=0;n<100;n++)if(Atomics.wait(i,e,1,100),Atomics.compareExchange(i,e,0,1)===0)return!0;return console.error("[RingBuffer] Lock acquisition timeout after 10s - possible deadlock"),!1}return!1}function us(i,e){Atomics.store(i,e,0),Atomics.notify(i,e,1)}function it({atomicView:i,dataView:e,uint8View:t,bufferConstants:s,ringBufferBase:r,controlIndices:n,oscMessage:o,sourceId:a=0,maxSpins:c=0,useWait:u=!1,headerScratch:l=null,headerScratchView:f=null}){let h=o.length,y=s.MESSAGE_HEADER_SIZE+h;if(y>s.IN_BUFFER_SIZE-s.MESSAGE_HEADER_SIZE||!ls(i,n.IN_WRITE_LOCK,c,u))return!1;try{let p=Atomics.load(i,n.IN_HEAD),d=Atomics.load(i,n.IN_TAIL),m=y+3&-4;if(as(p,d,s.IN_BUFFER_SIZE)<m)return!1;let g=Atomics.add(i,n.IN_SEQUENCE,1),w=cs({uint8View:t,dataView:e,bufferStart:r+s.IN_BUFFER_START,bufferSize:s.IN_BUFFER_SIZE,head:p,payload:o,sequence:g,messageMagic:s.MESSAGE_MAGIC,headerSize:s.MESSAGE_HEADER_SIZE,sourceId:a,headerScratch:l,headerScratchView:f});return Atomics.load(i,n.IN_HEAD),Atomics.store(i,n.IN_HEAD,w),Atomics.notify(i,n.IN_HEAD,1),!0}finally{us(i,n.IN_WRITE_LOCK)}}function ot(i,e,t,s){let r=i+e+s*t;return{controlBase:r,headIndex:(r+0)/4,tailIndex:(r+4)/4,activeIndex:(r+8)/4,dropsIndex:(r+12)/4}}function K(i,e){let t=i+e;return{IN_HEAD:(t+0)/4,IN_TAIL:(t+4)/4,IN_SEQUENCE:(t+24)/4,IN_WRITE_LOCK:(t+40)/4,IN_LOG_TAIL:(t+44)/4}}function at(i,e){let t=i+e;return{IN_HEAD:(t+0)/4,IN_TAIL:(t+4)/4,OUT_HEAD:(t+8)/4,OUT_TAIL:(t+12)/4,DEBUG_HEAD:(t+16)/4,DEBUG_TAIL:(t+20)/4,IN_SEQUENCE:(t+24)/4,OUT_SEQUENCE:(t+28)/4,DEBUG_SEQUENCE:(t+32)/4,STATUS_FLAGS:(t+36)/4,IN_WRITE_LOCK:(t+40)/4,IN_LOG_TAIL:(t+44)/4}}function fs(i){return i.length>=8&&i[0]===35&&i[1]===98&&i[2]===117&&i[3]===110&&i[4]===100&&i[5]===108&&i[6]===101&&i[7]===0}var ge=.5;function be(i){if(i.length<16)return null;let e=new DataView(i.buffer,i.byteOffset,i.byteLength);return{ntpSeconds:e.getUint32(8,!1),ntpFraction:e.getUint32(12,!1)}}function M(){return(performance.timeOrigin+performance.now())/1e3+2208988800}function ct(i,e={}){let{getCurrentNTP:t=M,bypassLookaheadS:s=ge}=e;if(!fs(i))return"nonBundle";let r=be(i);if(!r)return"nonBundle";let{ntpSeconds:n,ntpFraction:o}=r;if(n===0&&o<=1)return"immediate";let a=t();if(a===null||a===0)return"immediate";let u=n+o/4294967296-a,l=128/48e3;return u<-l?"late":u<s?"nearFuture":"farFuture"}function Z(i){return i!=="farFuture"}var hs={nonBundle:38,immediate:39,nearFuture:40,late:41},O=class i{#r;#e;#s;#a;#o;#c;#i;#n;#u;#l;#y;#S;#_;#d;#E;#p;#g;#T;#t;#f;#h=-1;#m;#b;#A;#w;#C;#R=[];#B;#I;#O={messagesSent:0,bytesSent:0,nonBundle:0,immediate:0,nearFuture:0,late:0,bypassed:0};constructor(e,t){if(this.#r=e,this.#o=t.preschedulerPort||null,this.#i=t.bypassLookaheadS??ge,this.#n=t.sourceId??0,this.#u=t.blocking??this.#n!==0,this.#l=t.getCurrentNTP??M,this.#E=1e3,e==="postMessage")this.#e=t.port;else{if(this.#s={sharedBuffer:t.sharedBuffer,ringBufferBase:t.ringBufferBase,bufferConstants:t.bufferConstants,controlIndices:t.controlIndices},this.#P(),this.#b=t.replyNotifier||null,t.sharedBuffer&&t.bufferConstants){let s=t.ringBufferBase+t.bufferConstants.METRICS_START;this.#c=new Int32Array(t.sharedBuffer,s,t.bufferConstants.METRICS_SIZE/4)}if(t.sharedBuffer&&t.bufferConstants?.NODE_ID_COUNTER_START!==void 0){let s=t.ringBufferBase+t.bufferConstants.NODE_ID_COUNTER_START;this.#y=new Int32Array(t.sharedBuffer,s,1),this.#L()}}t.nodeIdSource&&(this.#p=t.nodeIdSource,this.#L()),t.nodeIdRange&&(this.#S=t.nodeIdRange.from,this.#_=t.nodeIdRange.to,this.#d=t.nodeIdRange.from),t.replyWorkletPort&&(this.#B=t.replyWorkletPort),t.nodeIdPort&&(this.#g=t.nodeIdPort,this.#g.onmessage=s=>{s.data.type==="nodeIdRange"&&(this.#T={from:s.data.from,to:s.data.to})},this.#k())}#P(){let e=this.#s.sharedBuffer,t=this.#s.bufferConstants.MESSAGE_HEADER_SIZE||16,s=new Uint8Array(t);this.#a={atomicView:new Int32Array(e),dataView:new DataView(e),uint8View:new Uint8Array(e),headerScratch:s,headerScratchView:new DataView(s.buffer)}}classify(e){return ct(e,{getCurrentNTP:this.#l,bypassLookaheadS:this.#i})}#D(e,t=null){if(this.#r==="sab"&&this.#c){if(Atomics.add(this.#c,24,1),Atomics.add(this.#c,25,e),t){let s=hs[t];s!==void 0&&(Atomics.add(this.#c,s,1),Atomics.add(this.#c,22,1))}}else this.#O.messagesSent++,this.#O.bytesSent+=e,t&&t in this.#O&&(this.#O[t]++,this.#O.bypassed++)}getAndResetMetrics(){let e={...this.#O};return this.#O={messagesSent:0,bytesSent:0,nonBundle:0,immediate:0,nearFuture:0,late:0,bypassed:0},e}getMetrics(){return this.#r==="sab"&&this.#c?{messagesSent:Atomics.load(this.#c,24),bytesSent:Atomics.load(this.#c,25),nonBundle:Atomics.load(this.#c,38),immediate:Atomics.load(this.#c,39),nearFuture:Atomics.load(this.#c,40),late:Atomics.load(this.#c,41),bypassed:Atomics.load(this.#c,22)}:{...this.#O}}#U(e,t=null,s=!0){if(this.#r==="postMessage")return this.#e?(this.#e.postMessage({type:"osc",oscData:e,bypassCategory:t,sourceId:this.#n}),!0):!1;{let r=this.#u,n=it({atomicView:this.#a.atomicView,dataView:this.#a.dataView,uint8View:this.#a.uint8View,bufferConstants:this.#s.bufferConstants,ringBufferBase:this.#s.ringBufferBase,controlIndices:this.#s.controlIndices,oscMessage:e,sourceId:this.#n,maxSpins:r?10:0,useWait:r,headerScratch:this.#a.headerScratch,headerScratchView:this.#a.headerScratchView});return!n&&!r&&s&&this.#o?(this.#c&&Atomics.add(this.#c,45,1),this.#o.postMessage({type:"directDispatch",oscData:e,sourceId:this.#n}),!0):n}}#x(e){return this.#o?(this.#o.postMessage({type:"osc",oscData:e,sourceId:this.#n}),!0):(console.error("[OscChannel] No prescheduler port, sending direct"),this.#U(e))}send(e){let t=this.classify(e);if(Z(t)){let s=this.#U(e,t);return s&&this.#D(e.length,t),s}else{let s=this.#x(e);return s&&this.#D(e.length,null),s}}sendDirect(e){return this.#U(e)}sendToPrescheduler(e){return this.#x(e)}nextNodeId(){if(this.#y)return Atomics.add(this.#y,0,1);this.#d>=this.#_&&this.#L();let e=this.#d++;return this.#g&&!this.#T&&this.#_-this.#d<=this.#E>>>1&&this.#k(),e}#L(){if(this.#p){let e=this.#p(this.#E);this.#S=e.from,this.#_=e.to,this.#d=e.from}else if(this.#T)this.#S=this.#T.from,this.#_=this.#T.to,this.#d=this.#T.from,this.#T=null,this.#k();else if(this.#g)throw new Error("[OscChannel] Node ID range exhausted before async refill arrived. Yield to the event loop between large batches of nextNodeId() calls.")}#k(){this.#g&&this.#g.postMessage({type:"requestNodeIdRange"})}set getCurrentNTP(e){this.#l=e}get mode(){return this.#r}get replyDrops(){if(!(this.#r!=="sab"||this.#h<0))return Atomics.load(this.#a.atomicView,this.#I.dropsIndex)}get transferable(){let e={mode:this.#r,preschedulerPort:this.#o,bypassLookaheadS:this.#i,sourceId:this.#n,blocking:this.#u};if(this.#r==="postMessage"){let t=this.#E*10,s,r;if(this.#p){let n=this.#p(t);s={from:n.from,to:n.to};let o=new MessageChannel,a=this.#p,c=this.#E;o.port1.onmessage=u=>{if(u.data.type==="requestNodeIdRange"){let l=a(c);o.port1.postMessage({type:"nodeIdRange",from:l.from,to:l.to})}},r=o.port2,this.#t=r}return{...e,port:this.#e,nodeIdRange:s,nodeIdPort:r}}else return{...e,sharedBuffer:this.#s.sharedBuffer,ringBufferBase:this.#s.ringBufferBase,bufferConstants:this.#s.bufferConstants,controlIndices:this.#s.controlIndices}}get transferList(){let e=[];return this.#r==="postMessage"&&this.#e&&e.push(this.#e),this.#o&&e.push(this.#o),this.#t&&(e.push(this.#t),this.#t=null),e}activateReplies(){this.#r==="sab"?this.#H():this.#F()}deactivateReplies(){this.#r==="sab"?this.#N():this.#$()}setReplyHandler(e){this.#f=e,this.activateReplies(),this.#G()}clearReplyHandler(){this.#f=null,this.deactivateReplies()}pollReplies(e){let t=e||this.#f;return t?this.#r==="sab"?this.#h<0?0:this.#Y(t):this.#C?this.#v(t):0:0}#H(){if(this.#h>=0)return;let e=this.#s.bufferConstants;if(!e.REPLY_CHANNEL_COUNT)throw new Error("WASM does not support reply channels");let t=this.#a.atomicView;for(let s=0;s<e.REPLY_CHANNEL_COUNT;s++){let r=ot(this.#s.ringBufferBase,e.REPLY_CHANNELS_CONTROL_START,e.REPLY_CHANNEL_CONTROL_SIZE,s);if(Atomics.store(t,r.headIndex,0),Atomics.store(t,r.tailIndex,0),Atomics.store(t,r.dropsIndex,0),Atomics.compareExchange(t,r.activeIndex,0,1)===0){this.#I=r,this.#h=s;return}}throw new Error("All "+e.REPLY_CHANNEL_COUNT+" reply channel slots are in use \u2014 cannot register for replies")}#G(){this.#A||this.#w||this.#m||typeof AudioWorkletGlobalScope<"u"||this.#r==="sab"&&(this.#b?(this.#A=()=>this.pollReplies(),this.#b.subscribe(this.#A)):typeof Atomics<"u"&&typeof Atomics.waitAsync=="function"?this.#z():this.#m=setInterval(()=>this.pollReplies(),5))}#N(){this.#h<0||(Atomics.store(this.#a.atomicView,this.#I.activeIndex,0),this.#m&&(clearInterval(this.#m),this.#m=null),this.#A&&this.#b&&(this.#b.unsubscribe(this.#A),this.#A=null),this.#w=!1,this.#h=-1,this.#I=null)}#z(){let e=this.#a.atomicView,{headIndex:t,tailIndex:s}=this.#I;this.#w=!0;let r=()=>{if(!this.#w)return;let n=Atomics.load(e,t),o=Atomics.load(e,s);if(n!==o&&this.pollReplies(),!this.#w)return;let a=Atomics.load(e,t),c=Atomics.waitAsync(e,t,a);c.async?c.value.then(()=>{this.#w&&(this.pollReplies(),r())}):(this.pollReplies(),setTimeout(r,0))};r()}#Y(e){let t=this.#a.atomicView,{headIndex:s,tailIndex:r}=this.#I,n=Atomics.load(t,s),o=Atomics.load(t,r);if(n===o)return 0;let a=this.#s.bufferConstants,c=this.#s.ringBufferBase+a.REPLY_CHANNELS_BUFFER_START+this.#h*a.REPLY_CHANNEL_BUFFER_SIZE,u=a.REPLY_CHANNEL_BUFFER_SIZE,l=this.#a.uint8View,{newTail:f,messagesRead:h}=rt({uint8View:l,dataView:this.#a.dataView,bufferStart:c,bufferSize:u,head:n,tail:o,messageMagic:a.MESSAGE_MAGIC,paddingMagic:a.PADDING_MAGIC,headerSize:a.MESSAGE_HEADER_SIZE||16,maxMessages:64,onMessage:(y,p,d)=>{e(l,y,p,d)}});return h>0&&Atomics.store(t,r,f),h}#F(){if(this.#C)return;let e=this.#B||this.#e;if(!e)throw new Error("No port available for reply registration");let t=new MessageChannel;e.postMessage({type:"addReplyPort",sourceId:this.#n},[t.port1]),this.#C=t.port2;let s=typeof AudioWorkletGlobalScope<"u";this.#C.onmessage=r=>{if(r.data.type!=="oscReplies"||!r.data.count)return;let{count:n,buffer:o,messages:a}=r.data;if(!a||!o)return;let c=new Uint8Array(o);if(s)for(let u=0;u<n;u++){let l=a[u];if(!l)continue;let f=c.slice(l.offset,l.offset+l.length);this.#R.push({oscData:f,sequence:l.sequence})}else{let u=this.#f;if(!u)return;for(let l=0;l<n;l++){let f=a[l];if(!f)continue;let h=c.slice(f.offset,f.offset+f.length);u(h,f.sequence)}}}}#$(){if(this.#C){let e=this.#B||this.#e;e&&e.postMessage({type:"removeReplyPort",sourceId:this.#n}),this.#C.close(),this.#C=null}this.#R.length=0}#v(e){let t=this.#R,s=t.length;if(s===0)return 0;for(let r=0;r<s;r++)e(t[r].oscData,t[r].sequence);return t.length=0,s}close(){this.clearReplyHandler(),this.#r==="postMessage"&&this.#e&&(this.#e.close(),this.#e=null),this.#o&&(this.#o.close(),this.#o=null)}static createPostMessage(e){return e instanceof MessagePort?new i("postMessage",{port:e}):new i("postMessage",e)}static createSAB(e){let t=e.controlIndices;return t||(t=K(e.ringBufferBase,e.bufferConstants.CONTROL_START)),new i("sab",{sharedBuffer:e.sharedBuffer,ringBufferBase:e.ringBufferBase,bufferConstants:e.bufferConstants,controlIndices:t,preschedulerPort:e.preschedulerPort,bypassLookaheadS:e.bypassLookaheadS,sourceId:e.sourceId,blocking:e.blocking,replyNotifier:e.replyNotifier})}static fromTransferable(e){return e.mode==="postMessage"?new i("postMessage",{port:e.port,preschedulerPort:e.preschedulerPort,bypassLookaheadS:e.bypassLookaheadS,sourceId:e.sourceId,blocking:e.blocking,nodeIdRange:e.nodeIdRange,nodeIdPort:e.nodeIdPort}):new i("sab",{sharedBuffer:e.sharedBuffer,ringBufferBase:e.ringBufferBase,bufferConstants:e.bufferConstants,controlIndices:e.controlIndices,preschedulerPort:e.preschedulerPort,bypassLookaheadS:e.bypassLookaheadS,sourceId:e.sourceId,blocking:e.blocking})}};var G=class extends R{#r;#e;#s;#a;#o;#c;#i;#n;#u;#l;#y;#S;#_;#d=[];#E;#p;#g;#T=1;#t=!1;#f;#h=0;#m=0;#b=0;#A=null;constructor(e){if(super({...e,mode:"sab"}),this.#r=e.sharedBuffer,this.#e=e.ringBufferBase,this.#s=e.bufferConstants,this.#S=e.workerBaseURL,this.#f=e.preschedulerCapacity||65536,!(this.#r instanceof SharedArrayBuffer))throw new Error("SABTransport requires a SharedArrayBuffer");this.#w()}async initialize(){if(this.#t)return;let[e,t,s,r]=await Promise.all([I(this.#S+"osc_out_prescheduler_worker.js",{type:"module"}),I(this.#S+"osc_in_worker.js",{type:"module"}),I(this.#S+"debug_worker.js",{type:"module"}),I(this.#S+"osc_out_log_sab_worker.js",{type:"module"})]);this.#n=e,this.#u=t,this.#l=s,this.#y=r,this.#R(),await Promise.all([this.#C(this.#n,"OSC OUT",{maxPendingMessages:this.#f,bypassLookaheadS:this._config.bypassLookaheadS}),this.#C(this.#u,"OSC IN"),this.#C(this.#l,"DEBUG"),this.#C(this.#y,"OSC OUT LOG")]),this.#u.postMessage({type:"start"}),this.#l.postMessage({type:"start"}),this.#y.postMessage({type:"start"}),this.#t=!0}send(e,t){return!this.#t||this._disposed?!1:(this.#n.postMessage({type:"send",oscData:e,sessionId:0,runTag:"",audioTimeS:null,currentTimeS:null}),this.#h++,this.#b+=e.length,!0)}sendWithOptions(e,t={}){if(!this.#t||this._disposed)return!1;let{sessionId:s=0,runTag:r="",audioTimeS:n=null,currentTimeS:o=null}=t;return this.#n.postMessage({type:"send",oscData:e,sessionId:s,runTag:r,audioTimeS:n,currentTimeS:o}),this.#h++,this.#b+=e.length,!0}sendImmediate(e){return!this.#t||this._disposed?!1:(this.#n.postMessage({type:"sendImmediate",oscData:e}),this.#h++,this.#b+=e.length,!0)}createOscChannel(e={}){if(!this.#t)throw new Error("Transport not initialized");let t=e.sourceId??this.#T++,s=new MessageChannel;this.#n.postMessage({type:"addOscSource"},[s.port1]);let r=this.#d;return O.createSAB({sharedBuffer:this.#r,ringBufferBase:this.#e,bufferConstants:this.#s,controlIndices:this.#i,preschedulerPort:s.port2,bypassLookaheadS:this._config.bypassLookaheadS,sourceId:t,blocking:e.blocking,replyNotifier:{subscribe(n){r.push(n)},unsubscribe(n){let o=r.indexOf(n);o>=0&&r.splice(o,1)}}})}cancelSessionTag(e,t){this.#t&&this.#n.postMessage({type:"cancelSessionTag",sessionId:e,runTag:t})}cancelSession(e){this.#t&&this.#n.postMessage({type:"cancelSession",sessionId:e})}cancelTag(e){this.#t&&this.#n.postMessage({type:"cancelTag",runTag:e})}cancelAll(){this.#t&&this.#n.postMessage({type:"cancelAll"})}cancelAllWithAck(){return this.#t?new Promise(e=>{let t=s=>{s.data.type==="cancelAllAck"&&(this.#n.removeEventListener("message",t),e())};this.#n.addEventListener("message",t),this.#n.postMessage({type:"cancelAll",ack:!0})}):Promise.resolve()}onReply(e){this.#_=e}onDebug(e){this.#E=e}onError(e){this.#p=e}onOscLog(e){this.#g=e}handleOscLog(e){this.#g&&this.#g(e)}getMetrics(){return{oscOutMessagesSent:this.#h,oscOutMessagesDropped:this.#m,oscOutBytesSent:this.#b}}get ready(){return this.#t&&!this._disposed}dispose(){this._disposed||(this.#n&&(this.#n.postMessage({type:"stop"}),this.#n.terminate(),this.#n=null),this.#u&&(this.#u.postMessage({type:"stop"}),this.#u.terminate(),this.#u=null),this.#l&&(this.#l.postMessage({type:"stop"}),this.#l.terminate(),this.#l=null),this.#y&&(this.#y.postMessage({type:"stop"}),this.#y.terminate(),this.#y=null),this.#t=!1,super.dispose())}#w(){this.#a=new Int32Array(this.#r),this.#o=new DataView(this.#r),this.#c=new Uint8Array(this.#r),this.#i=K(this.#e,this.#s.CONTROL_START)}#C(e,t,s={}){return new Promise((r,n)=>{let o=setTimeout(()=>{n(new Error(`${t} worker initialization timeout`))},5e3),a=c=>{c.data.type==="initialized"&&(clearTimeout(o),e.removeEventListener("message",a),r())};e.addEventListener("message",a),e.postMessage({type:"init",sharedBuffer:this.#r,ringBufferBase:this.#e,bufferConstants:this.#s,...s})})}#R(){this.#u.onmessage=e=>{let t=e.data;if(t.type==="messages"){this.#_&&t.messages.forEach(s=>{s.oscData&&this.#_(s.oscData,s.sequence,s.timestamp)});for(let s=0;s<this.#d.length;s++)this.#d[s]()}else t.type==="error"&&(console.error("[SABTransport] OSC IN error:",t.error),this.#p&&this.#p(t.error,"oscIn"))},this.#l.onmessage=e=>{let t=e.data;t.type==="debug"&&this.#E?t.messages.forEach(s=>{this.#E(s)}):t.type==="error"&&(console.error("[SABTransport] DEBUG error:",t.error),this.#p&&this.#p(t.error,"debug"))},this.#n.onmessage=e=>{let t=e.data;t.type==="preschedulerMetrics"?this.#A=t.metrics:t.type==="error"&&(console.error("[SABTransport] OSC OUT error:",t.error),this.#m++,this.#p&&this.#p(t.error,"oscOut"))},this.#y.onmessage=e=>{let t=e.data;t.type==="oscLog"&&this.#g?this.#g(t.entries):t.type==="error"&&(console.error("[SABTransport] OSC OUT LOG error:",t.error),this.#p&&this.#p(t.error,"oscOutLog"))}}getPreschedulerMetrics(){return this.#A}};var z=class extends R{#r;#e;#s;#a;#o;#c;#i;#n=1;#u=null;#l=!1;#y;#S;#_=null;#d=0;#E=0;#p=0;#g=0;#T=0;#t=-1;#f=0;#h=0;#m;#b;constructor(e){super({...e,mode:"postMessage"}),this.#s=e.workerBaseURL,this.#y=e.preschedulerCapacity||65536,this.#S=e.snapshotIntervalMs,this.#m=e.getAudioContextTime,this.#b=e.getNTPStartTime}async initialize(e){if(this.#l)return;if(!e)throw new Error("PostMessageTransport requires workletPort");this.#r=e,this.#r.onmessage=s=>{this.#w(s.data)};let t=new MessageChannel;this.#r.postMessage({type:"addOscPort"},[t.port1]),this.#e=await I(this.#s+"osc_out_prescheduler_worker.js",{type:"module"}),this.#e.onmessage=s=>{this.#C(s.data)},await this.#A(t.port2),this.#l=!0}setBufferConstants(e){this.#_=e}send(e,t){return!this.#l||this._disposed?!1:(this.#e.postMessage({type:"send",oscData:e,sessionId:0,runTag:"",audioTimeS:null,currentTimeS:null}),this.#d++,this.#p+=e.length,!0)}sendWithOptions(e,t={}){if(!this.#l||this._disposed)return!1;let{sessionId:s=0,runTag:r="",audioTimeS:n=null,currentTimeS:o=null}=t;return this.#e.postMessage({type:"send",oscData:e,sessionId:s,runTag:r,audioTimeS:n,currentTimeS:o}),this.#d++,this.#p+=e.length,!0}sendImmediate(e,t){return!this.#l||this._disposed?!1:(this.#r.postMessage({type:"osc",oscData:e,bypassCategory:t}),this.#d++,this.#p+=e.length,!0)}createOscChannel(e={}){if(!this.#l)throw new Error("Transport not initialized");let t=e.sourceId??this.#n++,s=new MessageChannel;this.#r.postMessage({type:"addOscPort",sourceId:t},[s.port1]);let r=new MessageChannel;return this.#e.postMessage({type:"addOscSource"},[r.port1]),O.createPostMessage({port:s.port2,preschedulerPort:r.port2,bypassLookaheadS:this._config.bypassLookaheadS,sourceId:t,blocking:e.blocking,nodeIdSource:this._config.nodeIdSource,replyWorkletPort:this.#r})}cancelSessionTag(e,t){this.#l&&this.#e.postMessage({type:"cancelSessionTag",sessionId:e,runTag:t})}cancelSession(e){this.#l&&this.#e.postMessage({type:"cancelSession",sessionId:e})}cancelTag(e){this.#l&&this.#e.postMessage({type:"cancelTag",runTag:e})}cancelAll(){this.#l&&this.#e.postMessage({type:"cancelAll"})}cancelAllWithAck(){return this.#l?new Promise(e=>{let t=s=>{s.data.type==="cancelAllAck"&&(this.#e.removeEventListener("message",t),e())};this.#e.addEventListener("message",t),this.#e.postMessage({type:"cancelAll",ack:!0})}):Promise.resolve()}onReply(e){this.#a=e}onDebug(e){this.#o=e}onError(e){this.#c=e}onOscLog(e){this.#i=e}handleDebugRaw(e){if(e.messages&&e.count>0&&e.buffer){let t=new TextDecoder("utf-8"),s=new Uint8Array(e.buffer);for(let r=0;r<e.count;r++){let n=e.messages[r];try{let o=s.subarray(n.offset,n.offset+n.length),a=t.decode(o);a.endsWith(`
|
|
2
|
+
`)&&(a=a.slice(0,-1)),this.#f++,this.#h+=n.length,this.#o&&this.#o({text:a,timestamp:performance.now(),sequence:n.sequence})}catch(o){console.error("[PostMessageTransport] Failed to decode debug message:",o)}}}}getPreschedulerMetrics(){return this.#u}getMetrics(){return{oscInMessagesReceived:this.#g,oscInBytesReceived:this.#T,oscInMessagesDropped:this.#E,debugMessagesReceived:this.#f,debugBytesReceived:this.#h}}get ready(){return this.#l&&!this._disposed}dispose(){this._disposed||(this.#e&&(this.#e.postMessage({type:"stop"}),this.#e.terminate(),this.#e=null),this.#r=null,this.#l=!1,super.dispose())}#A(e){return new Promise((t,s)=>{let r=setTimeout(()=>{s(new Error("Prescheduler worker initialization timeout"))},5e3),n=o=>{o.data.type==="initialized"&&(clearTimeout(r),this.#e.removeEventListener("message",n),t())};this.#e.addEventListener("message",n),this.#e.postMessage({type:"init",mode:"postMessage",maxPendingMessages:this.#y,snapshotIntervalMs:this.#S,bypassLookaheadS:this._config.bypassLookaheadS,workletPort:e},[e])})}#w(e){switch(e.type){case"oscReplies":if(e.messages&&e.count>0&&e.buffer){let t=new Uint8Array(e.buffer);for(let s=0;s<e.count;s++){let r=e.messages[s],n=t.subarray(r.offset,r.offset+r.length);if(r.sequence!==void 0&&this.#t>=0){let o=this.#t+1&4294967295;if(r.sequence!==o){let a=r.sequence-o+4294967296&4294967295;a<1e3&&(this.#E+=a)}}r.sequence!==void 0&&(this.#t=r.sequence),this.#g++,this.#T+=r.length,this.#a&&this.#a(n,r.sequence,M())}}break;case"metrics":break;case"bufferLoaded":break;case"debugRawBatch":this.handleDebugRaw(e);break;case"oscLog":if(this.#i&&e.count>0&&e.buffer&&e.entries){let t=new Uint8Array(e.buffer),s=[];for(let r=0;r<e.count;r++){let n=e.entries[r],o=t.subarray(n.offset,n.offset+n.length);s.push({oscData:o,sourceId:n.sourceId,sequence:n.sequence,timestamp:M(),truncated:n.length<n.originalLength,originalLength:n.originalLength})}this.#i(s)}break;case"error":console.error("[PostMessageTransport] Worklet error:",e.error),this.#E++,this.#c&&this.#c(e.error,"worklet");break;case"debug":break}}#C(e){switch(e.type){case"preschedulerMetrics":this.#u=e.metrics;break;case"error":console.error("[PostMessageTransport] Prescheduler error:",e.error),this.#E++,this.#c&&this.#c(e.error,"oscOut");break}}};function lt(i,e){if(i==="sab")return new G(e);if(i==="postMessage")return new z(e);throw new Error(`Unknown transport mode: ${i}. Use 'sab' or 'postMessage'`)}var ds={5120:"i8",5121:"u8",5122:"i16",5123:"u16",5124:"i32",5125:"u32",5126:"f32"};var ut={u8:1,u8c:1,i8:1,u16:2,i16:2,u32:4,i32:4,i64:8,u64:8,f32:4,f64:8};var ps={f32:Float32Array,f64:Float64Array},ms={i8:Int8Array,i16:Int16Array,i32:Int32Array},ys={u8:Uint8Array,u8c:Uint8ClampedArray,u16:Uint16Array,u32:Uint32Array},Ss={i64:BigInt64Array,u64:BigUint64Array},Es={...ps,...ms,...ys},_s=i=>{let e=ds[i];return e!==void 0?e:i};function ft(i,...e){let t=Ss[i];return new(t||Es[_s(i)])(...e)}var Y=(i,e)=>(e--,i+e&~e);var ht=i=>typeof i=="number";var j=(i,e=t=>t!==void 0?": "+t:"")=>class extends Error{origMessage;constructor(t){super(i(t)+e(t)),this.origMessage=t!==void 0?String(t):""}};var gs=j(()=>"Assertion failed"),Te=(typeof process<"u"&&process.env!==void 0?process.env.UMBRELLA_ASSERTS:!import.meta.env||import.meta.env.MODE!=="production"||import.meta.env.UMBRELLA_ASSERTS||import.meta.env.VITE_UMBRELLA_ASSERTS)?(i,e)=>{if(typeof i=="function"&&!i()||!i)throw new gs(typeof e=="function"?e():e)}:()=>{};var bs=j(()=>"illegal argument(s)"),dt=i=>{throw new bs(i)};var pt=0,mt=1,yt=2,St=3,Et=4,v=5,_t=6,we=1,Ce=2,gt=7*4,Me=0,Oe=1,B=2*4,Q=class{buf;start;u8;u32;state;constructor(e={}){if(this.buf=e.buf?e.buf:new ArrayBuffer(e.size||4096),this.start=e.start!=null?Y(Math.max(e.start,0),4):0,this.u8=new Uint8Array(this.buf),this.u32=new Uint32Array(this.buf),this.state=new Uint32Array(this.buf,this.start,gt/4),!e.skipInitialization){let t=e.align||8;Te(t>=8,`invalid alignment: ${t}, must be a pow2 and >= 8`);let s=this.initialTop(t),r=e.end!=null?Math.min(e.end,this.buf.byteLength):this.buf.byteLength;s>=r&&dt(`insufficient address range (0x${this.start.toString(16)} - 0x${r.toString(16)})`),this.align=t,this.doCompact=e.compact!==!1,this.doSplit=e.split!==!1,this.minSplit=e.minSplit||16,this.end=r,this.top=s,this._free=0,this._used=0}}stats(){let e=s=>{let r=0,n=0;for(;s;)r++,n+=this.blockSize(s),s=this.blockNext(s);return{count:r,size:n}},t=e(this._free);return{free:t,used:e(this._used),top:this.top,available:this.end-this.top+t.size,total:this.buf.byteLength}}callocAs(e,t,s=0){let r=this.mallocAs(e,t);return r?.fill(s),r}mallocAs(e,t){let s=this.malloc(t*ut[e]);return s?ft(e,this.buf,s,t):void 0}calloc(e,t=0){let s=this.malloc(e);return s&&this.u8.fill(t,s,s+e),s}malloc(e){if(e<=0)return 0;let t=Y(e+B,this.align),s=this.end,r=this.top,n=this._free,o=0;for(;n;){let a=this.blockSize(n),c=n+a>=r;if(c||a>=t)return this.mallocTop(n,o,a,t,c);o=n,n=this.blockNext(n)}return n=r,r=n+t,r<=s?(this.initBlock(n,t,this._used),this._used=n,this.top=r,$(n)):0}mallocTop(e,t,s,r,n){if(n&&e+r>this.end)return 0;if(t?this.unlinkBlock(t,e):this._free=this.blockNext(e),this.setBlockNext(e,this._used),this._used=e,n)this.top=e+this.setBlockSize(e,r);else if(this.doSplit){let o=s-r;o>=this.minSplit&&this.splitBlock(e,r,o)}return $(e)}realloc(e,t){if(t<=0)return 0;let s=Be(e),r=0,n=this._used,o=0;for(;n;){if(n===s){[r,o]=this.reallocBlock(n,t);break}n=this.blockNext(n)}return r&&r!==s&&this.u8.copyWithin($(r),$(s),o),$(r)}reallocBlock(e,t){let s=this.blockSize(e),r=e+s,n=r>=this.top,o=Y(t+B,this.align);if(o<=s){if(this.doSplit){let a=s-o;a>=this.minSplit?this.splitBlock(e,o,a):n&&(this.top=e+o)}else n&&(this.top=e+o);return[e,r]}return n&&e+o<this.end?(this.top=e+this.setBlockSize(e,o),[e,r]):(this.free(e),[Be(this.malloc(t)),r])}reallocArray(e,t){if(e.buffer!==this.buf)return;let s=this.realloc(e.byteOffset,t*e.BYTES_PER_ELEMENT);return s?new e.constructor(this.buf,s,t):void 0}free(e){let t;if(ht(e))t=e;else{if(e.buffer!==this.buf)return!1;t=e.byteOffset}t=Be(t);let s=this._used,r=0;for(;s;){if(s===t)return r?this.unlinkBlock(r,s):this._used=this.blockNext(s),this.insert(s),this.doCompact&&this.compact(),!0;r=s,s=this.blockNext(s)}return!1}freeAll(){this._free=0,this._used=0,this.top=this.initialTop()}release(){return delete this.u8,delete this.u32,delete this.state,delete this.buf,!0}get align(){return this.state[Et]}set align(e){this.state[Et]=e}get end(){return this.state[St]}set end(e){this.state[St]=e}get top(){return this.state[yt]}set top(e){this.state[yt]=e}get _free(){return this.state[pt]}set _free(e){this.state[pt]=e}get _used(){return this.state[mt]}set _used(e){this.state[mt]=e}get doCompact(){return!!(this.state[v]&we)}set doCompact(e){e?this.state[v]|=1<<we-1:this.state[v]&=~we}get doSplit(){return!!(this.state[v]&Ce)}set doSplit(e){e?this.state[v]|=1<<Ce-1:this.state[v]&=~Ce}get minSplit(){return this.state[_t]}set minSplit(e){Te(e>B,`illegal min split threshold: ${e}, require at least ${B+1}`),this.state[_t]=e}blockSize(e){return this.u32[(e>>2)+Me]}setBlockSize(e,t){return this.u32[(e>>2)+Me]=t,t}blockNext(e){return this.u32[(e>>2)+Oe]}setBlockNext(e,t){this.u32[(e>>2)+Oe]=t}initBlock(e,t,s){let r=e>>>2;return this.u32[r+Me]=t,this.u32[r+Oe]=s,e}unlinkBlock(e,t){this.setBlockNext(e,this.blockNext(t))}splitBlock(e,t,s){this.insert(this.initBlock(e+this.setBlockSize(e,t),s,0)),this.doCompact&&this.compact()}initialTop(e=this.align){return Y(this.start+gt+B,e)-B}compact(){let e=this._free,t=0,s=0,r,n=!1;for(;e;){for(r=e,s=this.blockNext(e);s&&r+this.blockSize(r)===s;)r=s,s=this.blockNext(s);if(r!==e){let o=r-e+this.blockSize(r);this.setBlockSize(e,o);let a=this.blockNext(r),c=this.blockNext(e);for(;c&&c!==a;){let u=this.blockNext(c);this.setBlockNext(c,0),c=u}this.setBlockNext(e,a),n=!0}e+this.blockSize(e)>=this.top&&(this.top=e,t?this.unlinkBlock(t,e):this._free=this.blockNext(e)),t=e,e=this.blockNext(e)}return n}insert(e){let t=this._free,s=0;for(;t&&!(e<=t);)s=t,t=this.blockNext(t);s?this.setBlockNext(s,e):this._free=e,this.setBlockNext(e,t)}},$=i=>i>0?i+B:0,Be=i=>i>0?i-B:0;var Re=8,bt=65536,J=class{#r=[];#e;#s;#a=0;#o=!1;#c;#i;#n;#u;constructor({buf:e,start:t,size:s,wasmMemory:r=null,maxSize:n,growIncrement:o=32*1024*1024,growFn:a=null,onGrowth:c=null}){this.#e=r,this.#s=o,this.#c=a,this.#i=c,this.#n=t+s,this.#u=t+n,this.#l(e,t,s,0)}malloc(e){for(let t=this.#r.length-1;t>=0;t--){let s=this.#r[t],r=s.pool.malloc(e);if(r!==0)return r+s.baseOffset}return 0}free(e){for(let t of this.#r)if(e>=t.start&&e<t.end)return t.pool.free(e-t.baseOffset);return!1}stats(){let e=0,t=0,s=0,r=0,n=0,o=0,a=0;for(let c of this.#r){let u=c.pool.stats();e+=u.free?.count||0,t+=u.free?.size||0,s+=u.used?.count||0,r+=u.used?.size||0,n+=u.available||0,o+=u.total||0,u.top>a&&(a=u.top)}return{free:{count:e,size:t},used:{count:s,size:r},top:a,available:n,total:o}}canGrow(){return this.#n+Re<this.#u}async grow(e=0){if(this.#o||!this.canGrow())return!1;this.#o=!0;try{let t=this.#u-this.#n,s=Math.min(Math.max(this.#s,e),t);if(s<Re)return!1;let r=Math.ceil(s/bt),n=this.#n,o=Math.min(r*bt,this.#u-n),a;if(this.#e){if(this.#e.grow(r)===-1)return!1;a=this.#e.buffer}else if(this.#c){if(!await this.#c(r))return!1;a=new ArrayBuffer(o)}else return!1;let c=this.#e?0:n,u=this.#e?n:0;return this.#l(a,u,o,c),this.#n=n+o,this.#a++,this.#i&&this.#i({poolIndex:this.#r.length-1,newBytes:o,totalCapacity:this.totalCapacity}),!0}finally{this.#o=!1}}get poolCount(){return this.#r.length}get growthCount(){return this.#a}get totalCapacity(){let e=0;for(let t of this.#r)e+=t.end-t.start;return e}get maxCapacity(){return this.#u-this.#r[0].start}#l(e,t,s,r){let n=new Q({buf:e,start:t,size:s,align:Re}),o=t+r;this.#r.push({pool:n,start:o,end:o+s,baseOffset:r})}};function At(i){if(i.byteLength<12)return!1;let e=new Uint8Array(i,0,12),t=String.fromCharCode(e[0],e[1],e[2],e[3]),s=String.fromCharCode(e[8],e[9],e[10],e[11]);return t==="FORM"&&(s==="AIFF"||s==="AIFC")}function As(i){let e=i[0]>>7&1,t=(i[0]&127)<<8|i[1],s=0;for(let n=2;n<10;n++)s=s*256+i[n];if(t===0)return 0;let r=s*Math.pow(2,t-16383-63);return e?-r:r}function Tt(i,e){let t=12;for(;t<i.byteLength-8;){let s=String.fromCharCode(i.getUint8(t),i.getUint8(t+1),i.getUint8(t+2),i.getUint8(t+3)),r=i.getUint32(t+4,!1);if(s===e)return{offset:t+8,size:r};t+=8+r+r%2}return null}function wt(i){let e=new DataView(i),t=String.fromCharCode(e.getUint8(8),e.getUint8(9),e.getUint8(10),e.getUint8(11)),s=Tt(e,"COMM");if(!s)throw new Error("AIFF file missing COMM chunk");let r=e.getUint16(s.offset,!1),n=e.getUint32(s.offset+2,!1),o=e.getUint16(s.offset+6,!1),a=new Uint8Array(i,s.offset+8,10),c=As(a);if(t==="AIFC"&&s.size>=22){let d=String.fromCharCode(e.getUint8(s.offset+18),e.getUint8(s.offset+19),e.getUint8(s.offset+20),e.getUint8(s.offset+21));if(d!=="NONE"&&d!=="sowt")throw new Error(`AIFC compression type '${d}' is not supported. Only uncompressed AIFF/AIFC files are supported.`);if(d==="sowt")return Ts(i,r,n,o,c)}let{wavBuffer:u,wavBytes:l,srcBytes:f,audioDataSize:h,bytesPerSample:y,wavHeaderSize:p}=Ct(i,r,n,o,c);if(y===1)for(let d=0;d<h;d++)l[p+d]=f[d]+128;else if(y===2)for(let d=0;d<h;d+=2)l[p+d]=f[d+1],l[p+d+1]=f[d];else if(y===3)for(let d=0;d<h;d+=3)l[p+d]=f[d+2],l[p+d+1]=f[d+1],l[p+d+2]=f[d];else if(y===4)for(let d=0;d<h;d+=4)l[p+d]=f[d+3],l[p+d+1]=f[d+2],l[p+d+2]=f[d+1],l[p+d+3]=f[d];else throw new Error(`Unsupported bit depth: ${o}`);return u}function Ct(i,e,t,s,r){let n=new DataView(i),o=Tt(n,"SSND");if(!o)throw new Error("AIFF file missing SSND chunk");let a=n.getUint32(o.offset,!1),c=o.offset+8+a,u=s/8,l=t*e*u;if(c+l>i.byteLength)throw new Error("AIFF file truncated: not enough audio data");let f=44,h=new ArrayBuffer(f+l),y=new DataView(h),p=new Uint8Array(h);ws(y,{numChannels:e,sampleRate:Math.round(r),bitsPerSample:s,dataSize:l});let d=new Uint8Array(i,c,l);return{wavBuffer:h,wavBytes:p,srcBytes:d,audioDataSize:l,bytesPerSample:u,wavHeaderSize:f}}function Ts(i,e,t,s,r){let{wavBuffer:n,wavBytes:o,srcBytes:a,audioDataSize:c,bytesPerSample:u,wavHeaderSize:l}=Ct(i,e,t,s,r);if(u===1)for(let f=0;f<c;f++)o[l+f]=a[f]+128;else o.set(a,l);return n}function ws(i,{numChannels:e,sampleRate:t,bitsPerSample:s,dataSize:r}){let n=t*e*(s/8),o=e*(s/8);i.setUint8(0,82),i.setUint8(1,73),i.setUint8(2,70),i.setUint8(3,70),i.setUint32(4,36+r,!0),i.setUint8(8,87),i.setUint8(9,65),i.setUint8(10,86),i.setUint8(11,69),i.setUint8(12,102),i.setUint8(13,109),i.setUint8(14,116),i.setUint8(15,32),i.setUint32(16,16,!0),i.setUint16(20,1,!0),i.setUint16(22,e,!0),i.setUint32(24,t,!0),i.setUint32(28,n,!0),i.setUint16(32,o,!0),i.setUint16(34,s,!0),i.setUint8(36,100),i.setUint8(37,97),i.setUint8(38,116),i.setUint8(39,97),i.setUint32(40,r,!0)}var ee=class{#r;#e;#s;#a;#o;#c;#i;#n;#u;#l;#y;constructor(e){let{mode:t="sab",audioContext:s,sharedBuffer:r,bufferPoolConfig:n,sampleBaseURL:o,maxBuffers:a=1024,assetLoader:c=null,workletPort:u=null,wasmMemory:l=null,maxBufferMemory:f=null,bufferGrowIncrement:h=32*1024*1024,onBufferPoolGrowth:y=null,growFn:p=null}=e;if(this.#r=t,!s)throw new Error("BufferManager requires audioContext");if(t==="sab"){if(!r||!(r instanceof SharedArrayBuffer))throw new Error("BufferManager requires sharedBuffer (SharedArrayBuffer) in SAB mode");if(!n||typeof n!="object")throw new Error("BufferManager requires bufferPoolConfig (object with start, size, align)");if(!Number.isFinite(n.start)||n.start<0)throw new Error("bufferPoolConfig.start must be a non-negative number");if(!Number.isFinite(n.size)||n.size<=0)throw new Error("bufferPoolConfig.size must be a positive number")}if(t==="postMessage"&&(!n||typeof n!="object"))throw new Error("BufferManager requires bufferPoolConfig in postMessage mode");if(!Number.isInteger(a)||a<=0)throw new Error("maxBuffers must be a positive integer");this.#a=s,this.#o=r,this.#c=l,this.#e=o,this.#s=c,this.#y=u;let d=f||n.maxSize||n.size,m=t==="sab"?r:new ArrayBuffer(n.start+n.size);this.#i=new J({buf:m,start:n.start,size:n.size,wasmMemory:t==="sab"?l:null,maxSize:d,growIncrement:h,growFn:t==="postMessage"?p:null,onGrowth:y}),this.#n=new Map,this.#u=new Map,this.#l=new Map,this.GUARD_BEFORE=3,this.GUARD_AFTER=1,this.MAX_BUFFERS=a;let E=(n.size/(1024*1024)).toFixed(0),g=(n.start/(1024*1024)).toFixed(0)}async#S(e){let t=e.byteOffset===0&&e.byteLength===e.buffer.byteLength?e.buffer:e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),s=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(s)).map(r=>r.toString(16).padStart(2,"0")).join("")}async#_({source:e,startFrame:t=0,numFrames:s=0,channels:r=null}){let n,o;if(typeof e=="string"){let m=this.#g(e),E=e.split("/").pop();n=await this.#s.fetch(m,{type:"sample",name:E}),o={type:"file",path:e,startFrame:t,numFrames:s,channels:r}}else n=e instanceof ArrayBuffer?e:e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),o=null;let a=await this.#p(n),c=Math.max(0,Math.floor(t||0)),u=a.length-c,l=s&&s>0?Math.min(Math.floor(s),u):u;if(l<=0)throw new Error("No audio frames available");let f=this.#f(r,a.numberOfChannels),h=f.length,y=l*h+(this.GUARD_BEFORE+this.GUARD_AFTER)*h,p=new Float32Array(y),d=this.GUARD_BEFORE*h;for(let m=0;m<l;m++)for(let E=0;E<h;E++){let g=a.getChannelData(f[E]);p[d+m*h+E]=g[c+m]}return{interleaved:p,numFrames:l,numChannels:h,sampleRate:a.sampleRate,sourceInfo:o}}async#d(e){let t=await this.#m(e.length);return await this.#b(t,e),t}async#E(e,t,s,r){let n,o=await this.#t(e,t,async()=>{let[c,u]=await Promise.all([this.#S(s.interleaved),this.#d(s.interleaved)]);return n=c,{ptr:u,sizeBytes:s.interleaved.length*4,numFrames:s.numFrames,numChannels:s.numChannels,sampleRate:s.sampleRate,source:r||null}}),a=this.#n.get(e);return a&&(a.hash=n),{...o,hash:n}}async#p(e){return At(e)&&(e=wt(e)),this.#a.decodeAudioData(e)}setWorkletPort(e){if(this.#r==="postMessage"){if(!e)throw new Error("BufferManager.setWorkletPort() requires a valid port");this.#y=e}}#g(e){if(typeof e!="string"||e.length===0)throw new Error("Invalid audio path: must be a non-empty string");if(e.includes(".."))throw new Error(`Invalid audio path: path cannot contain '..' (got: ${e})`);if(e.includes("%2e")||e.includes("%2E"))throw new Error(`Invalid audio path: path cannot contain URL-encoded characters (got: ${e})`);if(e.includes("\\"))throw new Error(`Invalid audio path: use forward slashes only (got: ${e})`);if(e.includes("://")||e.startsWith("/")||e.startsWith("./"))return e;if(!this.#e)throw new Error(`sampleBaseURL not configured. Please set it in SuperSonic constructor options.
|
|
3
3
|
Example: new SuperSonic({ sampleBaseURL: "./dist/samples/" })
|
|
4
4
|
Or use CDN: new SuperSonic({ sampleBaseURL: "https://unpkg.com/supersonic-scsynth-samples@latest/samples/" })
|
|
5
|
-
Or install: npm install supersonic-scsynth-samples`);return this.#e+e}#T(e){if(!Number.isInteger(e)||e<0||e>=this.MAX_BUFFERS)throw new Error(`Invalid buffer number ${e} (must be 0-${this.MAX_BUFFERS-1})`)}async#t(e,t,s){let r=null,n=null,o=!1,a=await this.#C(e),c=!1;try{await this.#B(e);let{ptr:u,sizeBytes:l,numFrames:f,numChannels:h,sampleRate:y,source:p,...d}=await s();r=u;let{uuid:m,allocationComplete:E}=this.#w(e,t);n=m,this.#R(e,r,l,m,E,{numFrames:f,numChannels:h,sampleRate:y,source:p}),o=!0;let _=this.#I(e,m,E);return a(),c=!0,{ptr:r,uuid:m,allocationComplete:_,numFrames:f,numChannels:h,sampleRate:y,...d}}catch(u){throw o&&n?this.#O(e,n,!1):r&&this.#i.free(r),u}finally{c||a()}}async prepareFromBlob(e){let{bufnum:t,blob:s,startFrame:r=0,numFrames:n=0,channels:o=null}=e;if(this.#T(t),!s||!(s instanceof ArrayBuffer||ArrayBuffer.isView(s)))throw new Error("/b_allocFile requires audio data as ArrayBuffer or typed array");let a=await this.#g({source:s,startFrame:r,numFrames:n,channels:o});return this.#E(t,3e4,a,null)}async prepareFromFile(e){let{bufnum:t,path:s,startFrame:r=0,numFrames:n=0,channels:o=null}=e;this.#T(t);let a=await this.#g({source:s,startFrame:r,numFrames:n,channels:o});return this.#E(t,6e4,a,a.sourceInfo)}async prepareEmpty(e){let{bufnum:t,numFrames:s,numChannels:r=1,sampleRate:n=null}=e;if(this.#T(t),!Number.isFinite(s)||s<=0)throw new Error(`/b_alloc requires a positive number of frames (got ${s})`);if(!Number.isFinite(r)||r<=0)throw new Error(`/b_alloc requires a positive channel count (got ${r})`);let o=Math.floor(s),a=Math.floor(r),c=o*a+(this.GUARD_BEFORE+this.GUARD_AFTER)*a,l={interleaved:new Float32Array(c),numFrames:o,numChannels:a,sampleRate:n||this.#a.sampleRate};return this.#E(t,5e3,l,null)}#f(e,t){return!e||e.length===0?Array.from({length:t},(s,r)=>r):(e.forEach(s=>{if(!Number.isInteger(s)||s<0||s>=t)throw new Error(`Channel ${s} is out of range (file has ${t} channels)`)}),e)}async#h(e){let t=this.#i.malloc(e);return t===0&&this.#i.canGrow()&&await this.#i.grow(e)&&(t=this.#i.malloc(e)),t}async#m(e){let t=e*4,s=await this.#h(t);if(s===0){let r=this.#i.stats(),n=((r.available||0)/(1024*1024)).toFixed(2),o=((r.total||0)/(1024*1024)).toFixed(2),a=((this.#i.maxCapacity||0)/(1024*1024)).toFixed(2),c=(t/(1024*1024)).toFixed(2);throw new Error(`Buffer pool allocation failed: requested ${c}MB, available ${n}MB of ${o}MB total (max ${a}MB)`)}return s}async#b(e,t){if(this.#r==="sab"){let s=this.#c?.buffer||this.#o;new Float32Array(s,e,t.length).set(t)}else{let s=crypto.randomUUID(),r=new Promise((o,a)=>{let c=setTimeout(()=>{a(new Error("Buffer copy to WASM memory timed out"))},1e4),u=l=>{let f=l.data;f.type==="bufferCopied"&&f.copyId===s&&(this.#y.removeEventListener("message",u),clearTimeout(c),f.success?o():a(new Error(f.error||"Buffer copy failed")))};this.#y.addEventListener("message",u)}),n=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);this.#y.postMessage({type:"copyBufferData",copyId:s,ptr:e,data:n},[n]),await r}}#A(e,t,s){return new Promise((r,n)=>{let o=setTimeout(()=>{this.#u.delete(e),n(new Error(`Buffer ${t} allocation timeout (${s}ms)`))},s);this.#u.set(e,{resolve:r,reject:n,timeout:o})})}#w(e,t){let s=crypto.randomUUID(),r=this.#A(s,e,t);return{uuid:s,allocationComplete:r}}async#C(e){let t=this.#l.get(e)||Promise.resolve(),s,r=new Promise(n=>{s=n});return this.#l.set(e,t.then(()=>r)),await t,()=>{s&&(s(),s=null),this.#l.get(e)===r&&this.#l.delete(e)}}#R(e,t,s,r,n,o={}){let a=this.#n.get(e),c={ptr:t,size:s,numFrames:o.numFrames||0,numChannels:o.numChannels||1,sampleRate:o.sampleRate||48e3,pendingToken:r,pendingPromise:n,previousAllocation:a?{ptr:a.ptr,size:a.size}:null,source:o.source||null};return this.#n.set(e,c),c}async#B(e){let t=this.#n.get(e);if(t&&t.pendingToken&&t.pendingPromise)try{await t.pendingPromise}catch{}}#I(e,t,s){return!s||typeof s.then!="function"?(this.#O(e,t,!0),Promise.resolve()):s.then(r=>(this.#O(e,t,!0),r)).catch(r=>{throw this.#O(e,t,!1),r})}#O(e,t,s){let r=this.#n.get(e);if(!r||r.pendingToken!==t)return;let n=r.previousAllocation;if(s){r.pendingToken=null,r.pendingPromise=null,r.previousAllocation=null,n?.ptr&&this.#i.free(n.ptr);return}r.ptr&&this.#i.free(r.ptr),r.pendingPromise=null,n?.ptr?this.#n.set(e,{ptr:n.ptr,size:n.size,pendingToken:null,previousAllocation:null}):this.#n.delete(e)}handleBufferFreed(e){let t=typeof e[0]=="bigint"?Number(e[0]):e[0],s=typeof e[1]=="bigint"?Number(e[1]):e[1],r=this.#n.get(t);if(!r){typeof s=="number"&&s!==0&&this.#i.free(s);return}if(typeof s=="number"&&s===r.ptr){this.#i.free(r.ptr),this.#n.delete(t);return}if(typeof s=="number"&&r.previousAllocation&&r.previousAllocation.ptr===s){this.#i.free(s),r.previousAllocation=null;return}this.#i.free(r.ptr),this.#n.delete(t)}handleBufferAllocated(e){let t=e[0],s=e[1],r=this.#u.get(t);r&&(clearTimeout(r.timeout),r.resolve({bufnum:s}),this.#u.delete(t))}async allocate(e){return this.#h(e*4)}free(e){return this.#i.free(e)}getView(e,t){let s=this.#c?.buffer||this.#o;return new Float32Array(s,e,t)}getStats(){return this.#i?this.#i.stats():{total:0,available:0,used:0,allocations:0}}getGrowthStats(){return this.#i?{totalCapacity:this.#i.totalCapacity,maxCapacity:this.#i.maxCapacity,growthCount:this.#i.growthCount,poolCount:this.#i.poolCount}:{totalCapacity:0,maxCapacity:0,growthCount:0,poolCount:0}}async sampleInfo({source:e,startFrame:t=0,numFrames:s=0,channels:r=null}){let n=await this.#g({source:e,startFrame:t,numFrames:s,channels:r});return{hash:await this.#S(n.interleaved),source:n.sourceInfo?.path||null,numFrames:n.numFrames,numChannels:n.numChannels,sampleRate:n.sampleRate,duration:n.sampleRate>0?n.numFrames/n.sampleRate:0}}getAllocatedBuffers(){let e=[];for(let[t,s]of this.#n.entries())!s||!s.ptr||e.push({bufnum:t,ptr:s.ptr,numFrames:s.numFrames,numChannels:s.numChannels,sampleRate:s.sampleRate,source:s.source||null,hash:s.hash||null});return e}updateAudioContext(e){if(!e)throw new Error("BufferManager.updateAudioContext requires audioContext");this.#a=e}destroy(){for(let[e,t]of this.#u.entries())clearTimeout(t.timeout),t.reject(new Error("BufferManager destroyed"));this.#u.clear();for(let[e,t]of this.#n.entries())t.ptr&&this.#i.free(t.ptr);this.#n.clear(),this.#l.clear()}};var te=class{#r;#e;#s;#a;constructor(e={}){let{onLoadingEvent:t=null,maxRetries:s=3,baseDelay:r=1e3,skipHeadRequests:n=!1}=e;this.#r=t,this.#e=s,this.#s=r,this.#a=n}async fetch(e,{type:t,name:s}){let r=this.#c(e);if(this.#a)this.#r?.("loading:start",{type:t,name:s});else{let a=await this.#o(e);this.#r?.("loading:start",{type:t,name:s,...a!=null&&{size:a}})}let o=await(await r).arrayBuffer();return this.#r?.("loading:complete",{type:t,name:s,size:o.byteLength}),o}async#o(e){try{let t=await fetch(e,{method:"HEAD"});if(t.ok){let s=t.headers.get("Content-Length");return s?parseInt(s,10):null}return null}catch{return null}}async#c(e){let t;for(let s=0;s<=this.#e;s++)try{let r=await fetch(e);if(r.status>=400&&r.status<500)throw new Error(`Failed to fetch ${e}: ${r.status} ${r.statusText}`);if(!r.ok)throw new Error(`Server error fetching ${e}: ${r.status} ${r.statusText}`);return r}catch(r){if(t=r,r.message.match(/Failed to fetch .+: 4\d{2} /))throw r;if(s<this.#e){let n=this.#s*Math.pow(2,s);await this.#i(n)}}throw t}#i(e){return new Promise(t=>setTimeout(t,e))}};var se=class{#r;#e;constructor({bufferManager:e,getDefaultSampleRate:t}){if(!e)throw new Error("OSCRewriter requires bufferManager");if(typeof t!="function")throw new Error("OSCRewriter requires getDefaultSampleRate callback");this.#r=e,this.#e=t}async rewritePacket(e){if(Array.isArray(e)){let{message:t,changed:s}=await this.#s(e);return{packet:t,changed:s}}if(this.#u(e)){let t=await Promise.all(e.packets.map(n=>this.rewritePacket(n)));if(!t.some(n=>n.changed))return{packet:e,changed:!1};let r=t.map(n=>n.packet);return{packet:{timeTag:e.timeTag,packets:r},changed:!0}}return{packet:e,changed:!1}}async#s(e){let t=e[0],s=e.slice(1);switch(t){case"/b_alloc":return{message:await this.#a(s),changed:!0};case"/b_allocRead":return{message:await this.#o(s),changed:!0};case"/b_allocReadChannel":return{message:await this.#c(s),changed:!0};case"/b_allocFile":return{message:await this.#i(s),changed:!0};default:return{message:e,changed:!1}}}async#a(e){let t=this.#S(e,0,"/b_alloc requires a buffer number"),s=this.#S(e,1,"/b_alloc requires a frame count"),r=2,n=1,o=this.#e();Number.isFinite(this.#l(e,r))&&(n=Math.max(1,this.#g(e,r,1)),r++),(Array.isArray(e)?e[r]:void 0)?.type==="b"&&r++;let a=this.#l(e,r);Number.isFinite(a)&&(o=a);let c=await this.#r.prepareEmpty({bufnum:t,numFrames:s,numChannels:n,sampleRate:o});return this.#p(c.allocationComplete,`/b_alloc ${t}`),this.#n(t,c)}async#o(e){let t=this.#S(e,0,"/b_allocRead requires a buffer number"),s=this.#d(e,1,"/b_allocRead requires a file path"),r=this.#g(e,2,0),n=this.#g(e,3,0),o=await this.#r.prepareFromFile({bufnum:t,path:s,startFrame:r,numFrames:n});return this.#p(o.allocationComplete,`/b_allocRead ${t}`),this.#n(t,o)}async#c(e){let t=this.#S(e,0,"/b_allocReadChannel requires a buffer number"),s=this.#d(e,1,"/b_allocReadChannel requires a file path"),r=this.#g(e,2,0),n=this.#g(e,3,0),o=[];for(let c=4;c<(e?.length||0);c++){let u=this.#l(e,c);if(!Number.isFinite(u))break;o.push(Math.floor(u))}let a=await this.#r.prepareFromFile({bufnum:t,path:s,startFrame:r,numFrames:n,channels:o.length>0?o:null});return this.#p(a.allocationComplete,`/b_allocReadChannel ${t}`),this.#n(t,a)}async#i(e){let t=this.#S(e,0,"/b_allocFile requires a buffer number"),s=this.#E(e,1,"/b_allocFile requires audio file data as blob"),r=await this.#r.prepareFromBlob({bufnum:t,blob:s});return this.#p(r.allocationComplete,`/b_allocFile ${t}`),this.#n(t,r)}#n(e,t){return["/b_allocPtr",Math.floor(e),Math.floor(t.ptr),Math.floor(t.numFrames),Math.floor(t.numChannels),t.sampleRate,String(t.uuid)]}#u(e){return e&&e.timeTag!==void 0&&Array.isArray(e.packets)}#l(e,t){let s=Array.isArray(e)?e[t]:void 0;if(s!=null)return typeof s=="object"&&Object.prototype.hasOwnProperty.call(s,"value")?s.value:s}#y(e,t,s,r){let n=this.#l(e,t);if(!s(n))throw new Error(r);return n}#S(e,t,s){return Math.floor(this.#y(e,t,Number.isFinite,s))}#g(e,t,s=0){let r=this.#l(e,t);return Number.isFinite(r)?Math.floor(r):s}#d(e,t,s){return this.#y(e,t,r=>typeof r=="string",s)}#E(e,t,s){return this.#y(e,t,r=>r instanceof Uint8Array||r instanceof ArrayBuffer,s)}#p(e,t){!e||typeof e.catch!="function"||e.catch(s=>{console.error(`[OSCRewriter] ${t} allocation failed:`,s)})}};function H(i){if(!i)return null;if(typeof i=="string")return(i.split("/").filter(Boolean).pop()||i).replace(/\.scsyndef$/i,"");let e=i instanceof ArrayBuffer?new Uint8Array(i):i;if(!(e instanceof Uint8Array)||e.length<11||e[0]!==83||e[1]!==67||e[2]!==103||e[3]!==102)return null;let s=(e[4]<<24|e[5]<<16|e[6]<<8|e[7])>=3?14:10;if(s>=e.length)return null;let r=e[s];if(r===0||s+1+r>e.length)return null;try{return new TextDecoder().decode(e.slice(s+1,s+1+r))}catch{return null}}var re=class{#r=new Map;on(e,t){if(typeof t!="function")throw new Error("Callback must be a function");return this.#r.has(e)||this.#r.set(e,new Set),this.#r.get(e).add(t),()=>this.off(e,t)}off(e,t){let s=this.#r.get(e);return s&&s.delete(t),this}once(e,t){let s=(...r)=>{this.off(e,s),t(...r)};return this.on(e,s)}removeAllListeners(e){return e===void 0?this.#r.clear():this.#r.delete(e),this}hasListeners(e){let t=this.#r.get(e);return t?t.size>0:!1}emit(e,...t){let s=this.#r.get(e);if(s)for(let r of s)try{r(...t)}catch(n){console.error(`[EventEmitter] Error in ${e} listener:`,n)}}async emitAsync(e,...t){let s=this.#r.get(e);if(s)for(let r of s)try{await r(...t)}catch(n){console.error(`[EventEmitter] Error in ${e} listener:`,n)}}};var Rr={oscOutMessagesSent:24,oscOutBytesSent:25,preschedulerBypassed:22,bypassNonBundle:38,bypassImmediate:39,bypassNearFuture:40,bypassLate:41},ie=class{#r;#e;#s;#a;#o;#c;#i;#n=null;#u=new Uint32Array(70);#l=new DataView(this.#u.buffer);constructor(e={}){this.#a=e.mode||"sab",this.#r=e.sharedBuffer||null,this.#e=e.ringBufferBase||0,this.#s=e.bufferConstants||null}initSharedViews(e,t,s){if(this.#r=e,this.#e=t,this.#s=s,this.#a==="sab"&&e&&s){this.#o=new Int32Array(e),this.#i=at(t,s.CONTROL_START);let r=t+s.METRICS_START;this.#c=new Uint32Array(e,r,s.METRICS_SIZE/4)}}updateSnapshot(e){this.#n=e}getSnapshotBuffer(){return this.#n}getMetricsView(){return this.#c}addMetric(e,t=1){if(!this.#c)return;let s=Rr[e];s!==void 0&&Atomics.add(this.#c,s,t)}overlayPreschedulerMetrics(e){if(!this.#n||!e)return;let t=new Uint32Array(this.#n,0,46),s=9,r=13;t.set(e.subarray(s,s+r),s),t[23]=e[23]}gatherMetrics(e={}){this.updateMergedArray(e);let t=this.#u,s={scsynthProcessCount:t[0],scsynthMessagesProcessed:t[1],scsynthMessagesDropped:t[2],scsynthSchedulerDepth:t[3],scsynthSchedulerPeakDepth:t[4],scsynthSchedulerDropped:t[5],scsynthSequenceGaps:t[6],scsynthSchedulerLates:t[8],scsynthSchedulerMaxLateMs:t[42],scsynthSchedulerLastLateMs:t[43],scsynthSchedulerLastLateTick:t[44],preschedulerPending:t[9],preschedulerPendingPeak:t[10],preschedulerDispatched:t[12],preschedulerRetriesSucceeded:t[16],preschedulerRetriesFailed:t[17],preschedulerBundlesScheduled:t[11],preschedulerEventsCancelled:t[13],preschedulerTotalDispatches:t[21],preschedulerMessagesRetried:t[20],preschedulerRetryQueueSize:t[18],preschedulerRetryQueuePeak:t[19],preschedulerBypassed:t[22],preschedulerMinHeadroomMs:t[14],preschedulerLates:t[15],preschedulerMaxLateMs:t[23],oscInMessagesReceived:t[26],oscInMessagesDropped:t[28],oscInBytesReceived:t[27],debugMessagesReceived:t[30],debugBytesReceived:t[31],oscOutMessagesSent:t[24],oscOutBytesSent:t[25],scsynthWasmErrors:t[7],oscInCorrupted:t[29],ringBufferDirectWriteFails:t[45],bypassNonBundle:t[38],bypassImmediate:t[39],bypassNearFuture:t[40],bypassLate:t[41],mode:this.#a},r=this.#s;return t[32]!==void 0&&r&&(s.inBufferUsed={bytes:t[32],percentage:t[32]/r.IN_BUFFER_SIZE*100,peakBytes:t[35],peakPercentage:t[35]/r.IN_BUFFER_SIZE*100,capacity:r.IN_BUFFER_SIZE},s.outBufferUsed={bytes:t[33],percentage:t[33]/r.OUT_BUFFER_SIZE*100,peakBytes:t[36],peakPercentage:t[36]/r.OUT_BUFFER_SIZE*100,capacity:r.OUT_BUFFER_SIZE},s.debugBufferUsed={bytes:t[34],percentage:t[34]/r.DEBUG_BUFFER_SIZE*100,peakBytes:t[37],peakPercentage:t[37]/r.DEBUG_BUFFER_SIZE*100,capacity:r.DEBUG_BUFFER_SIZE}),r?.scheduler_slot_count!==void 0&&(s.scsynthSchedulerCapacity=r.scheduler_slot_count),e.driftOffsetMs!==void 0&&(s.driftOffsetMs=e.driftOffsetMs),e.ntpStartTime!==void 0&&(s.ntpStartTime=e.ntpStartTime),e.clockOffsetMs!==void 0&&(s.clockOffsetMs=e.clockOffsetMs),e.audioContextState&&(s.audioContextState=e.audioContextState),e.bufferPoolStats&&(s.bufferPoolUsedBytes=e.bufferPoolStats.used.size,s.bufferPoolAvailableBytes=e.bufferPoolStats.available,s.bufferPoolAllocations=e.bufferPoolStats.used.count),e.bufferPoolGrowthStats&&(s.bufferPoolTotalCapacity=e.bufferPoolGrowthStats.totalCapacity,s.bufferPoolMaxCapacity=e.bufferPoolGrowthStats.maxCapacity,s.bufferPoolGrowthCount=e.bufferPoolGrowthStats.growthCount,s.bufferPoolPoolCount=e.bufferPoolGrowthStats.poolCount),e.loadedSynthDefsCount!==void 0&&(s.loadedSynthDefs=e.loadedSynthDefsCount),e.preschedulerCapacity!==void 0&&(s.preschedulerCapacity=e.preschedulerCapacity),s.audioHealthPct=e.audioHealthPct??100,s.hasPlaybackStats=!!e.playbackStats,e.playbackStats?(s.glitchCount=e.playbackStats.fallbackFramesEvents??0,s.glitchDurationMs=Math.round((e.playbackStats.fallbackFramesDuration??0)*1e3),s.averageLatencyUs=Math.round((e.playbackStats.averageLatency??0)*1e6),s.maxLatencyUs=Math.round((e.playbackStats.maximumLatency??0)*1e6),s.totalFramesDurationMs=Math.round((e.playbackStats.totalFramesDuration??0)*1e3)):(s.glitchCount=0,s.glitchDurationMs=0,s.averageLatencyUs=0,s.maxLatencyUs=0,s.totalFramesDurationMs=0),this.#a==="postMessage"&&e.transportMetrics&&Object.assign(s,e.transportMetrics),s}updateMergedArray(e={}){let t=this.#u;if(this.#a==="postMessage"){if(e.preschedulerMetrics&&this.overlayPreschedulerMetrics(e.preschedulerMetrics),this.#n){let a=new Uint32Array(this.#n,0,46);t.set(a)}e.transportMetrics&&(e.transportMetrics.oscOutMessagesSent!==void 0&&(t[24]=e.transportMetrics.oscOutMessagesSent),e.transportMetrics.oscOutBytesSent!==void 0&&(t[25]=e.transportMetrics.oscOutBytesSent),e.transportMetrics.preschedulerBypassed!==void 0&&(t[22]=e.transportMetrics.preschedulerBypassed),e.transportMetrics.bypassNonBundle!==void 0&&(t[38]=e.transportMetrics.bypassNonBundle),e.transportMetrics.bypassImmediate!==void 0&&(t[39]=e.transportMetrics.bypassImmediate),e.transportMetrics.bypassNearFuture!==void 0&&(t[40]=e.transportMetrics.bypassNearFuture),e.transportMetrics.bypassLate!==void 0&&(t[41]=e.transportMetrics.bypassLate))}else this.#c&&t.set(this.#c);let s=this.#l;s.setInt32(46*4,e.driftOffsetMs??0,!0),s.setInt32(47*4,e.clockOffsetMs??0,!0);let r=e.audioContextState||"unknown",n={unknown:0,running:1,suspended:2,closed:3,interrupted:4};t[48]=n[r]??0,e.bufferPoolStats&&(t[49]=e.bufferPoolStats.used?.size??0,t[50]=e.bufferPoolStats.available??0,t[51]=e.bufferPoolStats.used?.count??0),t[52]=e.loadedSynthDefsCount??0;let o=this.#s;t[53]=o?.scheduler_slot_count??0,t[54]=e.preschedulerCapacity??0,t[55]=o?.IN_BUFFER_SIZE??0,t[56]=o?.OUT_BUFFER_SIZE??0,t[57]=o?.DEBUG_BUFFER_SIZE??0,t[58]=this.#a==="sab"?0:1,t[65]=e.playbackStats?1:0,e.playbackStats&&(t[59]=e.playbackStats.fallbackFramesEvents??0,t[60]=Math.round((e.playbackStats.fallbackFramesDuration??0)*1e3),t[61]=Math.round((e.playbackStats.averageLatency??0)*1e6),t[62]=Math.round((e.playbackStats.maximumLatency??0)*1e6),t[64]=Math.round((e.playbackStats.totalFramesDuration??0)*1e3)),t[63]=e.audioHealthPct??100,e.bufferPoolGrowthStats&&(t[66]=e.bufferPoolGrowthStats.totalCapacity??0,t[67]=e.bufferPoolGrowthStats.maxCapacity??0,t[68]=e.bufferPoolGrowthStats.growthCount??0,t[69]=e.bufferPoolGrowthStats.poolCount??0)}getMergedArray(){return this.#u}get bufferConstants(){return this.#s}get ringBufferBase(){return this.#e}get sharedBuffer(){return this.#r}};function Pe(i){return i/1e3+2208988800}function Pt(i,e){return i-e}function Ir(i,e){let t=i-e;return Math.round(t*1e6)}var ne=class{#r;#e;#s;#a;#o;#c;#i;#n;#u;#l=0;#y=0;#S=null;constructor(e={}){this.#r=e.mode||"sab",this.#e=e.audioContext,this.#s=e.workletPort||null}#g(e){this.#c.setFloat64(0,e,!0),this.#i&&Atomics.store(this.#i,0,Atomics.load(this.#i,0))}initSharedViews(e,t,s){this.#o=t,this.#a=s,this.#r==="sab"&&e&&s&&(this.#c=new DataView(e,t+s.NTP_START_TIME_START,8),this.#i=new Int32Array(e,t+s.DRIFT_OFFSET_START,1),this.#n=new Int32Array(e,t+s.GLOBAL_OFFSET_START,1))}updateAudioContext(e){this.#e=e}async initialize(){if(!this.#e)return;let e;for(;e=this.#e.getOutputTimestamp(),!(e.contextTime>0);)await new Promise(o=>setTimeout(o,50));e=this.#e.getOutputTimestamp();let t=performance.timeOrigin+e.performanceTime,s=Pe(t),r=e.contextTime,n=Pt(s,r);this.#r==="sab"&&this.#c?this.#g(n):this.#s&&this.#s.postMessage({type:"setNTPStartTime",ntpStartTime:n}),this.#u=n,await new Promise(o=>setTimeout(o,500)),this.updateDriftOffset()}updateDriftOffset(){if(!this.#e||this.#u===void 0)return;let e=this.#e.getOutputTimestamp(),t=performance.timeOrigin+e.performanceTime,r=Pe(t)-this.#u,n=Ir(r,e.contextTime);this.#l=Math.round(n/1e3),this.#r==="sab"&&this.#i?Atomics.store(this.#i,0,n):this.#s&&this.#s.postMessage({type:"setDriftOffset",driftOffsetUs:n})}resync(){if(!this.#e)return;let e=this.#e.getOutputTimestamp();if(!e||e.contextTime<=0)return;let t=performance.timeOrigin+e.performanceTime,s=Pe(t),r=Pt(s,e.contextTime);this.#r==="sab"&&this.#c?this.#g(r):this.#s&&this.#s.postMessage({type:"setNTPStartTime",ntpStartTime:r}),this.#u=r,this.updateDriftOffset()}startDriftTimer(){this.stopDriftTimer(),this.#S=setInterval(()=>{this.updateDriftOffset()},1e3)}stopDriftTimer(){this.#S&&(clearInterval(this.#S),this.#S=null)}getDriftOffset(){return this.#i?Math.round(Atomics.load(this.#i,0)/1e3):this.#l}getNTPStartTime(){return this.#c?this.#c.getFloat64(0,!0):this.#u??0}getClockOffset(){return this.#n?Atomics.load(this.#n,0):this.#y}setClockOffset(e){let t=Math.round(e*1e3);this.#y=t,this.#r==="sab"&&this.#n?Atomics.store(this.#n,0,t):this.#s&&this.#s.postMessage({type:"setClockOffset",clockOffsetMs:t})}reset(){this.stopDriftTimer(),this.#u=void 0,this.#l=0,this.#y=0,this.#c=null,this.#i=null,this.#n=null}};var oe=Object.freeze({SET_SESSION_BPM:"setSessionBpm",SET_SESSION_IS_PLAYING:"setSessionIsPlaying",SET_SESSION_BEAT_ORIGIN_NTP:"setSessionBeatOriginNtp"}),Dt=new ArrayBuffer(8),Lt=new Float64Array(Dt),kt=new BigInt64Array(Dt);function ae(i){return Lt[0]=i,kt[0]}function ce(i){return kt[0]=i,Lt[0]}var le=class{#r;#e;#s;#a;#o;#c=120;#i=0;#n=!1;#u=0;#l;constructor(e={}){this.#r=e.mode||"sab",this.#e=e.workletPort||null,this.#s=e.audioContext||null,this.#l=new ne({mode:this.#r,audioContext:e.audioContext,workletPort:this.#e})}initSharedViews(e,t,s){if(this.#r==="sab"){let r=t+s.SUPERCLOCK_STATE_START,n=s.SUPERCLOCK_STATE_SIZE;this.#a=new BigInt64Array(e,r,n/8),this.#o=new Int32Array(e,r,n/4)}this.#l.initSharedViews(e,t,s)}setWorkletPort(e){this.#e=e}updateAudioContext(e){this.#s=e,this.#l.updateAudioContext(e)}async initialize(){await this.#l.initialize()}resync(){this.#l.resync()}startDriftTimer(){this.#l.startDriftTimer()}stopDriftTimer(){this.#l.stopDriftTimer()}updateDriftOffset(){this.#l.updateDriftOffset()}getDriftOffset(){return this.#l.getDriftOffset()}getNTPStartTime(){return this.#l.getNTPStartTime()}getClockOffset(){return this.#l.getClockOffset()}setClockOffset(e){this.#l.setClockOffset(e)}reset(){this.#l.reset()}setBpm(e,t=0){(!Number.isFinite(e)||e<1)&&(e=1),this.#c=e,this.#a?Atomics.store(this.#a,0,ae(e)):this.#e&&this.#e.postMessage({type:oe.SET_SESSION_BPM,bpm:e,atNtpSeconds:t})}setIsPlaying(e,t=0){this.#n=!!e,this.#u=t,this.#a?(Atomics.store(this.#a,2,ae(t)),Atomics.store(this.#o,6,e?1:0)):this.#e&&this.#e.postMessage({type:oe.SET_SESSION_IS_PLAYING,isPlaying:this.#n,atNtpSeconds:t})}setLinkEnabled(e){e&&console.warn("[SuperClock] setLinkEnabled(true) ignored on web \u2014 Link is native-only. Use the native build + /link/visibility.")}requestBeatAtTime(e,t,s){let r=this.getBpm(),n=t-e*60/r;this.#i=n,this.#a?Atomics.store(this.#a,1,ae(n)):this.#e&&this.#e.postMessage({type:oe.SET_SESSION_BEAT_ORIGIN_NTP,beatOriginNtp:n})}forceBeatAtTime(e,t,s){this.requestBeatAtTime(e,t,s)}getBpm(){return this.#a?ce(Atomics.load(this.#a,0)):this.#c}isPlaying(){return this.#o?Atomics.load(this.#o,6)!==0:this.#n}getBeatOriginNtp(){return this.#a?ce(Atomics.load(this.#a,1)):this.#i}getIsPlayingAtNtp(){return this.#a?ce(Atomics.load(this.#a,2)):this.#u}isLinkEnabled(){return!1}numPeers(){return 0}now(){return this.#s?this.nowAt(this.#s.currentTime):0}nowAt(e){return e+this.getNTPStartTime()+this.getDriftOffset()/1e3+this.getClockOffset()/1e3}wallNow(){return(performance.timeOrigin+performance.now())/1e3+2208988800}beatAtTime(e,t){return(e-this.getBeatOriginNtp())*this.getBpm()/60}phaseAtTime(e,t){let r=this.beatAtTime(e,t)%t;return r<0&&(r+=t),r}timeAtBeat(e,t){return this.getBeatOriginNtp()+e*60/this.getBpm()}};var ue=class i{#r;#e=0;#s=0;#a=100;static#o=1e3;constructor({audioContext:e}){this.#r=e}update(){if(this.#r.state!=="running")return this.#a;let e=performance.now(),t=this.#r.currentTime;if(this.#s===0)return this.#s=e,this.#e=t,this.#a;let s=e-this.#s;if(s<i.#o)return this.#a;let r=s/1e3,n=t-this.#e;return this.#a=Math.min(100,Math.round(n/r*100)),this.#s=e,this.#e=t,this.#a}getHealth(){return{healthPct:this.#a}}reset(){this.#e=0,this.#s=0,this.#a=100}};var fe=class i{#r;#e;#s;constructor(e={}){this.#r=e.sharedBuffer||null,this.#e=e.bufferConstants||null,this.#s=e.ringBufferBase||0}update(e,t,s){this.#r=e,this.#s=t,this.#e=s}isAvailable(){return!!(this.#r&&this.#e)}static#a=0;static#o=1;static#c=2;static#i=4;static#n=5;static#u=8;start(){if(!this.isAvailable())throw new Error("AudioCapture not initialized");let e=this.#e,t=this.#s+e.SHM_AUDIO_START,s=new Uint32Array(this.#r,t,i.#u);Atomics.store(s,i.#a,0),Atomics.store(s,i.#i,0),Atomics.store(s,i.#n,0),Atomics.store(s,i.#a,1)}stop(){if(!this.isAvailable())throw new Error("AudioCapture not initialized");let e=this.#e,t=this.#s+e.SHM_AUDIO_START,s=new Uint32Array(this.#r,t,1);return Atomics.store(s,i.#a,0),this.read()}read(){if(!this.isAvailable())throw new Error("AudioCapture not initialized");let e=this.#e,t=this.#s+e.SHM_AUDIO_START,s=new Uint32Array(this.#r,t,i.#u),r=s[i.#o],n=s[i.#c],o=Atomics.load(s,i.#i),a=Atomics.load(s,i.#n);if(a!==0)throw new Error(`AudioCapture: write_position too large (high=${a})`);let c=o,u=t+e.SHM_AUDIO_HEADER_SIZE,l=new Float32Array(this.#r,u,c*n),f=new Float32Array(c),h=n>1?new Float32Array(c):null;for(let y=0;y<c;y++)f[y]=l[y*n],h&&(h[y]=l[y*n+1]);return{sampleRate:r,channels:n,frames:c,left:f,right:h}}isEnabled(){if(!this.isAvailable())return!1;let e=this.#e,t=this.#s+e.SHM_AUDIO_START,s=new Uint32Array(this.#r,t,1);return Atomics.load(s,i.#a)===1}getFrameCount(){if(!this.isAvailable())return 0;let e=this.#e,t=this.#s+e.SHM_AUDIO_START,s=new Uint32Array(this.#r,t,i.#u);return Atomics.load(s,i.#i)}getMaxDuration(){if(!this.#e)return 0;let e=this.#e;return e.SHM_AUDIO_FRAMES/(e.SHM_AUDIO_SAMPLE_RATE||48e3)}};function Ht(i,e,t){let s=t,r=new Uint32Array(i,e,3),n=r[0],o=r[1],a=r[2],c=e+s.NODE_TREE_HEADER_SIZE,u=s.NODE_TREE_MIRROR_MAX_NODES,l=s.NODE_TREE_ENTRY_SIZE,f=s.NODE_TREE_DEF_NAME_SIZE,h=new DataView(i,c,u*l),y=new TextDecoder("utf-8"),p=[],d=0;for(let m=0;m<u&&d<n;m++){let E=m*l,_=h.getInt32(E,!0);if(_===-1)continue;d++;let w=c+E+24,C=new Uint8Array(i,w,f),g=new Uint8Array(f);g.set(C);let Se=g.indexOf(0);Se===-1&&(Se=f);let ns=y.decode(g.subarray(0,Se)),os=c+E+56,Ee=new Uint8Array(i,os,16),Je=!1;for(let T=0;T<16;T++)if(Ee[T]!==0){Je=!0;break}let X=null;if(Je){X=new Uint8Array(16);for(let T=0;T<8;T++)X[T]=Ee[7-T];for(let T=0;T<8;T++)X[8+T]=Ee[15-T]}p.push({id:_,parentId:h.getInt32(E+4,!0),isGroup:h.getInt32(E+8,!0)===1,prevId:h.getInt32(E+12,!0),nextId:h.getInt32(E+16,!0),headId:h.getInt32(E+20,!0),defName:ns,uuid:X})}return{nodeCount:n,version:o,droppedCount:a,nodes:p}}var Ye=new Uint8Array(2097152),Gt=new DataView(Ye.buffer),S=Ye,A=Gt,De=new Map,Ur=1e3,Pr=new TextDecoder,Dr=new TextEncoder,Le=[null,0],$e=2208988800,pe=4294967296,We=new Uint8Array([35,98,117,110,100,108,101,0]),zt=44,xe=105,Ne=102,Fe=115,ve=98,He=84,Ge=70,Yt=104,$t=100,Wt=116,Vt=117,qt=91,Xt=93;function he(i,e,t=0){let s=i.length+4;s+=5;for(let r=t;r<e.length;r++)s+=Kt(e[r]);return s}function Kt(i){if(i instanceof Uint8Array)return 5+i.length+3;if(i instanceof ArrayBuffer)return 5+i.byteLength+3;if(typeof i=="string")return 1+i.length*3+4;if(Array.isArray(i)){let e=2;for(let t=0;t<i.length;t++)e+=Kt(i[t]);return e}if(i&&i.type==="string")return 1+i.value.length*3+4;if(i&&i.type==="blob"){let e=i.value;return 5+(e instanceof Uint8Array?e.length:e.byteLength)+3}return i&&i.type==="uuid"?17:9}function Zt(i){let e=16;for(let t of i)e+=4,Array.isArray(t)?e+=he(t[0],t,1):t.packets!==void 0?e+=Zt(t.packets):e+=he(t.address,t.args||[]);return e}function Ve(i){if(i<=2097152){S=Ye,A=Gt;return}S=new Uint8Array(i),A=new DataView(S.buffer)}function jt(i,e=[]){let t=he(i,e);Ve(t);let s=0;s=qe(i,s),s=Xe(e,s);for(let r=0;r<e.length;r++)s=W(e[r],s);return S.subarray(0,s)}function Qt(i,e){let t=Zt(e);Ve(t);let s=0;S.set(We,s),s+=8,s=me(i,s);for(let r=0;r<e.length;r++){let n=e[r],o=s;s+=4;let a=s;Array.isArray(n)?s=de(n[0],n,s,1):n.packets!==void 0?s=es(n.timeTag,n.packets,s):s=de(n.address,n.args||[],s);let c=s-a;A.setUint32(o,c,!1)}return S.subarray(0,s)}function Jt(i,e,t=[]){let s=20+he(e,t);Ve(s);let r=0;S.set(We,r),r+=8,r=me(i,r);let n=r;r+=4;let o=r;r=qe(e,r),r=Xe(t,r);for(let a=0;a<t.length;a++)r=W(t[a],r);return A.setUint32(n,r-o,!1),S.subarray(0,r)}function de(i,e,t,s=0){t=qe(i,t),t=Xe(e,t,s);for(let r=s;r<e.length;r++)t=W(e[r],t);return t}function es(i,e,t){S.set(We,t),t+=8,t=me(i,t);for(let s=0;s<e.length;s++){let r=e[s],n=t;t+=4;let o=t;Array.isArray(r)?t=de(r[0],r,t,1):r.packets!==void 0?t=es(r.timeTag,r.packets,t):t=de(r.address,r.args||[],t),A.setUint32(n,t-o,!1)}return t}function qe(i,e){let t=De.get(i);if(t)return S.set(t,e),e+t.length;let s=e;if(e=ze(i,e),De.size<Ur){let r=S.slice(s,e);De.set(i,r)}return e}function ze(i,e){let t=!1;for(let s=0;s<i.length;s++)if(i.charCodeAt(s)>=128){t=!0;break}if(t){let s=Dr.encodeInto(i,S.subarray(e));e+=s.written}else for(let s=0;s<i.length;s++)S[e++]=i.charCodeAt(s);for(S[e++]=0;e&3;)S[e++]=0;return e}function Xe(i,e,t=0){S[e++]=zt;for(let s=t;s<i.length;s++)e=ts(i[s],e,s);for(S[e++]=0;e&3;)S[e++]=0;return e}function ts(i,e,t){let s=typeof i;if(s==="number")S[e++]=Number.isInteger(i)?xe:Ne;else if(s==="string")S[e++]=Fe;else if(s==="boolean")S[e++]=i?He:Ge;else if(i instanceof Uint8Array||i instanceof ArrayBuffer)S[e++]=ve;else if(Array.isArray(i)){S[e++]=qt;for(let r=0;r<i.length;r++)e=ts(i[r],e,t);S[e++]=Xt}else if(i&&i.type==="int")S[e++]=xe;else if(i&&i.type==="float")S[e++]=Ne;else if(i&&i.type==="string")S[e++]=Fe;else if(i&&i.type==="blob")S[e++]=ve;else if(i&&i.type==="bool")S[e++]=i.value?He:Ge;else if(i&&i.type==="int64")S[e++]=Yt;else if(i&&i.type==="double")S[e++]=$t;else if(i&&i.type==="timetag")S[e++]=Wt;else if(i&&i.type==="uuid")S[e++]=Vt;else throw i==null?new Error(`OSC argument at index ${t} is ${i}`):new Error(`Unknown OSC argument type at index ${t}: ${s}`);return e}function W(i,e){let t=typeof i;if(t==="number")return Number.isInteger(i)?(A.setInt32(e,i,!1),e+4):(A.setFloat32(e,i,!1),e+4);if(t==="string")return ze(i,e);if(t==="boolean")return e;if(i instanceof Uint8Array){let s=i.length;for(A.setUint32(e,s,!1),e+=4,S.set(i,e),e+=s;e&3;)S[e++]=0;return e}if(i instanceof ArrayBuffer)return W(new Uint8Array(i),e);if(Array.isArray(i)){for(let s=0;s<i.length;s++)e=W(i[s],e);return e}if(i&&i.type==="int")return A.setInt32(e,i.value,!1),e+4;if(i&&i.type==="float")return A.setFloat32(e,i.value,!1),e+4;if(i&&i.type==="string")return ze(i.value,e);if(i&&i.type==="blob"){let s=i.value instanceof Uint8Array?i.value:new Uint8Array(i.value),r=s.length;for(A.setUint32(e,r,!1),e+=4,S.set(s,e),e+=r;e&3;)S[e++]=0;return e}return i&&i.type==="bool"?e:i&&i.type==="int64"?(A.setBigInt64(e,BigInt(i.value),!1),e+8):i&&i.type==="double"?(A.setFloat64(e,i.value,!1),e+8):i&&i.type==="timetag"?me(i.value,e):i&&i.type==="uuid"?(S.set(i.value,e),e+16):e}function me(i,e){if(i===1||i===null||i===void 0)return A.setUint32(e,0,!1),A.setUint32(e+4,1,!1),e+8;if(Array.isArray(i)){if(i.length!==2)throw new Error(`TimeTag array must have exactly 2 elements [seconds, fraction], got ${i.length}`);return A.setUint32(e,i[0]>>>0,!1),A.setUint32(e+4,i[1]>>>0,!1),e+8}if(typeof i!="number")throw new TypeError(`TimeTag must be a number, array, null, or undefined, got ${typeof i}`);i>1&&i<$e&&console.warn(`TimeTag ${i} looks like a Unix timestamp (< NTP_EPOCH_OFFSET). Did you mean to add NTP_EPOCH_OFFSET (2208988800)?`);let t=i>>>0,s=(i-Math.floor(i))*pe>>>0;return A.setUint32(e,t,!1),A.setUint32(e+4,s,!1),e+8}function V(i){return i instanceof Uint8Array||(i=new Uint8Array(i)),i[0]===35&&i[1]===98?kr(i):Lr(i)}function Lr(i){i instanceof Uint8Array||(i=new Uint8Array(i));let e=new DataView(i.buffer,i.byteOffset,i.byteLength),t=0,[s,r]=ke(i,t);if(t=r,t>=i.length||i[t]!==zt)return[s];let[n,o]=ke(i,t);t=o;let a=[s],c=a,u=[];for(let l=1;l<n.length;l++)switch(n.charCodeAt(l)){case xe:c.push(e.getInt32(t,!1)),t+=4;break;case Ne:c.push(e.getFloat32(t,!1)),t+=4;break;case Fe:let[h,y]=ke(i,t);c.push(h),t=y;break;case ve:let p=e.getUint32(t,!1);t+=4,c.push(i.slice(t,t+p)),t+=p,t=t+3&-4;break;case Yt:c.push(e.getBigInt64(t,!1)),t+=8;break;case $t:c.push(e.getFloat64(t,!1)),t+=8;break;case He:c.push(!0);break;case Ge:c.push(!1);break;case Wt:let d=e.getUint32(t,!1),m=e.getUint32(t+4,!1);c.push(d+m/pe),t+=8;break;case Vt:c.push({type:"uuid",value:i.slice(t,t+16)}),t+=16;break;case qt:{let E=[];c.push(E),u.push(c),c=E;break}case Xt:c=u.pop()||a;break}return a}function kr(i){i instanceof Uint8Array||(i=new Uint8Array(i));let e=new DataView(i.buffer,i.byteOffset,i.byteLength),t=8,s=e.getUint32(t,!1),r=e.getUint32(t+4,!1),n=s+r/pe;t+=8;let o=[];for(;t<i.length;){let a=e.getUint32(t,!1);if(t+=4,a>0&&t+a<=i.length){let c=i.subarray(t,t+a);o.push(V(c))}t+=a}return{timeTag:n,packets:o}}function ke(i,e){let t=e;for(;t<i.length&&i[t]!==0;)t++;let s=Pr.decode(i.subarray(e,t));return t++,t=t+3&-4,Le[0]=s,Le[1]=t,Le}function ye(i){return i.slice()}function xr(i){return!i||i.length<8?!1:i[0]===35&&i[1]===98}function Ke(i){if(!xr(i))return null;let e=new DataView(i.buffer,i.byteOffset,i.byteLength),t=e.getUint32(8,!1),s=e.getUint32(12,!1);return t+s/pe}var U={wasmHeapSize:8388608,ringBufferReserved:3145728,rtPoolSize:33554432,bufferPoolSize:4194304,maxBufferPoolSize:805306368,get rtPoolOffset(){return this.wasmHeapSize+this.ringBufferReserved},get bufferPoolOffset(){return this.rtPoolOffset+this.rtPoolSize},get totalMemory(){return this.bufferPoolOffset+this.bufferPoolSize},get maxTotalMemory(){return this.bufferPoolOffset+this.maxBufferPoolSize},get totalPages(){return Math.ceil(this.totalMemory/65536)}};var Ze={numBuffers:1024,maxNodes:8192,maxGraphDefs:1024,maxWireBufs:64,numAudioBusChannels:128,numInputBusChannels:2,numOutputBusChannels:2,numControlBusChannels:4096,bufLength:128,realTimeMemorySize:8192,numRGens:64,realTime:!1,memoryLocking:!1,loadGraphDefs:0,preferredSampleRate:0,verbosity:0};var Fr=1e4,vr=5e3,Hr=150,Gr=new Set(["/b_alloc","/b_allocRead","/b_allocReadChannel","/b_allocFile"]),b=[];for(let i=0;i<256;i++)b[i]=i.toString(16).padStart(2,"0");function zr(i){return b[i[0]]+b[i[1]]+b[i[2]]+b[i[3]]+"-"+b[i[4]]+b[i[5]]+"-"+b[i[6]]+b[i[7]]+"-"+b[i[8]]+b[i[9]]+"-"+b[i[10]]+b[i[11]]+b[i[12]]+b[i[13]]+b[i[14]]+b[i[15]]}function rs(i){return"\u2026"+b[i[13]]+b[i[14]]+b[i[15]]}function ss(i,e){if(i&&i.type==="uuid"&&i.value)return rs(i.value);if(i instanceof Uint8Array||i instanceof ArrayBuffer)return`<${i.byteLength||i.length} bytes>`;let t=JSON.stringify(i);return e&&t.length>e?t.slice(0,e)+"...":t}function q(i){return String(i).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function is(i,e,t){if(i&&i.type==="uuid"&&i.value)return`<span class="supersonic-scsynth-string" title="${zr(i.value)}">${rs(i.value)}</span>`;let s=i,r=null;if(typeof i=="object"&&i!==null&&i.value!==void 0&&(s=i.value,r=i.type),r==="b"||s instanceof Uint8Array||s instanceof ArrayBuffer)return`<span class="supersonic-scsynth-binary"><${s.byteLength??s.length??"?"} bytes></span>`;let n=r==="f"||r===null&&typeof s=="number"&&!Number.isInteger(s),o=r==="i"||r===null&&Number.isInteger(s),c=e==="/s_new"&&t>=4&&(t-4)%2===0&&typeof s=="string";return n?`<span class="supersonic-scsynth-float">${parseFloat(s.toFixed(3))}</span>`:o?`<span class="supersonic-scsynth-int">${s}</span>`:c?`<span class="supersonic-scsynth-param">${q(s)}</span>`:typeof s=="string"?`<span class="supersonic-scsynth-string">${q(JSON.stringify(s))}</span>`:`<span class="supersonic-scsynth-string">${q(s)}</span>`}function je(i,e,t,s,r){let n=i[0],o=i.slice(1),a=s&&t?(t-s).toFixed(2):"",c=`<span class="supersonic-scsynth-seq">[${e}]</span>`;if(a&&(c+=` <span class="supersonic-scsynth-time">${a}</span>`),r!==void 0&&(c+=` <span class="supersonic-scsynth-source">ch${r}</span>`),c+=` <span class="supersonic-scsynth-address">${q(n)}</span>`,o.length>0){let u=o.map((l,f)=>is(l,n,f)).join(", ");c+=" "+u}return c}function Yr(i,e,t,s,r){if(!i.packets)return je(i,e,t,s,r);if(i.packets.length===1)return je(i.packets[0],e,t,s,r);let n=s&&t?(t-s).toFixed(2):"",o=`<span class="supersonic-scsynth-seq">[${e}]</span>`;n&&(o+=` <span class="supersonic-scsynth-time">${n}</span>`),r!==void 0&&(o+=` <span class="supersonic-scsynth-source">ch${r}</span>`),o+=` <span class="supersonic-scsynth-bundle">Bundle (${i.packets.length})</span>`;for(let a of i.packets){let c=a[0],u=a.slice(1);o+=`<br><span class="supersonic-scsynth-address">${q(c)}</span>`,u.length>0&&(o+=" "+u.map((l,f)=>is(l,c,f)).join(", "))}return o}var Qe=class i{static osc={encodeMessage:(e,t)=>ye(jt(e,t)),encodeBundle:(e,t)=>ye(Qt(e,t)),decode:e=>V(e),encodeSingleBundle:(e,t,s)=>ye(Jt(e,t,s)),readTimetag:e=>be(e),ntpNow:()=>M(),NTP_EPOCH_OFFSET:$e};static#r=null;static getMetricsSchema(){return this.#r??={metrics:{scsynthProcessCount:{offset:0,type:"counter",unit:"count",description:"Audio process() calls"},scsynthMessagesProcessed:{offset:1,type:"counter",unit:"count",description:"OSC messages processed by scsynth"},scsynthMessagesDropped:{offset:2,type:"counter",unit:"count",description:"Messages dropped (ring buffer full)"},scsynthSchedulerDepth:{offset:3,type:"gauge",unit:"count",description:"Current scheduler queue depth"},scsynthSchedulerPeakDepth:{offset:4,type:"gauge",unit:"count",description:"Peak scheduler queue depth (high water mark)"},scsynthSchedulerDropped:{offset:5,type:"counter",unit:"count",description:"Scheduled events dropped"},scsynthSequenceGaps:{offset:6,type:"counter",unit:"count",description:"Messages lost in transit from JS to scsynth"},scsynthWasmErrors:{offset:7,type:"counter",unit:"count",description:"WASM execution errors in audio worklet"},scsynthSchedulerLates:{offset:8,type:"counter",unit:"count",description:"Bundles executed after their scheduled time"},preschedulerPending:{offset:9,type:"gauge",unit:"count",description:"Events waiting to be scheduled"},preschedulerPendingPeak:{offset:10,type:"gauge",unit:"count",description:"Peak pending events"},preschedulerBundlesScheduled:{offset:11,type:"counter",unit:"count",description:"Bundles scheduled"},preschedulerDispatched:{offset:12,type:"counter",unit:"count",description:"Events sent to worklet"},preschedulerEventsCancelled:{offset:13,type:"counter",unit:"count",description:"Events cancelled"},preschedulerMinHeadroomMs:{offset:14,type:"gauge",unit:"ms",description:"Smallest time gap between JS prescheduler dispatch and scsynth scheduler execution"},preschedulerLates:{offset:15,type:"counter",unit:"count",description:"Bundles dispatched after their scheduled execution time"},preschedulerRetriesSucceeded:{offset:16,type:"counter",unit:"count",description:"Retries that succeeded"},preschedulerRetriesFailed:{offset:17,type:"counter",unit:"count",description:"Retries that failed"},preschedulerRetryQueueSize:{offset:18,type:"gauge",unit:"count",description:"Current retry queue size"},preschedulerRetryQueuePeak:{offset:19,type:"gauge",unit:"count",description:"Peak retry queue size"},preschedulerMessagesRetried:{offset:20,type:"counter",unit:"count",description:"Messages that needed retry"},preschedulerTotalDispatches:{offset:21,type:"counter",unit:"count",description:"Total dispatch attempts"},preschedulerBypassed:{offset:22,type:"counter",unit:"count",description:"Messages sent directly from JS to scsynth, bypassing prescheduler (aggregate)"},preschedulerMaxLateMs:{offset:23,type:"gauge",unit:"ms",description:"Maximum lateness at prescheduler (ms)"},oscOutMessagesSent:{offset:24,type:"counter",unit:"count",description:"OSC messages sent from JS to scsynth"},oscOutBytesSent:{offset:25,type:"counter",unit:"bytes",description:"Total bytes sent from JS to scsynth"},oscInMessagesReceived:{offset:26,type:"counter",unit:"count",description:"OSC replies received from scsynth to JS"},oscInBytesReceived:{offset:27,type:"counter",unit:"bytes",description:"Total bytes received from scsynth to JS"},oscInMessagesDropped:{offset:28,type:"counter",unit:"count",description:"Replies lost in transit from scsynth to JS"},oscInCorrupted:{offset:29,type:"counter",unit:"count",description:"Corrupted messages detected from scsynth to JS"},debugMessagesReceived:{offset:30,type:"counter",unit:"count",description:"Debug messages from scsynth"},debugBytesReceived:{offset:31,type:"counter",unit:"bytes",description:"Debug bytes received"},inBufferUsedBytes:{offset:32,type:"gauge",unit:"bytes",description:"Bytes used in IN ring buffer"},outBufferUsedBytes:{offset:33,type:"gauge",unit:"bytes",description:"Bytes used in OUT ring buffer"},debugBufferUsedBytes:{offset:34,type:"gauge",unit:"bytes",description:"Bytes used in DEBUG ring buffer"},inBufferPeakBytes:{offset:35,type:"gauge",unit:"bytes",description:"Peak bytes used in IN ring buffer"},outBufferPeakBytes:{offset:36,type:"gauge",unit:"bytes",description:"Peak bytes used in OUT ring buffer"},debugBufferPeakBytes:{offset:37,type:"gauge",unit:"bytes",description:"Peak bytes used in DEBUG ring buffer"},bypassNonBundle:{offset:38,type:"counter",unit:"count",description:"Plain OSC messages (not bundles) that bypassed prescheduler"},bypassImmediate:{offset:39,type:"counter",unit:"count",description:"Bundles with timetag 0 or 1 that bypassed prescheduler"},bypassNearFuture:{offset:40,type:"counter",unit:"count",description:"Bundles within bypass lookahead threshold that bypassed prescheduler"},bypassLate:{offset:41,type:"counter",unit:"count",description:"Timestamped OSC bundles arriving late into SuperSonic bypassing prescheduler"},scsynthSchedulerMaxLateMs:{offset:42,type:"gauge",unit:"ms",description:"Maximum lateness observed in scsynth scheduler (ms)"},scsynthSchedulerLastLateMs:{offset:43,type:"gauge",unit:"ms",description:"Most recent late magnitude in scsynth scheduler (ms)"},scsynthSchedulerLastLateTick:{offset:44,type:"gauge",unit:"count",description:"Process count when last scsynth late occurred"},ringBufferDirectWriteFails:{offset:45,type:"counter",unit:"count",description:"SAB mode only: optimistic direct writes attempted but failed due to ring buffer lock not being available (delivered via prescheduler instead)"},driftOffsetMs:{offset:46,type:"gauge",unit:"ms",signed:!0,description:"Clock drift between AudioContext and wall clock"},clockOffsetMs:{offset:47,type:"gauge",unit:"ms",signed:!0,description:"Clock offset for multi-system sync"},audioContextState:{offset:48,type:"enum",values:["unknown","running","suspended","closed","interrupted"],description:"AudioContext state"},bufferPoolUsedBytes:{offset:49,type:"gauge",unit:"bytes",description:"Buffer pool bytes used"},bufferPoolAvailableBytes:{offset:50,type:"gauge",unit:"bytes",description:"Buffer pool bytes available"},bufferPoolAllocations:{offset:51,type:"counter",unit:"count",description:"Total buffer allocations"},loadedSynthDefs:{offset:52,type:"gauge",unit:"count",description:"Number of loaded synthdefs"},scsynthSchedulerCapacity:{offset:53,type:"constant",unit:"count",description:"Maximum scheduler queue size"},preschedulerCapacity:{offset:54,type:"constant",unit:"count",description:"Maximum pending events in prescheduler"},inBufferCapacity:{offset:55,type:"constant",unit:"bytes",description:"IN ring buffer capacity"},outBufferCapacity:{offset:56,type:"constant",unit:"bytes",description:"OUT ring buffer capacity"},debugBufferCapacity:{offset:57,type:"constant",unit:"bytes",description:"DEBUG ring buffer capacity"},mode:{offset:58,type:"enum",values:["sab","postMessage"],description:"Transport mode"},glitchCount:{offset:59,type:"counter",unit:"count",description:"Chrome only: audio underrun/glitch events"},glitchDurationMs:{offset:60,type:"gauge",unit:"ms",description:"Chrome only: total silence from audio underruns"},averageLatencyUs:{offset:61,type:"gauge",unit:"us",description:"Chrome only: average audio output latency"},maxLatencyUs:{offset:62,type:"gauge",unit:"us",description:"Chrome only: maximum audio output latency"},audioHealthPct:{offset:63,type:"gauge",unit:"%",description:"Cross-browser: fraction of expected audio frames delivered (100% = no issues)"},totalFramesDurationMs:{offset:64,type:"counter",unit:"ms",description:"Chrome only: total audio rendered duration"},hasPlaybackStats:{offset:65,type:"gauge",unit:"bool",description:"1 if Chrome playbackStats API is available, 0 otherwise"},bufferPoolTotalCapacity:{offset:66,type:"gauge",unit:"bytes",description:"Buffer pool committed capacity (grows on demand)"},bufferPoolMaxCapacity:{offset:67,type:"gauge",unit:"bytes",description:"Buffer pool hard ceiling"},bufferPoolGrowthCount:{offset:68,type:"counter",unit:"count",description:"Number of buffer pool growth events"},bufferPoolPoolCount:{offset:69,type:"gauge",unit:"count",description:"Number of buffer pool segments"}},layout:{panels:[{title:"OSC Out",rows:[{label:"sent",cells:[{key:"oscOutMessagesSent"}]},{label:"bytes",cells:[{key:"oscOutBytesSent",kind:"muted",format:"bytes"}]},{label:"bypass",cells:[{key:"preschedulerBypassed",kind:"green"}]},{label:"lost",cells:[{key:"scsynthSequenceGaps",kind:"error"}]}]},{title:"Bypass",rows:[{label:"msg",cells:[{key:"bypassNonBundle",kind:"muted"}]},{label:"imm",cells:[{key:"bypassImmediate",kind:"muted"}]},{label:"near",cells:[{key:"bypassNearFuture",kind:"muted"}]},{label:"late",cells:[{key:"bypassLate",kind:"muted"}]}]},{title:"OSC In",rows:[{label:"received",cells:[{key:"oscInMessagesReceived"}]},{label:"bytes",cells:[{key:"oscInBytesReceived",kind:"muted",format:"bytes"}]},{label:"dropped",cells:[{key:"oscInMessagesDropped",kind:"error"}]},{label:"corrupted",cells:[{key:"oscInCorrupted",kind:"error"}]}]},{title:"Presched Flow",rows:[{label:"pending",tooltip:"Current pending events | peak pending events",cells:[{key:"preschedulerPending"},{sep:" | "},{key:"preschedulerPendingPeak",kind:"muted"}]},{label:"scheduled",cells:[{key:"preschedulerBundlesScheduled"}]},{label:"dispatched",cells:[{key:"preschedulerDispatched",kind:"dim"}]},{label:"min slack",cells:[{key:"preschedulerMinHeadroomMs",kind:"dim",format:"headroom"},{text:" ms",kind:"muted"}]}]},{title:"Presched Health",rows:[{label:"lates",tooltip:"Bundles dispatched after their scheduled time (count and max lateness in ms)",cells:[{key:"preschedulerLates",kind:"error"},{sep:" ("},{key:"preschedulerMaxLateMs",kind:"dim"},{text:" ms max)",kind:"muted"}]},{label:"cancelled",cells:[{key:"preschedulerEventsCancelled",kind:"error"}]},{label:"retried",tooltip:"Messages retried | succeeded | failed",cells:[{key:"preschedulerMessagesRetried",kind:"dim"},{sep:" | "},{key:"preschedulerRetriesSucceeded",kind:"green"},{sep:" | "},{key:"preschedulerRetriesFailed",kind:"error"}]},{label:"retry queue",tooltip:"Current retry queue size | peak size",cells:[{key:"preschedulerRetryQueueSize"},{sep:" | "},{key:"preschedulerRetryQueuePeak",kind:"muted"}]}]},{title:"scsynth Scheduler",rows:[{label:"queue",tooltip:"Current scheduler queue depth | peak depth",cells:[{key:"scsynthSchedulerDepth"},{sep:" | "},{key:"scsynthSchedulerPeakDepth",kind:"muted"}]},{label:"dropped",cells:[{key:"scsynthSchedulerDropped",kind:"error"}]},{label:"lates",cells:[{key:"scsynthSchedulerLates",kind:"error"}]},{label:"max | last",tooltip:"Maximum lateness observed | most recent late magnitude (ms)",cells:[{key:"scsynthSchedulerMaxLateMs",kind:"error"},{sep:" | "},{key:"scsynthSchedulerLastLateMs",kind:"dim"},{text:" ms",kind:"muted"}]}]},{title:"scsynth",rows:[{label:"ticks",tooltip:"Audio process() callback count and OSC messages processed",cells:[{key:"scsynthProcessCount",kind:"dim"},{sep:" | "},{key:"scsynthMessagesProcessed",kind:"muted"},{text:" msgs",kind:"muted"}]},{label:"dropped",cells:[{key:"scsynthMessagesDropped",kind:"error"}]},{label:"drift",cells:[{key:"driftOffsetMs",format:"signed"},{text:" ms",kind:"muted"}]},{label:"debug",tooltip:"Debug messages from scsynth (count and bytes)",cells:[{key:"debugMessagesReceived",kind:"muted"},{text:" ("},{key:"debugBytesReceived",kind:"muted",format:"bytes"},{text:")"}]}]},{title:"Ring Buffer Level",class:"wide",rows:[{type:"bar",label:"in",usedKey:"inBufferUsedBytes",peakKey:"inBufferPeakBytes",capacityKey:"inBufferCapacity",color:"blue"},{type:"bar",label:"out",usedKey:"outBufferUsedBytes",peakKey:"outBufferPeakBytes",capacityKey:"outBufferCapacity",color:"green"},{type:"bar",label:"dbg",usedKey:"debugBufferUsedBytes",peakKey:"debugBufferPeakBytes",capacityKey:"debugBufferCapacity",color:"purple"},{label:"direct write fails",cells:[{key:"ringBufferDirectWriteFails",kind:"error"}]}]},{title:"Buffers & SynthDefs",rows:[{label:"buf used",cells:[{key:"bufferPoolUsedBytes",format:"bytes"}]},{label:"buf free",cells:[{key:"bufferPoolAvailableBytes",kind:"green",format:"bytes"}]},{label:"buf allocs",cells:[{key:"bufferPoolAllocations",kind:"dim"}]},{label:"synthdefs",cells:[{key:"loadedSynthDefs"}]}]},{title:"AudioWorklet",rows:[{label:"health",tooltip:"AudioContext state and audio health percentage (fraction of expected frames delivered)",cells:[{key:"audioContextState",kind:"green",format:"enum"},{sep:" | "},{key:"audioHealthPct",kind:"green",format:"percent"},{text:" %",kind:"muted"}]},{label:"glitches",tooltip:"Chrome only: audio underrun/glitch events and total silence duration",cells:[{key:"glitchCount",kind:"error",format:"chromeOnly"},{sep:" ("},{key:"glitchDurationMs",kind:"error",format:"chromeOnly"},{text:" ms)",kind:"muted"}]},{label:"latency",tooltip:"Chrome only: avg | max audio output latency in ms",cells:[{key:"averageLatencyUs",kind:"dim",format:"chromeLatencyUs"},{sep:" | "},{key:"maxLatencyUs",kind:"dim",format:"chromeLatencyUs"},{text:" ms",kind:"muted"}]},{label:"WASM errors",cells:[{key:"scsynthWasmErrors",kind:"error"}]}]}]},sentinels:{HEADROOM_UNSET:4294967295}}}static getTreeSchema(){return{nodeCount:{type:"number",description:"Total nodes in tree"},version:{type:"number",description:"Increments on any tree change, useful for detecting updates"},droppedCount:{type:"number",description:"Nodes that exceeded mirror capacity (tree may be incomplete)"},root:{type:"object",description:"Root node of the tree (always a group with id 0)",schema:{id:{type:"number",description:"Unique node ID"},type:{type:"string",values:["group","synth"],description:"Node type"},defName:{type:"string",description:"Synthdef name (synths only, empty for groups)"},children:{type:"array",description:"Child nodes (recursive)",itemSchema:"(self)"}}}}}static getRawTreeSchema(){return{nodeCount:{type:"number",description:"Total nodes in tree"},version:{type:"number",description:"Increments on any tree change, useful for detecting updates"},droppedCount:{type:"number",description:"Nodes that exceeded mirror capacity (tree may be incomplete)"},nodes:{type:"array",description:"Flat array of all nodes with internal linkage pointers",itemSchema:{id:{type:"number",description:"Unique node ID"},parentId:{type:"number",description:"Parent node ID (-1 for root)"},isGroup:{type:"boolean",description:"True if group, false if synth"},prevId:{type:"number",description:"Previous sibling node ID (-1 if none)"},nextId:{type:"number",description:"Next sibling node ID (-1 if none)"},headId:{type:"number",description:"First child node ID (groups only, -1 if empty)"},defName:{type:"string",description:"Synthdef name (synths only, empty for groups)"}}}}}#e;#s;#a=null;#o;#c;#i;#n;#u;#l;#y;#S;#g;#d;#E;#p;#_;#T;#t;#f;#h;#m;#b;#A;#w;#C=1e3;#R=null;#B=null;#I=0;#O=[];#P=null;#D=Promise.resolve();#U=null;#x(e){let t=[["numBuffers",1,65535],["maxNodes",1],["maxGraphDefs",1],["maxWireBufs",1],["numAudioBusChannels",1],["numInputBusChannels",0],["numOutputBusChannels",1,128],["numControlBusChannels",1],["realTimeMemorySize",1],["numRGens",1],["preferredSampleRate",0,384e3],["verbosity",0,4]];for(let[s,r,n]of t){let o=e[s];if(typeof o!="number"||!Number.isFinite(o))throw new Error(`scsynthOptions.${s} must be a finite number, got: ${o}`);if(o<r)throw new Error(`scsynthOptions.${s} must be >= ${r}, got: ${o}`);if(n!==void 0&&o>n)throw new Error(`scsynthOptions.${s} must be <= ${n}, got: ${o}`)}if(e.bufLength!==128)throw new Error(`scsynthOptions.bufLength must be 128 (WebAudio API constraint), got: ${e.bufLength}`);for(let s of["realTime","memoryLocking"])if(typeof e[s]!="boolean")throw new Error(`scsynthOptions.${s} must be a boolean, got: ${typeof e[s]}`);if(e.loadGraphDefs!==0&&e.loadGraphDefs!==1)throw new Error(`scsynthOptions.loadGraphDefs must be 0 or 1, got: ${e.loadGraphDefs}`);if(e.preferredSampleRate!==0&&e.preferredSampleRate<8e3)throw new Error(`scsynthOptions.preferredSampleRate must be 0 (auto) or >= 8000, got: ${e.preferredSampleRate}`)}#L(e,t){let s=e?{...U,...e}:{...U},r=t?.realTimeMemorySize||Ze.realTimeMemorySize;return r&&(s.rtPoolSize=Math.max(s.rtPoolSize,r*1024)),s.rtPoolOffset=(s.wasmHeapSize||U.wasmHeapSize)+(s.ringBufferReserved||U.ringBufferReserved),s.bufferPoolOffset=s.rtPoolOffset+s.rtPoolSize,s.totalMemory=s.bufferPoolOffset+s.bufferPoolSize,s.maxTotalMemory=s.bufferPoolOffset+s.maxBufferPoolSize,s}constructor(e={}){this.#d=!1,this.#E=!1,this.#p=null,this.#_={},this.#T=null,this.#f=new re,this.#h=new ie({mode:e.mode||"postMessage"}),this.#b=new fe({}),this.#e=null,this.#s=null,this.#o=null,this.#i=null,this.loadedSynthDefs=new Map;let t=e.baseURL||null,s=e.coreBaseURL||t,r=e.workerBaseURL||(t?`${t}workers/`:null),n=e.wasmBaseURL||(s?`${s}wasm/`:null);if(!r||!n)throw new Error(`SuperSonic requires explicit URL configuration.
|
|
5
|
+
Or install: npm install supersonic-scsynth-samples`);return this.#e+e}#T(e){if(!Number.isInteger(e)||e<0||e>=this.MAX_BUFFERS)throw new Error(`Invalid buffer number ${e} (must be 0-${this.MAX_BUFFERS-1})`)}async#t(e,t,s){let r=null,n=null,o=!1,a=await this.#C(e),c=!1;try{await this.#B(e);let{ptr:u,sizeBytes:l,numFrames:f,numChannels:h,sampleRate:y,source:p,...d}=await s();r=u;let{uuid:m,allocationComplete:E}=this.#w(e,t);n=m,this.#R(e,r,l,m,E,{numFrames:f,numChannels:h,sampleRate:y,source:p}),o=!0;let g=this.#I(e,m,E);return a(),c=!0,{ptr:r,uuid:m,allocationComplete:g,numFrames:f,numChannels:h,sampleRate:y,...d}}catch(u){throw o&&n?this.#O(e,n,!1):r&&this.#i.free(r),u}finally{c||a()}}async prepareFromBlob(e){let{bufnum:t,blob:s,startFrame:r=0,numFrames:n=0,channels:o=null}=e;if(this.#T(t),!s||!(s instanceof ArrayBuffer||ArrayBuffer.isView(s)))throw new Error("/b_allocFile requires audio data as ArrayBuffer or typed array");let a=await this.#_({source:s,startFrame:r,numFrames:n,channels:o});return this.#E(t,3e4,a,null)}async prepareFromFile(e){let{bufnum:t,path:s,startFrame:r=0,numFrames:n=0,channels:o=null}=e;this.#T(t);let a=await this.#_({source:s,startFrame:r,numFrames:n,channels:o});return this.#E(t,6e4,a,a.sourceInfo)}async prepareEmpty(e){let{bufnum:t,numFrames:s,numChannels:r=1,sampleRate:n=null}=e;if(this.#T(t),!Number.isFinite(s)||s<=0)throw new Error(`/b_alloc requires a positive number of frames (got ${s})`);if(!Number.isFinite(r)||r<=0)throw new Error(`/b_alloc requires a positive channel count (got ${r})`);let o=Math.floor(s),a=Math.floor(r),c=o*a+(this.GUARD_BEFORE+this.GUARD_AFTER)*a,l={interleaved:new Float32Array(c),numFrames:o,numChannels:a,sampleRate:n||this.#a.sampleRate};return this.#E(t,5e3,l,null)}#f(e,t){return!e||e.length===0?Array.from({length:t},(s,r)=>r):(e.forEach(s=>{if(!Number.isInteger(s)||s<0||s>=t)throw new Error(`Channel ${s} is out of range (file has ${t} channels)`)}),e)}async#h(e){let t=this.#i.malloc(e);return t===0&&this.#i.canGrow()&&await this.#i.grow(e)&&(t=this.#i.malloc(e)),t}async#m(e){let t=e*4,s=await this.#h(t);if(s===0){let r=this.#i.stats(),n=((r.available||0)/(1024*1024)).toFixed(2),o=((r.total||0)/(1024*1024)).toFixed(2),a=((this.#i.maxCapacity||0)/(1024*1024)).toFixed(2),c=(t/(1024*1024)).toFixed(2);throw new Error(`Buffer pool allocation failed: requested ${c}MB, available ${n}MB of ${o}MB total (max ${a}MB)`)}return s}async#b(e,t){if(this.#r==="sab"){let s=this.#c?.buffer||this.#o;new Float32Array(s,e,t.length).set(t)}else{let s=crypto.randomUUID(),r=new Promise((o,a)=>{let c=setTimeout(()=>{a(new Error("Buffer copy to WASM memory timed out"))},1e4),u=l=>{let f=l.data;f.type==="bufferCopied"&&f.copyId===s&&(this.#y.removeEventListener("message",u),clearTimeout(c),f.success?o():a(new Error(f.error||"Buffer copy failed")))};this.#y.addEventListener("message",u)}),n=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);this.#y.postMessage({type:"copyBufferData",copyId:s,ptr:e,data:n},[n]),await r}}#A(e,t,s){return new Promise((r,n)=>{let o=setTimeout(()=>{this.#u.delete(e),n(new Error(`Buffer ${t} allocation timeout (${s}ms)`))},s);this.#u.set(e,{resolve:r,reject:n,timeout:o})})}#w(e,t){let s=crypto.randomUUID(),r=this.#A(s,e,t);return{uuid:s,allocationComplete:r}}async#C(e){let t=this.#l.get(e)||Promise.resolve(),s,r=new Promise(n=>{s=n});return this.#l.set(e,t.then(()=>r)),await t,()=>{s&&(s(),s=null),this.#l.get(e)===r&&this.#l.delete(e)}}#R(e,t,s,r,n,o={}){let a=this.#n.get(e),c={ptr:t,size:s,numFrames:o.numFrames||0,numChannels:o.numChannels||1,sampleRate:o.sampleRate||48e3,pendingToken:r,pendingPromise:n,previousAllocation:a?{ptr:a.ptr,size:a.size}:null,source:o.source||null};return this.#n.set(e,c),c}async#B(e){let t=this.#n.get(e);if(t&&t.pendingToken&&t.pendingPromise)try{await t.pendingPromise}catch{}}#I(e,t,s){return!s||typeof s.then!="function"?(this.#O(e,t,!0),Promise.resolve()):s.then(r=>(this.#O(e,t,!0),r)).catch(r=>{throw this.#O(e,t,!1),r})}#O(e,t,s){let r=this.#n.get(e);if(!r||r.pendingToken!==t)return;let n=r.previousAllocation;if(s){r.pendingToken=null,r.pendingPromise=null,r.previousAllocation=null,n?.ptr&&this.#i.free(n.ptr);return}r.ptr&&this.#i.free(r.ptr),r.pendingPromise=null,n?.ptr?this.#n.set(e,{ptr:n.ptr,size:n.size,pendingToken:null,previousAllocation:null}):this.#n.delete(e)}handleBufferFreed(e){let t=typeof e[0]=="bigint"?Number(e[0]):e[0],s=typeof e[1]=="bigint"?Number(e[1]):e[1],r=this.#n.get(t);if(!r){typeof s=="number"&&s!==0&&this.#i.free(s);return}if(typeof s=="number"&&s===r.ptr){this.#i.free(r.ptr),this.#n.delete(t);return}if(typeof s=="number"&&r.previousAllocation&&r.previousAllocation.ptr===s){this.#i.free(s),r.previousAllocation=null;return}this.#i.free(r.ptr),this.#n.delete(t)}handleBufferAllocated(e){let t=e[0],s=e[1],r=this.#u.get(t);r&&(clearTimeout(r.timeout),r.resolve({bufnum:s}),this.#u.delete(t))}async allocate(e){return this.#h(e*4)}free(e){return this.#i.free(e)}getView(e,t){let s=this.#c?.buffer||this.#o;return new Float32Array(s,e,t)}getStats(){return this.#i?this.#i.stats():{total:0,available:0,used:0,allocations:0}}getGrowthStats(){return this.#i?{totalCapacity:this.#i.totalCapacity,maxCapacity:this.#i.maxCapacity,growthCount:this.#i.growthCount,poolCount:this.#i.poolCount}:{totalCapacity:0,maxCapacity:0,growthCount:0,poolCount:0}}async sampleInfo({source:e,startFrame:t=0,numFrames:s=0,channels:r=null}){let n=await this.#_({source:e,startFrame:t,numFrames:s,channels:r});return{hash:await this.#S(n.interleaved),source:n.sourceInfo?.path||null,numFrames:n.numFrames,numChannels:n.numChannels,sampleRate:n.sampleRate,duration:n.sampleRate>0?n.numFrames/n.sampleRate:0}}getAllocatedBuffers(){let e=[];for(let[t,s]of this.#n.entries())!s||!s.ptr||e.push({bufnum:t,ptr:s.ptr,numFrames:s.numFrames,numChannels:s.numChannels,sampleRate:s.sampleRate,source:s.source||null,hash:s.hash||null});return e}updateAudioContext(e){if(!e)throw new Error("BufferManager.updateAudioContext requires audioContext");this.#a=e}destroy(){for(let[e,t]of this.#u.entries())clearTimeout(t.timeout),t.reject(new Error("BufferManager destroyed"));this.#u.clear();for(let[e,t]of this.#n.entries())t.ptr&&this.#i.free(t.ptr);this.#n.clear(),this.#l.clear()}};var te=class{#r;#e;#s;#a;constructor(e={}){let{onLoadingEvent:t=null,maxRetries:s=3,baseDelay:r=1e3,skipHeadRequests:n=!1}=e;this.#r=t,this.#e=s,this.#s=r,this.#a=n}async fetch(e,{type:t,name:s}){let r=this.#c(e);if(this.#a)this.#r?.("loading:start",{type:t,name:s});else{let a=await this.#o(e);this.#r?.("loading:start",{type:t,name:s,...a!=null&&{size:a}})}let o=await(await r).arrayBuffer();return this.#r?.("loading:complete",{type:t,name:s,size:o.byteLength}),o}async#o(e){try{let t=await fetch(e,{method:"HEAD"});if(t.ok){let s=t.headers.get("Content-Length");return s?parseInt(s,10):null}return null}catch{return null}}async#c(e){let t;for(let s=0;s<=this.#e;s++)try{let r=await fetch(e);if(r.status>=400&&r.status<500)throw new Error(`Failed to fetch ${e}: ${r.status} ${r.statusText}`);if(!r.ok)throw new Error(`Server error fetching ${e}: ${r.status} ${r.statusText}`);return r}catch(r){if(t=r,r.message.match(/Failed to fetch .+: 4\d{2} /))throw r;if(s<this.#e){let n=this.#s*Math.pow(2,s);await this.#i(n)}}throw t}#i(e){return new Promise(t=>setTimeout(t,e))}};var se=class{#r;#e;constructor({bufferManager:e,getDefaultSampleRate:t}){if(!e)throw new Error("OSCRewriter requires bufferManager");if(typeof t!="function")throw new Error("OSCRewriter requires getDefaultSampleRate callback");this.#r=e,this.#e=t}async rewritePacket(e){if(Array.isArray(e)){let{message:t,changed:s}=await this.#s(e);return{packet:t,changed:s}}if(this.#u(e)){let t=await Promise.all(e.packets.map(n=>this.rewritePacket(n)));if(!t.some(n=>n.changed))return{packet:e,changed:!1};let r=t.map(n=>n.packet);return{packet:{timeTag:e.timeTag,packets:r},changed:!0}}return{packet:e,changed:!1}}async#s(e){let t=e[0],s=e.slice(1);switch(t){case"/b_alloc":return{message:await this.#a(s),changed:!0};case"/b_allocRead":return{message:await this.#o(s),changed:!0};case"/b_allocReadChannel":return{message:await this.#c(s),changed:!0};case"/b_allocFile":return{message:await this.#i(s),changed:!0};default:return{message:e,changed:!1}}}async#a(e){let t=this.#S(e,0,"/b_alloc requires a buffer number"),s=this.#S(e,1,"/b_alloc requires a frame count"),r=2,n=1,o=this.#e();Number.isFinite(this.#l(e,r))&&(n=Math.max(1,this.#_(e,r,1)),r++),(Array.isArray(e)?e[r]:void 0)?.type==="b"&&r++;let a=this.#l(e,r);Number.isFinite(a)&&(o=a);let c=await this.#r.prepareEmpty({bufnum:t,numFrames:s,numChannels:n,sampleRate:o});return this.#p(c.allocationComplete,`/b_alloc ${t}`),this.#n(t,c)}async#o(e){let t=this.#S(e,0,"/b_allocRead requires a buffer number"),s=this.#d(e,1,"/b_allocRead requires a file path"),r=this.#_(e,2,0),n=this.#_(e,3,0),o=await this.#r.prepareFromFile({bufnum:t,path:s,startFrame:r,numFrames:n});return this.#p(o.allocationComplete,`/b_allocRead ${t}`),this.#n(t,o)}async#c(e){let t=this.#S(e,0,"/b_allocReadChannel requires a buffer number"),s=this.#d(e,1,"/b_allocReadChannel requires a file path"),r=this.#_(e,2,0),n=this.#_(e,3,0),o=[];for(let c=4;c<(e?.length||0);c++){let u=this.#l(e,c);if(!Number.isFinite(u))break;o.push(Math.floor(u))}let a=await this.#r.prepareFromFile({bufnum:t,path:s,startFrame:r,numFrames:n,channels:o.length>0?o:null});return this.#p(a.allocationComplete,`/b_allocReadChannel ${t}`),this.#n(t,a)}async#i(e){let t=this.#S(e,0,"/b_allocFile requires a buffer number"),s=this.#E(e,1,"/b_allocFile requires audio file data as blob"),r=await this.#r.prepareFromBlob({bufnum:t,blob:s});return this.#p(r.allocationComplete,`/b_allocFile ${t}`),this.#n(t,r)}#n(e,t){return["/b_allocPtr",Math.floor(e),Math.floor(t.ptr),Math.floor(t.numFrames),Math.floor(t.numChannels),t.sampleRate,String(t.uuid)]}#u(e){return e&&e.timeTag!==void 0&&Array.isArray(e.packets)}#l(e,t){let s=Array.isArray(e)?e[t]:void 0;if(s!=null)return typeof s=="object"&&Object.prototype.hasOwnProperty.call(s,"value")?s.value:s}#y(e,t,s,r){let n=this.#l(e,t);if(!s(n))throw new Error(r);return n}#S(e,t,s){return Math.floor(this.#y(e,t,Number.isFinite,s))}#_(e,t,s=0){let r=this.#l(e,t);return Number.isFinite(r)?Math.floor(r):s}#d(e,t,s){return this.#y(e,t,r=>typeof r=="string",s)}#E(e,t,s){return this.#y(e,t,r=>r instanceof Uint8Array||r instanceof ArrayBuffer,s)}#p(e,t){!e||typeof e.catch!="function"||e.catch(s=>{console.error(`[OSCRewriter] ${t} allocation failed:`,s)})}};function H(i){if(!i)return null;if(typeof i=="string")return(i.split("/").filter(Boolean).pop()||i).replace(/\.scsyndef$/i,"");let e=i instanceof ArrayBuffer?new Uint8Array(i):i;if(!(e instanceof Uint8Array)||e.length<11||e[0]!==83||e[1]!==67||e[2]!==103||e[3]!==102)return null;let s=(e[4]<<24|e[5]<<16|e[6]<<8|e[7])>=3?14:10;if(s>=e.length)return null;let r=e[s];if(r===0||s+1+r>e.length)return null;try{return new TextDecoder().decode(e.slice(s+1,s+1+r))}catch{return null}}var re=class{#r=new Map;on(e,t){if(typeof t!="function")throw new Error("Callback must be a function");return this.#r.has(e)||this.#r.set(e,new Set),this.#r.get(e).add(t),()=>this.off(e,t)}off(e,t){let s=this.#r.get(e);return s&&s.delete(t),this}once(e,t){let s=(...r)=>{this.off(e,s),t(...r)};return this.on(e,s)}removeAllListeners(e){return e===void 0?this.#r.clear():this.#r.delete(e),this}hasListeners(e){let t=this.#r.get(e);return t?t.size>0:!1}emit(e,...t){let s=this.#r.get(e);if(s)for(let r of s)try{r(...t)}catch(n){console.error(`[EventEmitter] Error in ${e} listener:`,n)}}async emitAsync(e,...t){let s=this.#r.get(e);if(s)for(let r of s)try{await r(...t)}catch(n){console.error(`[EventEmitter] Error in ${e} listener:`,n)}}};var Rr={oscOutMessagesSent:24,oscOutBytesSent:25,preschedulerBypassed:22,bypassNonBundle:38,bypassImmediate:39,bypassNearFuture:40,bypassLate:41},ie=class{#r;#e;#s;#a;#o;#c;#i;#n=null;#u=new Uint32Array(70);#l=new DataView(this.#u.buffer);constructor(e={}){this.#a=e.mode||"sab",this.#r=e.sharedBuffer||null,this.#e=e.ringBufferBase||0,this.#s=e.bufferConstants||null}initSharedViews(e,t,s){if(this.#r=e,this.#e=t,this.#s=s,this.#a==="sab"&&e&&s){this.#o=new Int32Array(e),this.#i=at(t,s.CONTROL_START);let r=t+s.METRICS_START;this.#c=new Uint32Array(e,r,s.METRICS_SIZE/4)}}updateSnapshot(e){this.#n=e}getSnapshotBuffer(){return this.#n}getMetricsView(){return this.#c}addMetric(e,t=1){if(!this.#c)return;let s=Rr[e];s!==void 0&&Atomics.add(this.#c,s,t)}overlayPreschedulerMetrics(e){if(!this.#n||!e)return;let t=new Uint32Array(this.#n,0,58),s=9,r=13;t.set(e.subarray(s,s+r),s),t[23]=e[23]}gatherMetrics(e={}){this.updateMergedArray(e);let t=this.#u,s={scsynthProcessCount:t[0],scsynthMessagesProcessed:t[1],scsynthMessagesDropped:t[2],scsynthSchedulerDepth:t[3],scsynthSchedulerPeakDepth:t[4],scsynthSchedulerDropped:t[5],scsynthSequenceGaps:t[6],scsynthSchedulerLates:t[8],scsynthSchedulerMaxLateMs:t[42],scsynthSchedulerLastLateMs:t[43],scsynthSchedulerLastLateTick:t[44],preschedulerPending:t[9],preschedulerPendingPeak:t[10],preschedulerDispatched:t[12],preschedulerRetriesSucceeded:t[16],preschedulerRetriesFailed:t[17],preschedulerBundlesScheduled:t[11],preschedulerEventsCancelled:t[13],preschedulerTotalDispatches:t[21],preschedulerMessagesRetried:t[20],preschedulerRetryQueueSize:t[18],preschedulerRetryQueuePeak:t[19],preschedulerBypassed:t[22],preschedulerMinHeadroomMs:t[14],preschedulerLates:t[15],preschedulerMaxLateMs:t[23],oscInMessagesReceived:t[26],oscInMessagesDropped:t[28],oscInBytesReceived:t[27],debugMessagesReceived:t[30],debugBytesReceived:t[31],oscOutMessagesSent:t[24],oscOutBytesSent:t[25],scsynthWasmErrors:t[7],oscInCorrupted:t[29],ringBufferDirectWriteFails:t[45],bypassNonBundle:t[38],bypassImmediate:t[39],bypassNearFuture:t[40],bypassLate:t[41],mode:this.#a},r=this.#s;return t[32]!==void 0&&r&&(s.inBufferUsed={bytes:t[32],percentage:t[32]/r.IN_BUFFER_SIZE*100,peakBytes:t[35],peakPercentage:t[35]/r.IN_BUFFER_SIZE*100,capacity:r.IN_BUFFER_SIZE},s.outBufferUsed={bytes:t[33],percentage:t[33]/r.OUT_BUFFER_SIZE*100,peakBytes:t[36],peakPercentage:t[36]/r.OUT_BUFFER_SIZE*100,capacity:r.OUT_BUFFER_SIZE},s.debugBufferUsed={bytes:t[34],percentage:t[34]/r.DEBUG_BUFFER_SIZE*100,peakBytes:t[37],peakPercentage:t[37]/r.DEBUG_BUFFER_SIZE*100,capacity:r.DEBUG_BUFFER_SIZE}),r?.scheduler_slot_count!==void 0&&(s.scsynthSchedulerCapacity=r.scheduler_slot_count),e.driftOffsetMs!==void 0&&(s.driftOffsetMs=e.driftOffsetMs),e.ntpStartTime!==void 0&&(s.ntpStartTime=e.ntpStartTime),e.clockOffsetMs!==void 0&&(s.clockOffsetMs=e.clockOffsetMs),e.audioContextState&&(s.audioContextState=e.audioContextState),e.bufferPoolStats&&(s.bufferPoolUsedBytes=e.bufferPoolStats.used.size,s.bufferPoolAvailableBytes=e.bufferPoolStats.available,s.bufferPoolAllocations=e.bufferPoolStats.used.count),e.bufferPoolGrowthStats&&(s.bufferPoolTotalCapacity=e.bufferPoolGrowthStats.totalCapacity,s.bufferPoolMaxCapacity=e.bufferPoolGrowthStats.maxCapacity,s.bufferPoolGrowthCount=e.bufferPoolGrowthStats.growthCount,s.bufferPoolPoolCount=e.bufferPoolGrowthStats.poolCount),e.loadedSynthDefsCount!==void 0&&(s.loadedSynthDefs=e.loadedSynthDefsCount),e.preschedulerCapacity!==void 0&&(s.preschedulerCapacity=e.preschedulerCapacity),s.audioHealthPct=e.audioHealthPct??100,s.hasPlaybackStats=!!e.playbackStats,e.playbackStats?(s.glitchCount=e.playbackStats.fallbackFramesEvents??0,s.glitchDurationMs=Math.round((e.playbackStats.fallbackFramesDuration??0)*1e3),s.averageLatencyUs=Math.round((e.playbackStats.averageLatency??0)*1e6),s.maxLatencyUs=Math.round((e.playbackStats.maximumLatency??0)*1e6),s.totalFramesDurationMs=Math.round((e.playbackStats.totalFramesDuration??0)*1e3)):(s.glitchCount=0,s.glitchDurationMs=0,s.averageLatencyUs=0,s.maxLatencyUs=0,s.totalFramesDurationMs=0),this.#a==="postMessage"&&e.transportMetrics&&Object.assign(s,e.transportMetrics),s}updateMergedArray(e={}){let t=this.#u;if(this.#a==="postMessage"){if(e.preschedulerMetrics&&this.overlayPreschedulerMetrics(e.preschedulerMetrics),this.#n){let a=new Uint32Array(this.#n,0,58);t.set(a)}e.transportMetrics&&(e.transportMetrics.oscOutMessagesSent!==void 0&&(t[24]=e.transportMetrics.oscOutMessagesSent),e.transportMetrics.oscOutBytesSent!==void 0&&(t[25]=e.transportMetrics.oscOutBytesSent),e.transportMetrics.preschedulerBypassed!==void 0&&(t[22]=e.transportMetrics.preschedulerBypassed),e.transportMetrics.bypassNonBundle!==void 0&&(t[38]=e.transportMetrics.bypassNonBundle),e.transportMetrics.bypassImmediate!==void 0&&(t[39]=e.transportMetrics.bypassImmediate),e.transportMetrics.bypassNearFuture!==void 0&&(t[40]=e.transportMetrics.bypassNearFuture),e.transportMetrics.bypassLate!==void 0&&(t[41]=e.transportMetrics.bypassLate))}else this.#c&&t.set(this.#c);let s=this.#l;s.setInt32(46*4,e.driftOffsetMs??0,!0),s.setInt32(47*4,e.clockOffsetMs??0,!0);let r=e.audioContextState||"unknown",n={unknown:0,running:1,suspended:2,closed:3,interrupted:4};t[48]=n[r]??0,e.bufferPoolStats&&(t[49]=e.bufferPoolStats.used?.size??0,t[50]=e.bufferPoolStats.available??0,t[51]=e.bufferPoolStats.used?.count??0),t[52]=e.loadedSynthDefsCount??0;let o=this.#s;t[53]=o?.scheduler_slot_count??0,t[54]=e.preschedulerCapacity??0,t[55]=o?.IN_BUFFER_SIZE??0,t[56]=o?.OUT_BUFFER_SIZE??0,t[57]=o?.DEBUG_BUFFER_SIZE??0,t[58]=this.#a==="sab"?0:1,t[65]=e.playbackStats?1:0,e.playbackStats&&(t[59]=e.playbackStats.fallbackFramesEvents??0,t[60]=Math.round((e.playbackStats.fallbackFramesDuration??0)*1e3),t[61]=Math.round((e.playbackStats.averageLatency??0)*1e6),t[62]=Math.round((e.playbackStats.maximumLatency??0)*1e6),t[64]=Math.round((e.playbackStats.totalFramesDuration??0)*1e3)),t[63]=e.audioHealthPct??100,e.bufferPoolGrowthStats&&(t[66]=e.bufferPoolGrowthStats.totalCapacity??0,t[67]=e.bufferPoolGrowthStats.maxCapacity??0,t[68]=e.bufferPoolGrowthStats.growthCount??0,t[69]=e.bufferPoolGrowthStats.poolCount??0)}getMergedArray(){return this.#u}get bufferConstants(){return this.#s}get ringBufferBase(){return this.#e}get sharedBuffer(){return this.#r}};function Pe(i){return i/1e3+2208988800}function Pt(i,e){return i-e}function Ir(i,e){let t=i-e;return Math.round(t*1e6)}var ne=class{#r;#e;#s;#a;#o;#c;#i;#n;#u;#l=0;#y=0;#S=null;constructor(e={}){this.#r=e.mode||"sab",this.#e=e.audioContext,this.#s=e.workletPort||null}#_(e){this.#c.setFloat64(0,e,!0),this.#i&&Atomics.store(this.#i,0,Atomics.load(this.#i,0))}initSharedViews(e,t,s){this.#o=t,this.#a=s,this.#r==="sab"&&e&&s&&(this.#c=new DataView(e,t+s.NTP_START_TIME_START,8),this.#i=new Int32Array(e,t+s.DRIFT_OFFSET_START,1),this.#n=new Int32Array(e,t+s.GLOBAL_OFFSET_START,1))}updateAudioContext(e){this.#e=e}async initialize(){if(!this.#e)return;let e;for(;e=this.#e.getOutputTimestamp(),!(e.contextTime>0);)await new Promise(o=>setTimeout(o,50));e=this.#e.getOutputTimestamp();let t=performance.timeOrigin+e.performanceTime,s=Pe(t),r=e.contextTime,n=Pt(s,r);this.#r==="sab"&&this.#c?this.#_(n):this.#s&&this.#s.postMessage({type:"setNTPStartTime",ntpStartTime:n}),this.#u=n,await new Promise(o=>setTimeout(o,500)),this.updateDriftOffset()}updateDriftOffset(){if(!this.#e||this.#u===void 0)return;let e=this.#e.getOutputTimestamp(),t=performance.timeOrigin+e.performanceTime,r=Pe(t)-this.#u,n=Ir(r,e.contextTime);this.#l=Math.round(n/1e3),this.#r==="sab"&&this.#i?Atomics.store(this.#i,0,n):this.#s&&this.#s.postMessage({type:"setDriftOffset",driftOffsetUs:n})}resync(){if(!this.#e)return;let e=this.#e.getOutputTimestamp();if(!e||e.contextTime<=0)return;let t=performance.timeOrigin+e.performanceTime,s=Pe(t),r=Pt(s,e.contextTime);this.#r==="sab"&&this.#c?this.#_(r):this.#s&&this.#s.postMessage({type:"setNTPStartTime",ntpStartTime:r}),this.#u=r,this.updateDriftOffset()}startDriftTimer(){this.stopDriftTimer(),this.#S=setInterval(()=>{this.updateDriftOffset()},1e3)}stopDriftTimer(){this.#S&&(clearInterval(this.#S),this.#S=null)}getDriftOffset(){return this.#i?Math.round(Atomics.load(this.#i,0)/1e3):this.#l}getNTPStartTime(){return this.#c?this.#c.getFloat64(0,!0):this.#u??0}getClockOffset(){return this.#n?Atomics.load(this.#n,0):this.#y}setClockOffset(e){let t=Math.round(e*1e3);this.#y=t,this.#r==="sab"&&this.#n?Atomics.store(this.#n,0,t):this.#s&&this.#s.postMessage({type:"setClockOffset",clockOffsetMs:t})}reset(){this.stopDriftTimer(),this.#u=void 0,this.#l=0,this.#y=0,this.#c=null,this.#i=null,this.#n=null}};var oe=Object.freeze({SET_SESSION_BPM:"setSessionBpm",SET_SESSION_IS_PLAYING:"setSessionIsPlaying",SET_SESSION_BEAT_ORIGIN_NTP:"setSessionBeatOriginNtp"}),Dt=new ArrayBuffer(8),Lt=new Float64Array(Dt),kt=new BigInt64Array(Dt);function ae(i){return Lt[0]=i,kt[0]}function ce(i){return kt[0]=i,Lt[0]}var le=class{#r;#e;#s;#a;#o;#c=120;#i=0;#n=!1;#u=0;#l;constructor(e={}){this.#r=e.mode||"sab",this.#e=e.workletPort||null,this.#s=e.audioContext||null,this.#l=new ne({mode:this.#r,audioContext:e.audioContext,workletPort:this.#e})}initSharedViews(e,t,s){if(this.#r==="sab"){let r=t+s.SUPERCLOCK_STATE_START,n=s.SUPERCLOCK_STATE_SIZE;this.#a=new BigInt64Array(e,r,n/8),this.#o=new Int32Array(e,r,n/4)}this.#l.initSharedViews(e,t,s)}setWorkletPort(e){this.#e=e}updateAudioContext(e){this.#s=e,this.#l.updateAudioContext(e)}async initialize(){await this.#l.initialize()}resync(){this.#l.resync()}startDriftTimer(){this.#l.startDriftTimer()}stopDriftTimer(){this.#l.stopDriftTimer()}updateDriftOffset(){this.#l.updateDriftOffset()}getDriftOffset(){return this.#l.getDriftOffset()}getNTPStartTime(){return this.#l.getNTPStartTime()}getClockOffset(){return this.#l.getClockOffset()}setClockOffset(e){this.#l.setClockOffset(e)}reset(){this.#l.reset()}setBpm(e,t=0){(!Number.isFinite(e)||e<1)&&(e=1),this.#c=e,this.#a?Atomics.store(this.#a,0,ae(e)):this.#e&&this.#e.postMessage({type:oe.SET_SESSION_BPM,bpm:e,atNtpSeconds:t})}setIsPlaying(e,t=0){this.#n=!!e,this.#u=t,this.#a?(Atomics.store(this.#a,2,ae(t)),Atomics.store(this.#o,6,e?1:0)):this.#e&&this.#e.postMessage({type:oe.SET_SESSION_IS_PLAYING,isPlaying:this.#n,atNtpSeconds:t})}setLinkEnabled(e){e&&console.warn("[SuperClock] setLinkEnabled(true) ignored on web \u2014 Link is native-only. Use the native build + /link/visibility.")}requestBeatAtTime(e,t,s){let r=this.getBpm(),n=t-e*60/r;this.#i=n,this.#a?Atomics.store(this.#a,1,ae(n)):this.#e&&this.#e.postMessage({type:oe.SET_SESSION_BEAT_ORIGIN_NTP,beatOriginNtp:n})}forceBeatAtTime(e,t,s){this.requestBeatAtTime(e,t,s)}getBpm(){return this.#a?ce(Atomics.load(this.#a,0)):this.#c}isPlaying(){return this.#o?Atomics.load(this.#o,6)!==0:this.#n}getBeatOriginNtp(){return this.#a?ce(Atomics.load(this.#a,1)):this.#i}getIsPlayingAtNtp(){return this.#a?ce(Atomics.load(this.#a,2)):this.#u}isLinkEnabled(){return!1}numPeers(){return 0}now(){return this.#s?this.nowAt(this.#s.currentTime):0}nowAt(e){return e+this.getNTPStartTime()+this.getDriftOffset()/1e3+this.getClockOffset()/1e3}wallNow(){return(performance.timeOrigin+performance.now())/1e3+2208988800}beatAtTime(e,t){return(e-this.getBeatOriginNtp())*this.getBpm()/60}phaseAtTime(e,t){let r=this.beatAtTime(e,t)%t;return r<0&&(r+=t),r}timeAtBeat(e,t){return this.getBeatOriginNtp()+e*60/this.getBpm()}};var ue=class i{#r;#e=0;#s=0;#a=100;static#o=1e3;constructor({audioContext:e}){this.#r=e}update(){if(this.#r.state!=="running")return this.#a;let e=performance.now(),t=this.#r.currentTime;if(this.#s===0)return this.#s=e,this.#e=t,this.#a;let s=e-this.#s;if(s<i.#o)return this.#a;let r=s/1e3,n=t-this.#e;return this.#a=Math.min(100,Math.round(n/r*100)),this.#s=e,this.#e=t,this.#a}getHealth(){return{healthPct:this.#a}}reset(){this.#e=0,this.#s=0,this.#a=100}};var fe=class i{#r;#e;#s;constructor(e={}){this.#r=e.sharedBuffer||null,this.#e=e.bufferConstants||null,this.#s=e.ringBufferBase||0}update(e,t,s){this.#r=e,this.#s=t,this.#e=s}isAvailable(){return!!(this.#r&&this.#e)}static#a=0;static#o=1;static#c=2;static#i=4;static#n=5;static#u=8;start(){if(!this.isAvailable())throw new Error("AudioCapture not initialized");let e=this.#e,t=this.#s+e.SHM_AUDIO_START,s=new Uint32Array(this.#r,t,i.#u);Atomics.store(s,i.#a,0),Atomics.store(s,i.#i,0),Atomics.store(s,i.#n,0),Atomics.store(s,i.#a,1)}stop(){if(!this.isAvailable())throw new Error("AudioCapture not initialized");let e=this.#e,t=this.#s+e.SHM_AUDIO_START,s=new Uint32Array(this.#r,t,1);return Atomics.store(s,i.#a,0),this.read()}read(){if(!this.isAvailable())throw new Error("AudioCapture not initialized");let e=this.#e,t=this.#s+e.SHM_AUDIO_START,s=new Uint32Array(this.#r,t,i.#u),r=s[i.#o],n=s[i.#c],o=Atomics.load(s,i.#i),a=Atomics.load(s,i.#n);if(a!==0)throw new Error(`AudioCapture: write_position too large (high=${a})`);let c=o,u=t+e.SHM_AUDIO_HEADER_SIZE,l=new Float32Array(this.#r,u,c*n),f=new Float32Array(c),h=n>1?new Float32Array(c):null;for(let y=0;y<c;y++)f[y]=l[y*n],h&&(h[y]=l[y*n+1]);return{sampleRate:r,channels:n,frames:c,left:f,right:h}}isEnabled(){if(!this.isAvailable())return!1;let e=this.#e,t=this.#s+e.SHM_AUDIO_START,s=new Uint32Array(this.#r,t,1);return Atomics.load(s,i.#a)===1}getFrameCount(){if(!this.isAvailable())return 0;let e=this.#e,t=this.#s+e.SHM_AUDIO_START,s=new Uint32Array(this.#r,t,i.#u);return Atomics.load(s,i.#i)}getMaxDuration(){if(!this.#e)return 0;let e=this.#e;return e.SHM_AUDIO_FRAMES/(e.SHM_AUDIO_SAMPLE_RATE||48e3)}};function Ht(i,e,t){let s=t,r=new Uint32Array(i,e,3),n=r[0],o=r[1],a=r[2],c=e+s.NODE_TREE_HEADER_SIZE,u=s.NODE_TREE_MIRROR_MAX_NODES,l=s.NODE_TREE_ENTRY_SIZE,f=s.NODE_TREE_DEF_NAME_SIZE,h=new DataView(i,c,u*l),y=new TextDecoder("utf-8"),p=[],d=0;for(let m=0;m<u&&d<n;m++){let E=m*l,g=h.getInt32(E,!0);if(g===-1)continue;d++;let w=c+E+24,C=new Uint8Array(i,w,f),_=new Uint8Array(f);_.set(C);let Se=_.indexOf(0);Se===-1&&(Se=f);let ns=y.decode(_.subarray(0,Se)),os=c+E+56,Ee=new Uint8Array(i,os,16),Je=!1;for(let T=0;T<16;T++)if(Ee[T]!==0){Je=!0;break}let X=null;if(Je){X=new Uint8Array(16);for(let T=0;T<8;T++)X[T]=Ee[7-T];for(let T=0;T<8;T++)X[8+T]=Ee[15-T]}p.push({id:g,parentId:h.getInt32(E+4,!0),isGroup:h.getInt32(E+8,!0)===1,prevId:h.getInt32(E+12,!0),nextId:h.getInt32(E+16,!0),headId:h.getInt32(E+20,!0),defName:ns,uuid:X})}return{nodeCount:n,version:o,droppedCount:a,nodes:p}}var Ye=new Uint8Array(2097152),Gt=new DataView(Ye.buffer),S=Ye,A=Gt,De=new Map,Ur=1e3,Pr=new TextDecoder,Dr=new TextEncoder,Le=[null,0],$e=2208988800,pe=4294967296,We=new Uint8Array([35,98,117,110,100,108,101,0]),zt=44,xe=105,Ne=102,Fe=115,ve=98,He=84,Ge=70,Yt=104,$t=100,Wt=116,Vt=117,qt=91,Xt=93;function he(i,e,t=0){let s=i.length+4;s+=5;for(let r=t;r<e.length;r++)s+=Kt(e[r]);return s}function Kt(i){if(i instanceof Uint8Array)return 5+i.length+3;if(i instanceof ArrayBuffer)return 5+i.byteLength+3;if(typeof i=="string")return 1+i.length*3+4;if(Array.isArray(i)){let e=2;for(let t=0;t<i.length;t++)e+=Kt(i[t]);return e}if(i&&i.type==="string")return 1+i.value.length*3+4;if(i&&i.type==="blob"){let e=i.value;return 5+(e instanceof Uint8Array?e.length:e.byteLength)+3}return i&&i.type==="uuid"?17:9}function Zt(i){let e=16;for(let t of i)e+=4,Array.isArray(t)?e+=he(t[0],t,1):t.packets!==void 0?e+=Zt(t.packets):e+=he(t.address,t.args||[]);return e}function Ve(i){if(i<=2097152){S=Ye,A=Gt;return}S=new Uint8Array(i),A=new DataView(S.buffer)}function jt(i,e=[]){let t=he(i,e);Ve(t);let s=0;s=qe(i,s),s=Xe(e,s);for(let r=0;r<e.length;r++)s=W(e[r],s);return S.subarray(0,s)}function Qt(i,e){let t=Zt(e);Ve(t);let s=0;S.set(We,s),s+=8,s=me(i,s);for(let r=0;r<e.length;r++){let n=e[r],o=s;s+=4;let a=s;Array.isArray(n)?s=de(n[0],n,s,1):n.packets!==void 0?s=es(n.timeTag,n.packets,s):s=de(n.address,n.args||[],s);let c=s-a;A.setUint32(o,c,!1)}return S.subarray(0,s)}function Jt(i,e,t=[]){let s=20+he(e,t);Ve(s);let r=0;S.set(We,r),r+=8,r=me(i,r);let n=r;r+=4;let o=r;r=qe(e,r),r=Xe(t,r);for(let a=0;a<t.length;a++)r=W(t[a],r);return A.setUint32(n,r-o,!1),S.subarray(0,r)}function de(i,e,t,s=0){t=qe(i,t),t=Xe(e,t,s);for(let r=s;r<e.length;r++)t=W(e[r],t);return t}function es(i,e,t){S.set(We,t),t+=8,t=me(i,t);for(let s=0;s<e.length;s++){let r=e[s],n=t;t+=4;let o=t;Array.isArray(r)?t=de(r[0],r,t,1):r.packets!==void 0?t=es(r.timeTag,r.packets,t):t=de(r.address,r.args||[],t),A.setUint32(n,t-o,!1)}return t}function qe(i,e){let t=De.get(i);if(t)return S.set(t,e),e+t.length;let s=e;if(e=ze(i,e),De.size<Ur){let r=S.slice(s,e);De.set(i,r)}return e}function ze(i,e){let t=!1;for(let s=0;s<i.length;s++)if(i.charCodeAt(s)>=128){t=!0;break}if(t){let s=Dr.encodeInto(i,S.subarray(e));e+=s.written}else for(let s=0;s<i.length;s++)S[e++]=i.charCodeAt(s);for(S[e++]=0;e&3;)S[e++]=0;return e}function Xe(i,e,t=0){S[e++]=zt;for(let s=t;s<i.length;s++)e=ts(i[s],e,s);for(S[e++]=0;e&3;)S[e++]=0;return e}function ts(i,e,t){let s=typeof i;if(s==="number")S[e++]=Number.isInteger(i)?xe:Ne;else if(s==="string")S[e++]=Fe;else if(s==="boolean")S[e++]=i?He:Ge;else if(i instanceof Uint8Array||i instanceof ArrayBuffer)S[e++]=ve;else if(Array.isArray(i)){S[e++]=qt;for(let r=0;r<i.length;r++)e=ts(i[r],e,t);S[e++]=Xt}else if(i&&i.type==="int")S[e++]=xe;else if(i&&i.type==="float")S[e++]=Ne;else if(i&&i.type==="string")S[e++]=Fe;else if(i&&i.type==="blob")S[e++]=ve;else if(i&&i.type==="bool")S[e++]=i.value?He:Ge;else if(i&&i.type==="int64")S[e++]=Yt;else if(i&&i.type==="double")S[e++]=$t;else if(i&&i.type==="timetag")S[e++]=Wt;else if(i&&i.type==="uuid")S[e++]=Vt;else throw i==null?new Error(`OSC argument at index ${t} is ${i}`):new Error(`Unknown OSC argument type at index ${t}: ${s}`);return e}function W(i,e){let t=typeof i;if(t==="number")return Number.isInteger(i)?(A.setInt32(e,i,!1),e+4):(A.setFloat32(e,i,!1),e+4);if(t==="string")return ze(i,e);if(t==="boolean")return e;if(i instanceof Uint8Array){let s=i.length;for(A.setUint32(e,s,!1),e+=4,S.set(i,e),e+=s;e&3;)S[e++]=0;return e}if(i instanceof ArrayBuffer)return W(new Uint8Array(i),e);if(Array.isArray(i)){for(let s=0;s<i.length;s++)e=W(i[s],e);return e}if(i&&i.type==="int")return A.setInt32(e,i.value,!1),e+4;if(i&&i.type==="float")return A.setFloat32(e,i.value,!1),e+4;if(i&&i.type==="string")return ze(i.value,e);if(i&&i.type==="blob"){let s=i.value instanceof Uint8Array?i.value:new Uint8Array(i.value),r=s.length;for(A.setUint32(e,r,!1),e+=4,S.set(s,e),e+=r;e&3;)S[e++]=0;return e}return i&&i.type==="bool"?e:i&&i.type==="int64"?(A.setBigInt64(e,BigInt(i.value),!1),e+8):i&&i.type==="double"?(A.setFloat64(e,i.value,!1),e+8):i&&i.type==="timetag"?me(i.value,e):i&&i.type==="uuid"?(S.set(i.value,e),e+16):e}function me(i,e){if(i===1||i===null||i===void 0)return A.setUint32(e,0,!1),A.setUint32(e+4,1,!1),e+8;if(Array.isArray(i)){if(i.length!==2)throw new Error(`TimeTag array must have exactly 2 elements [seconds, fraction], got ${i.length}`);return A.setUint32(e,i[0]>>>0,!1),A.setUint32(e+4,i[1]>>>0,!1),e+8}if(typeof i!="number")throw new TypeError(`TimeTag must be a number, array, null, or undefined, got ${typeof i}`);i>1&&i<$e&&console.warn(`TimeTag ${i} looks like a Unix timestamp (< NTP_EPOCH_OFFSET). Did you mean to add NTP_EPOCH_OFFSET (2208988800)?`);let t=i>>>0,s=(i-Math.floor(i))*pe>>>0;return A.setUint32(e,t,!1),A.setUint32(e+4,s,!1),e+8}function V(i){return i instanceof Uint8Array||(i=new Uint8Array(i)),i[0]===35&&i[1]===98?kr(i):Lr(i)}function Lr(i){i instanceof Uint8Array||(i=new Uint8Array(i));let e=new DataView(i.buffer,i.byteOffset,i.byteLength),t=0,[s,r]=ke(i,t);if(t=r,t>=i.length||i[t]!==zt)return[s];let[n,o]=ke(i,t);t=o;let a=[s],c=a,u=[];for(let l=1;l<n.length;l++)switch(n.charCodeAt(l)){case xe:c.push(e.getInt32(t,!1)),t+=4;break;case Ne:c.push(e.getFloat32(t,!1)),t+=4;break;case Fe:let[h,y]=ke(i,t);c.push(h),t=y;break;case ve:let p=e.getUint32(t,!1);t+=4,c.push(i.slice(t,t+p)),t+=p,t=t+3&-4;break;case Yt:c.push(e.getBigInt64(t,!1)),t+=8;break;case $t:c.push(e.getFloat64(t,!1)),t+=8;break;case He:c.push(!0);break;case Ge:c.push(!1);break;case Wt:let d=e.getUint32(t,!1),m=e.getUint32(t+4,!1);c.push(d+m/pe),t+=8;break;case Vt:c.push({type:"uuid",value:i.slice(t,t+16)}),t+=16;break;case qt:{let E=[];c.push(E),u.push(c),c=E;break}case Xt:c=u.pop()||a;break}return a}function kr(i){i instanceof Uint8Array||(i=new Uint8Array(i));let e=new DataView(i.buffer,i.byteOffset,i.byteLength),t=8,s=e.getUint32(t,!1),r=e.getUint32(t+4,!1),n=s+r/pe;t+=8;let o=[];for(;t<i.length;){let a=e.getUint32(t,!1);if(t+=4,a>0&&t+a<=i.length){let c=i.subarray(t,t+a);o.push(V(c))}t+=a}return{timeTag:n,packets:o}}function ke(i,e){let t=e;for(;t<i.length&&i[t]!==0;)t++;let s=Pr.decode(i.subarray(e,t));return t++,t=t+3&-4,Le[0]=s,Le[1]=t,Le}function ye(i){return i.slice()}function xr(i){return!i||i.length<8?!1:i[0]===35&&i[1]===98}function Ke(i){if(!xr(i))return null;let e=new DataView(i.buffer,i.byteOffset,i.byteLength),t=e.getUint32(8,!1),s=e.getUint32(12,!1);return t+s/pe}var U={wasmHeapSize:8388608,ringBufferReserved:3145728,rtPoolSize:33554432,bufferPoolSize:4194304,maxBufferPoolSize:805306368,get rtPoolOffset(){return this.wasmHeapSize+this.ringBufferReserved},get bufferPoolOffset(){return this.rtPoolOffset+this.rtPoolSize},get totalMemory(){return this.bufferPoolOffset+this.bufferPoolSize},get maxTotalMemory(){return this.bufferPoolOffset+this.maxBufferPoolSize},get totalPages(){return Math.ceil(this.totalMemory/65536)}};var Ze={numBuffers:1024,maxNodes:8192,maxGraphDefs:1024,maxWireBufs:64,numAudioBusChannels:128,numInputBusChannels:2,numOutputBusChannels:2,numControlBusChannels:4096,bufLength:128,realTimeMemorySize:8192,numRGens:64,realTime:!1,memoryLocking:!1,loadGraphDefs:0,preferredSampleRate:0,verbosity:0};var Fr=1e4,vr=5e3,Hr=150,Gr=new Set(["/b_alloc","/b_allocRead","/b_allocReadChannel","/b_allocFile"]),b=[];for(let i=0;i<256;i++)b[i]=i.toString(16).padStart(2,"0");function zr(i){return b[i[0]]+b[i[1]]+b[i[2]]+b[i[3]]+"-"+b[i[4]]+b[i[5]]+"-"+b[i[6]]+b[i[7]]+"-"+b[i[8]]+b[i[9]]+"-"+b[i[10]]+b[i[11]]+b[i[12]]+b[i[13]]+b[i[14]]+b[i[15]]}function rs(i){return"\u2026"+b[i[13]]+b[i[14]]+b[i[15]]}function ss(i,e){if(i&&i.type==="uuid"&&i.value)return rs(i.value);if(i instanceof Uint8Array||i instanceof ArrayBuffer)return`<${i.byteLength||i.length} bytes>`;let t=JSON.stringify(i);return e&&t.length>e?t.slice(0,e)+"...":t}function q(i){return String(i).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function is(i,e,t){if(i&&i.type==="uuid"&&i.value)return`<span class="supersonic-scsynth-string" title="${zr(i.value)}">${rs(i.value)}</span>`;let s=i,r=null;if(typeof i=="object"&&i!==null&&i.value!==void 0&&(s=i.value,r=i.type),r==="b"||s instanceof Uint8Array||s instanceof ArrayBuffer)return`<span class="supersonic-scsynth-binary"><${s.byteLength??s.length??"?"} bytes></span>`;let n=r==="f"||r===null&&typeof s=="number"&&!Number.isInteger(s),o=r==="i"||r===null&&Number.isInteger(s),c=e==="/s_new"&&t>=4&&(t-4)%2===0&&typeof s=="string";return n?`<span class="supersonic-scsynth-float">${parseFloat(s.toFixed(3))}</span>`:o?`<span class="supersonic-scsynth-int">${s}</span>`:c?`<span class="supersonic-scsynth-param">${q(s)}</span>`:typeof s=="string"?`<span class="supersonic-scsynth-string">${q(JSON.stringify(s))}</span>`:`<span class="supersonic-scsynth-string">${q(s)}</span>`}function je(i,e,t,s,r){let n=i[0],o=i.slice(1),a=s&&t?(t-s).toFixed(2):"",c=`<span class="supersonic-scsynth-seq">[${e}]</span>`;if(a&&(c+=` <span class="supersonic-scsynth-time">${a}</span>`),r!==void 0&&(c+=` <span class="supersonic-scsynth-source">ch${r}</span>`),c+=` <span class="supersonic-scsynth-address">${q(n)}</span>`,o.length>0){let u=o.map((l,f)=>is(l,n,f)).join(", ");c+=" "+u}return c}function Yr(i,e,t,s,r){if(!i.packets)return je(i,e,t,s,r);if(i.packets.length===1)return je(i.packets[0],e,t,s,r);let n=s&&t?(t-s).toFixed(2):"",o=`<span class="supersonic-scsynth-seq">[${e}]</span>`;n&&(o+=` <span class="supersonic-scsynth-time">${n}</span>`),r!==void 0&&(o+=` <span class="supersonic-scsynth-source">ch${r}</span>`),o+=` <span class="supersonic-scsynth-bundle">Bundle (${i.packets.length})</span>`;for(let a of i.packets){let c=a[0],u=a.slice(1);o+=`<br><span class="supersonic-scsynth-address">${q(c)}</span>`,u.length>0&&(o+=" "+u.map((l,f)=>is(l,c,f)).join(", "))}return o}var Qe=class i{static osc={encodeMessage:(e,t)=>ye(jt(e,t)),encodeBundle:(e,t)=>ye(Qt(e,t)),decode:e=>V(e),encodeSingleBundle:(e,t,s)=>ye(Jt(e,t,s)),readTimetag:e=>be(e),ntpNow:()=>M(),NTP_EPOCH_OFFSET:$e};static#r=null;static getMetricsSchema(){return this.#r??={metrics:{scsynthProcessCount:{offset:0,type:"counter",unit:"count",description:"Audio process() calls"},scsynthMessagesProcessed:{offset:1,type:"counter",unit:"count",description:"OSC messages processed by scsynth"},scsynthMessagesDropped:{offset:2,type:"counter",unit:"count",description:"Messages dropped (ring buffer full)"},scsynthSchedulerDepth:{offset:3,type:"gauge",unit:"count",description:"Current scheduler queue depth"},scsynthSchedulerPeakDepth:{offset:4,type:"gauge",unit:"count",description:"Peak scheduler queue depth (high water mark)"},scsynthSchedulerDropped:{offset:5,type:"counter",unit:"count",description:"Scheduled events dropped"},scsynthSequenceGaps:{offset:6,type:"counter",unit:"count",description:"Messages lost in transit from JS to scsynth"},scsynthWasmErrors:{offset:7,type:"counter",unit:"count",description:"WASM execution errors in audio worklet"},scsynthSchedulerLates:{offset:8,type:"counter",unit:"count",description:"Bundles executed after their scheduled time"},preschedulerPending:{offset:9,type:"gauge",unit:"count",description:"Events waiting to be scheduled"},preschedulerPendingPeak:{offset:10,type:"gauge",unit:"count",description:"Peak pending events"},preschedulerBundlesScheduled:{offset:11,type:"counter",unit:"count",description:"Bundles scheduled"},preschedulerDispatched:{offset:12,type:"counter",unit:"count",description:"Events sent to worklet"},preschedulerEventsCancelled:{offset:13,type:"counter",unit:"count",description:"Events cancelled"},preschedulerMinHeadroomMs:{offset:14,type:"gauge",unit:"ms",description:"Smallest time gap between JS prescheduler dispatch and scsynth scheduler execution"},preschedulerLates:{offset:15,type:"counter",unit:"count",description:"Bundles dispatched after their scheduled execution time"},preschedulerRetriesSucceeded:{offset:16,type:"counter",unit:"count",description:"Retries that succeeded"},preschedulerRetriesFailed:{offset:17,type:"counter",unit:"count",description:"Retries that failed"},preschedulerRetryQueueSize:{offset:18,type:"gauge",unit:"count",description:"Current retry queue size"},preschedulerRetryQueuePeak:{offset:19,type:"gauge",unit:"count",description:"Peak retry queue size"},preschedulerMessagesRetried:{offset:20,type:"counter",unit:"count",description:"Messages that needed retry"},preschedulerTotalDispatches:{offset:21,type:"counter",unit:"count",description:"Total dispatch attempts"},preschedulerBypassed:{offset:22,type:"counter",unit:"count",description:"Messages sent directly from JS to scsynth, bypassing prescheduler (aggregate)"},preschedulerMaxLateMs:{offset:23,type:"gauge",unit:"ms",description:"Maximum lateness at prescheduler (ms)"},oscOutMessagesSent:{offset:24,type:"counter",unit:"count",description:"OSC messages sent from JS to scsynth"},oscOutBytesSent:{offset:25,type:"counter",unit:"bytes",description:"Total bytes sent from JS to scsynth"},oscInMessagesReceived:{offset:26,type:"counter",unit:"count",description:"OSC replies received from scsynth to JS"},oscInBytesReceived:{offset:27,type:"counter",unit:"bytes",description:"Total bytes received from scsynth to JS"},oscInMessagesDropped:{offset:28,type:"counter",unit:"count",description:"Replies lost in transit from scsynth to JS"},oscInCorrupted:{offset:29,type:"counter",unit:"count",description:"Corrupted messages detected from scsynth to JS"},debugMessagesReceived:{offset:30,type:"counter",unit:"count",description:"Debug messages from scsynth"},debugBytesReceived:{offset:31,type:"counter",unit:"bytes",description:"Debug bytes received"},inBufferUsedBytes:{offset:32,type:"gauge",unit:"bytes",description:"Bytes used in IN ring buffer"},outBufferUsedBytes:{offset:33,type:"gauge",unit:"bytes",description:"Bytes used in OUT ring buffer"},debugBufferUsedBytes:{offset:34,type:"gauge",unit:"bytes",description:"Bytes used in DEBUG ring buffer"},inBufferPeakBytes:{offset:35,type:"gauge",unit:"bytes",description:"Peak bytes used in IN ring buffer"},outBufferPeakBytes:{offset:36,type:"gauge",unit:"bytes",description:"Peak bytes used in OUT ring buffer"},debugBufferPeakBytes:{offset:37,type:"gauge",unit:"bytes",description:"Peak bytes used in DEBUG ring buffer"},bypassNonBundle:{offset:38,type:"counter",unit:"count",description:"Plain OSC messages (not bundles) that bypassed prescheduler"},bypassImmediate:{offset:39,type:"counter",unit:"count",description:"Bundles with timetag 0 or 1 that bypassed prescheduler"},bypassNearFuture:{offset:40,type:"counter",unit:"count",description:"Bundles within bypass lookahead threshold that bypassed prescheduler"},bypassLate:{offset:41,type:"counter",unit:"count",description:"Timestamped OSC bundles arriving late into SuperSonic bypassing prescheduler"},scsynthSchedulerMaxLateMs:{offset:42,type:"gauge",unit:"ms",description:"Maximum lateness observed in scsynth scheduler (ms)"},scsynthSchedulerLastLateMs:{offset:43,type:"gauge",unit:"ms",description:"Most recent late magnitude in scsynth scheduler (ms)"},scsynthSchedulerLastLateTick:{offset:44,type:"gauge",unit:"count",description:"Process count when last scsynth late occurred"},ringBufferDirectWriteFails:{offset:45,type:"counter",unit:"count",description:"SAB mode only: optimistic direct writes attempted but failed due to ring buffer lock not being available (delivered via prescheduler instead)"},driftOffsetMs:{offset:46,type:"gauge",unit:"ms",signed:!0,description:"Clock drift between AudioContext and wall clock"},clockOffsetMs:{offset:47,type:"gauge",unit:"ms",signed:!0,description:"Clock offset for multi-system sync"},audioContextState:{offset:48,type:"enum",values:["unknown","running","suspended","closed","interrupted"],description:"AudioContext state"},bufferPoolUsedBytes:{offset:49,type:"gauge",unit:"bytes",description:"Buffer pool bytes used"},bufferPoolAvailableBytes:{offset:50,type:"gauge",unit:"bytes",description:"Buffer pool bytes available"},bufferPoolAllocations:{offset:51,type:"counter",unit:"count",description:"Total buffer allocations"},loadedSynthDefs:{offset:52,type:"gauge",unit:"count",description:"Number of loaded synthdefs"},scsynthSchedulerCapacity:{offset:53,type:"constant",unit:"count",description:"Maximum scheduler queue size"},preschedulerCapacity:{offset:54,type:"constant",unit:"count",description:"Maximum pending events in prescheduler"},inBufferCapacity:{offset:55,type:"constant",unit:"bytes",description:"IN ring buffer capacity"},outBufferCapacity:{offset:56,type:"constant",unit:"bytes",description:"OUT ring buffer capacity"},debugBufferCapacity:{offset:57,type:"constant",unit:"bytes",description:"DEBUG ring buffer capacity"},mode:{offset:58,type:"enum",values:["sab","postMessage"],description:"Transport mode"},glitchCount:{offset:59,type:"counter",unit:"count",description:"Chrome only: audio underrun/glitch events"},glitchDurationMs:{offset:60,type:"gauge",unit:"ms",description:"Chrome only: total silence from audio underruns"},averageLatencyUs:{offset:61,type:"gauge",unit:"us",description:"Chrome only: average audio output latency"},maxLatencyUs:{offset:62,type:"gauge",unit:"us",description:"Chrome only: maximum audio output latency"},audioHealthPct:{offset:63,type:"gauge",unit:"%",description:"Cross-browser: fraction of expected audio frames delivered (100% = no issues)"},totalFramesDurationMs:{offset:64,type:"counter",unit:"ms",description:"Chrome only: total audio rendered duration"},hasPlaybackStats:{offset:65,type:"gauge",unit:"bool",description:"1 if Chrome playbackStats API is available, 0 otherwise"},bufferPoolTotalCapacity:{offset:66,type:"gauge",unit:"bytes",description:"Buffer pool committed capacity (grows on demand)"},bufferPoolMaxCapacity:{offset:67,type:"gauge",unit:"bytes",description:"Buffer pool hard ceiling"},bufferPoolGrowthCount:{offset:68,type:"counter",unit:"count",description:"Number of buffer pool growth events"},bufferPoolPoolCount:{offset:69,type:"gauge",unit:"count",description:"Number of buffer pool segments"}},layout:{panels:[{title:"OSC Out",rows:[{label:"sent",cells:[{key:"oscOutMessagesSent"}]},{label:"bytes",cells:[{key:"oscOutBytesSent",kind:"muted",format:"bytes"}]},{label:"bypass",cells:[{key:"preschedulerBypassed",kind:"green"}]},{label:"lost",cells:[{key:"scsynthSequenceGaps",kind:"error"}]}]},{title:"Bypass",rows:[{label:"msg",cells:[{key:"bypassNonBundle",kind:"muted"}]},{label:"imm",cells:[{key:"bypassImmediate",kind:"muted"}]},{label:"near",cells:[{key:"bypassNearFuture",kind:"muted"}]},{label:"late",cells:[{key:"bypassLate",kind:"muted"}]}]},{title:"OSC In",rows:[{label:"received",cells:[{key:"oscInMessagesReceived"}]},{label:"bytes",cells:[{key:"oscInBytesReceived",kind:"muted",format:"bytes"}]},{label:"dropped",cells:[{key:"oscInMessagesDropped",kind:"error"}]},{label:"corrupted",cells:[{key:"oscInCorrupted",kind:"error"}]}]},{title:"Presched Flow",rows:[{label:"pending",tooltip:"Current pending events | peak pending events",cells:[{key:"preschedulerPending"},{sep:" | "},{key:"preschedulerPendingPeak",kind:"muted"}]},{label:"scheduled",cells:[{key:"preschedulerBundlesScheduled"}]},{label:"dispatched",cells:[{key:"preschedulerDispatched",kind:"dim"}]},{label:"min slack",cells:[{key:"preschedulerMinHeadroomMs",kind:"dim",format:"headroom"},{text:" ms",kind:"muted"}]}]},{title:"Presched Health",rows:[{label:"lates",tooltip:"Bundles dispatched after their scheduled time (count and max lateness in ms)",cells:[{key:"preschedulerLates",kind:"error"},{sep:" ("},{key:"preschedulerMaxLateMs",kind:"dim"},{text:" ms max)",kind:"muted"}]},{label:"cancelled",cells:[{key:"preschedulerEventsCancelled",kind:"error"}]},{label:"retried",tooltip:"Messages retried | succeeded | failed",cells:[{key:"preschedulerMessagesRetried",kind:"dim"},{sep:" | "},{key:"preschedulerRetriesSucceeded",kind:"green"},{sep:" | "},{key:"preschedulerRetriesFailed",kind:"error"}]},{label:"retry queue",tooltip:"Current retry queue size | peak size",cells:[{key:"preschedulerRetryQueueSize"},{sep:" | "},{key:"preschedulerRetryQueuePeak",kind:"muted"}]}]},{title:"scsynth Scheduler",rows:[{label:"queue",tooltip:"Current scheduler queue depth | peak depth",cells:[{key:"scsynthSchedulerDepth"},{sep:" | "},{key:"scsynthSchedulerPeakDepth",kind:"muted"}]},{label:"dropped",cells:[{key:"scsynthSchedulerDropped",kind:"error"}]},{label:"lates",cells:[{key:"scsynthSchedulerLates",kind:"error"}]},{label:"max | last",tooltip:"Maximum lateness observed | most recent late magnitude (ms)",cells:[{key:"scsynthSchedulerMaxLateMs",kind:"error"},{sep:" | "},{key:"scsynthSchedulerLastLateMs",kind:"dim"},{text:" ms",kind:"muted"}]}]},{title:"scsynth",rows:[{label:"ticks",tooltip:"Audio process() callback count and OSC messages processed",cells:[{key:"scsynthProcessCount",kind:"dim"},{sep:" | "},{key:"scsynthMessagesProcessed",kind:"muted"},{text:" msgs",kind:"muted"}]},{label:"dropped",cells:[{key:"scsynthMessagesDropped",kind:"error"}]},{label:"drift",cells:[{key:"driftOffsetMs",format:"signed"},{text:" ms",kind:"muted"}]},{label:"debug",tooltip:"Debug messages from scsynth (count and bytes)",cells:[{key:"debugMessagesReceived",kind:"muted"},{text:" ("},{key:"debugBytesReceived",kind:"muted",format:"bytes"},{text:")"}]}]},{title:"Ring Buffer Level",class:"wide",rows:[{type:"bar",label:"in",usedKey:"inBufferUsedBytes",peakKey:"inBufferPeakBytes",capacityKey:"inBufferCapacity",color:"blue"},{type:"bar",label:"out",usedKey:"outBufferUsedBytes",peakKey:"outBufferPeakBytes",capacityKey:"outBufferCapacity",color:"green"},{type:"bar",label:"dbg",usedKey:"debugBufferUsedBytes",peakKey:"debugBufferPeakBytes",capacityKey:"debugBufferCapacity",color:"purple"},{label:"direct write fails",cells:[{key:"ringBufferDirectWriteFails",kind:"error"}]}]},{title:"Buffers & SynthDefs",rows:[{label:"buf used",cells:[{key:"bufferPoolUsedBytes",format:"bytes"}]},{label:"buf free",cells:[{key:"bufferPoolAvailableBytes",kind:"green",format:"bytes"}]},{label:"buf allocs",cells:[{key:"bufferPoolAllocations",kind:"dim"}]},{label:"synthdefs",cells:[{key:"loadedSynthDefs"}]}]},{title:"AudioWorklet",rows:[{label:"health",tooltip:"AudioContext state and audio health percentage (fraction of expected frames delivered)",cells:[{key:"audioContextState",kind:"green",format:"enum"},{sep:" | "},{key:"audioHealthPct",kind:"green",format:"percent"},{text:" %",kind:"muted"}]},{label:"glitches",tooltip:"Chrome only: audio underrun/glitch events and total silence duration",cells:[{key:"glitchCount",kind:"error",format:"chromeOnly"},{sep:" ("},{key:"glitchDurationMs",kind:"error",format:"chromeOnly"},{text:" ms)",kind:"muted"}]},{label:"latency",tooltip:"Chrome only: avg | max audio output latency in ms",cells:[{key:"averageLatencyUs",kind:"dim",format:"chromeLatencyUs"},{sep:" | "},{key:"maxLatencyUs",kind:"dim",format:"chromeLatencyUs"},{text:" ms",kind:"muted"}]},{label:"WASM errors",cells:[{key:"scsynthWasmErrors",kind:"error"}]}]}]},sentinels:{HEADROOM_UNSET:4294967295}}}static getTreeSchema(){return{nodeCount:{type:"number",description:"Total nodes in tree"},version:{type:"number",description:"Increments on any tree change, useful for detecting updates"},droppedCount:{type:"number",description:"Nodes that exceeded mirror capacity (tree may be incomplete)"},root:{type:"object",description:"Root node of the tree (always a group with id 0)",schema:{id:{type:"number",description:"Unique node ID"},type:{type:"string",values:["group","synth"],description:"Node type"},defName:{type:"string",description:"Synthdef name (synths only, empty for groups)"},children:{type:"array",description:"Child nodes (recursive)",itemSchema:"(self)"}}}}}static getRawTreeSchema(){return{nodeCount:{type:"number",description:"Total nodes in tree"},version:{type:"number",description:"Increments on any tree change, useful for detecting updates"},droppedCount:{type:"number",description:"Nodes that exceeded mirror capacity (tree may be incomplete)"},nodes:{type:"array",description:"Flat array of all nodes with internal linkage pointers",itemSchema:{id:{type:"number",description:"Unique node ID"},parentId:{type:"number",description:"Parent node ID (-1 for root)"},isGroup:{type:"boolean",description:"True if group, false if synth"},prevId:{type:"number",description:"Previous sibling node ID (-1 if none)"},nextId:{type:"number",description:"Next sibling node ID (-1 if none)"},headId:{type:"number",description:"First child node ID (groups only, -1 if empty)"},defName:{type:"string",description:"Synthdef name (synths only, empty for groups)"}}}}}#e;#s;#a=null;#o;#c;#i;#n;#u;#l;#y;#S;#_;#d;#E;#p;#g;#T;#t;#f;#h;#m;#b;#A;#w;#C=1e3;#R=null;#B=null;#I=0;#O=[];#P=null;#D=Promise.resolve();#U=null;#x(e){let t=[["numBuffers",1,65535],["maxNodes",1],["maxGraphDefs",1],["maxWireBufs",1],["numAudioBusChannels",1],["numInputBusChannels",0],["numOutputBusChannels",1,128],["numControlBusChannels",1],["realTimeMemorySize",1],["numRGens",1],["preferredSampleRate",0,384e3],["verbosity",0,4]];for(let[s,r,n]of t){let o=e[s];if(typeof o!="number"||!Number.isFinite(o))throw new Error(`scsynthOptions.${s} must be a finite number, got: ${o}`);if(o<r)throw new Error(`scsynthOptions.${s} must be >= ${r}, got: ${o}`);if(n!==void 0&&o>n)throw new Error(`scsynthOptions.${s} must be <= ${n}, got: ${o}`)}if(e.bufLength!==128)throw new Error(`scsynthOptions.bufLength must be 128 (WebAudio API constraint), got: ${e.bufLength}`);for(let s of["realTime","memoryLocking"])if(typeof e[s]!="boolean")throw new Error(`scsynthOptions.${s} must be a boolean, got: ${typeof e[s]}`);if(e.loadGraphDefs!==0&&e.loadGraphDefs!==1)throw new Error(`scsynthOptions.loadGraphDefs must be 0 or 1, got: ${e.loadGraphDefs}`);if(e.preferredSampleRate!==0&&e.preferredSampleRate<8e3)throw new Error(`scsynthOptions.preferredSampleRate must be 0 (auto) or >= 8000, got: ${e.preferredSampleRate}`)}#L(e,t){let s=e?{...U,...e}:{...U},r=t?.realTimeMemorySize||Ze.realTimeMemorySize;return r&&(s.rtPoolSize=Math.max(s.rtPoolSize,r*1024)),s.rtPoolOffset=(s.wasmHeapSize||U.wasmHeapSize)+(s.ringBufferReserved||U.ringBufferReserved),s.bufferPoolOffset=s.rtPoolOffset+s.rtPoolSize,s.totalMemory=s.bufferPoolOffset+s.bufferPoolSize,s.maxTotalMemory=s.bufferPoolOffset+s.maxBufferPoolSize,s}constructor(e={}){this.#d=!1,this.#E=!1,this.#p=null,this.#g={},this.#T=null,this.#f=new re,this.#h=new ie({mode:e.mode||"postMessage"}),this.#b=new fe({}),this.#e=null,this.#s=null,this.#o=null,this.#i=null,this.loadedSynthDefs=new Map;let t=e.baseURL||null,s=e.coreBaseURL||t,r=e.workerBaseURL||(t?`${t}workers/`:null),n=e.wasmBaseURL||(s?`${s}wasm/`:null);if(!r||!n)throw new Error(`SuperSonic requires explicit URL configuration.
|
|
6
6
|
|
|
7
7
|
For CDN usage:
|
|
8
8
|
import { SuperSonic } from 'https://unpkg.com/supersonic-scsynth@VERSION/dist/supersonic.js';
|
|
@@ -14,6 +14,6 @@ For CDN usage:
|
|
|
14
14
|
For local usage:
|
|
15
15
|
new SuperSonic({ baseURL: '/path/to/supersonic/dist/' })
|
|
16
16
|
|
|
17
|
-
See: https://github.com/samaaron/supersonic#configuration`);let o={...Ze,...e.scsynthOptions};this.#x(o);let a=e.mode||"postMessage";this.#t={mode:a,snapshotIntervalMs:e.snapshotIntervalMs??Hr,wasmBytes:e.wasmBytes??null,wasmUrl:e.wasmUrl||n+"scsynth-nrt.wasm",wasmBaseURL:n,workletUrl:e.workletUrl||(s?`${s}workers/scsynth_audio_worklet.js`:r+"scsynth_audio_worklet.js"),workerBaseURL:r,audioContext:e.audioContext||null,autoConnect:e.autoConnect!==!1,audioContextOptions:{latencyHint:"interactive",sampleRate:48e3,...e.audioContextOptions},memory:this.#L(e.memory,e.scsynthOptions),worldOptions:o,preschedulerCapacity:e.preschedulerCapacity||65536,bypassLookaheadMs:e.bypassLookaheadMs??500,activityEvent:{maxLineLength:e.activityEvent?.maxLineLength??200,scsynthMaxLineLength:e.activityEvent?.scsynthMaxLineLength??null,oscInMaxLineLength:e.activityEvent?.oscInMaxLineLength??null,oscOutMaxLineLength:e.activityEvent?.oscOutMaxLineLength??null},debug:e.debug??!1,debugScsynth:e.debugScsynth??!1,debugOscIn:e.debugOscIn??!1,debugOscOut:e.debugOscOut??!1,bufferGrowIncrement:e.bufferGrowIncrement??32*1024*1024},this.#t.effectiveMaxBufferMemory=e.maxBufferMemory||this.#t.memory.maxBufferPoolSize||this.#t.memory.bufferPoolSize,this.#l=e.sampleBaseURL||(t?`${t}samples/`:null),this.#y=e.synthdefBaseURL||(t?`${t}synthdefs/`:null),this.#S={maxRetries:e.fetchMaxRetries??3,baseDelay:e.fetchRetryDelay??1e3},this.#g=new te({onLoadingEvent:(c,u)=>this.#f.emit(c,u),maxRetries:this.#S.maxRetries,baseDelay:this.#S.baseDelay,skipHeadRequests:e.skipHeadRequests??!1}),this.bootStats={initStartTime:null,initDuration:null}}get initialized(){return this.#d}get initializing(){return this.#E}isRunning(){return this.#d}getEngineState(){return this.#E?"booting":this.#d?"running":"stopped"}get audioContext(){return this.#e}get superClock(){return this.#m}get mode(){return this.#t.mode}get bufferConstants(){return this.#h.bufferConstants}get ringBufferBase(){return this.#h.ringBufferBase}get sharedBuffer(){return this.#h.sharedBuffer}get node(){return this.#a}get osc(){return this.#o}get initTime(){return this.#m?.getNTPStartTime()??0}on(e,t){return this.#f.on(e,t)}off(e,t){return this.#f.off(e,t),this}once(e,t){return this.#f.once(e,t)}removeAllListeners(e){return this.#f.removeAllListeners(e),this}async init(){if(!this.#d)return this.#p?this.#p:(this.#p=this.#k(),this.#p)}async#k(){this.#E=!0,this.bootStats.initStartTime=performance.now();try{this.#z(),this.#Y(),this.#F(),this.#$(),this.#v();let e=await this.#V();await this.#q(e),await this.#X(),await this.#K()}catch(e){throw this.#E=!1,this.#p=null,console.error("[SuperSonic] Initialization failed:",e),this.#f.emit("error",e),e}}getMetrics(){return this.#W()}getMetricsArray(){return this.#re(),this.#h.getMergedArray()}getSnapshot(){let e=this.#W(),t=i.getMetricsSchema()?.metrics||{},s={};for(let[n,o]of Object.entries(e)){let a=t[n];a?.description?s[n]={value:o,description:a.description}:s[n]={value:o}}let r=null;return typeof performance<"u"&&performance.memory&&(r={usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize,jsHeapSizeLimit:performance.memory.jsHeapSizeLimit}),{timestamp:new Date().toISOString(),metrics:s,nodeTree:this.getRawTree(),memory:r}}getSystemReport(){this.#M("get system report");let e=this.#W(),t=[],s={userAgent:navigator.userAgent,hardwareConcurrency:navigator.hardwareConcurrency??null,deviceMemory:navigator.deviceMemory??null,platform:navigator.platform},r={sampleRate:this.#e.sampleRate,baseLatency:this.#e.baseLatency??null,outputLatency:this.#e.outputLatency??null,state:this.#e.state,channelCount:this.#t.worldOptions.numOutputBusChannels},n=this.#_.playbackStats?this.#e.playbackStats:null,o=n?{glitchCount:n.fallbackFramesEvents,glitchDurationS:n.fallbackFramesDuration,totalDurationS:n.totalFramesDuration,averageLatencyS:n.averageLatency,maximumLatencyS:n.maximumLatency}:null,a=this.#A?.getHealth()?.healthPct??100;a<95&&t.push({severity:a<80?"critical":"warning",message:`Audio health at ${a}% \u2014 audio thread may be falling behind`}),e.scsynthSchedulerLates>0&&t.push({severity:"warning",message:`${e.scsynthSchedulerLates} late bundles in scsynth scheduler`}),e.scsynthWasmErrors>0&&t.push({severity:"error",message:`${e.scsynthWasmErrors} WASM errors detected`}),n?.fallbackFramesEvents>0&&t.push({severity:"warning",message:`${n.fallbackFramesEvents} audio glitch events (${(n.fallbackFramesDuration*1e3).toFixed(1)}ms total silence)`}),e.driftOffsetMs!==void 0&&Math.abs(e.driftOffsetMs)>10&&t.push({severity:"warning",message:`Clock drift: ${e.driftOffsetMs}ms between AudioContext and wall clock`});let c=t.length===0?`Audio health: ${a}% \u2014 no issues detected`:`Audio health: ${a}% \u2014 ${t.length} issue(s): ${t.map(u=>u.message).join("; ")}`;return{timestamp:new Date().toISOString(),system:s,audio:r,playbackStats:o,engine:{mode:this.mode,version:this.#T,bootTimeMs:this.bootStats.initDuration},health:{audioHealthPct:a,issues:t,summary:c},metrics:e}}setClockOffset(e){this.#M("set clock offset"),this.#m?.setClockOffset(e)}async recover(){return this.#d?await this.resume()?!0:await this.reload():!1}async resume(){if(!this.#d||!this.#e)return!1;await this.purge();try{await this.#e.resume()}catch{}this.#m?.startDriftTimer();let e=this.#j();if(e===null){let r=this.#e.state==="running";return r&&(this.#m?.resync(),this.#f.emit("resumed")),r}await new Promise(r=>setTimeout(r,200));let t=this.#j(),s=t!==null&&t>e;return s&&(this.#m?.resync(),this.#f.emit("resumed")),s}async suspend(){if(this.#d){this.#m?.stopDriftTimer();try{await this.#e?.suspend()}catch{}}}async reload(){if(!this.#d)return!1;this.#f.emit("reload:start");let e=new Map(this.loadedSynthDefs),t=this.#i?.getAllocatedBuffers()||[];await this.#H(),await this.#G();for(let[s,r]of e)try{await this.send("/d_recv",r)}catch(n){console.error(`[SuperSonic] Failed to restore synthdef ${s}:`,n)}for(let s of t)try{if(this.#t.mode==="postMessage"&&s.source)s.source.type==="file"&&await this.loadSample(s.bufnum,s.source.path,s.source.startFrame||0,s.source.numFrames||0);else{let r=crypto.randomUUID();await this.send("/b_allocPtr",s.bufnum,s.ptr,s.numFrames,s.numChannels,s.sampleRate,r)}}catch(r){console.error(`[SuperSonic] Failed to restore buffer ${s.bufnum}:`,r)}return(e.size>0||t.length>0)&&await this.sync(),this.#f.emit("reload:complete",{success:!0}),!0}async#H(){this.#m?.stopDriftTimer(),this.#u?.clear(),this.#u=null,this.#o&&(this.#o.cancelAll(),this.#o.dispose(),this.#o=null),this.#P=null,this.#s&&(this.#s.disconnect(),this.#s=null),this.#e&&(await this.#e.close(),this.#e=null),this.#d=!1,this.#U=null,this.loadedSynthDefs.clear(),this.#p=null,this.#w=null,this.#m?.reset(),this.#A?.reset()}async#G(){this.#E=!0,this.bootStats.initStartTime=performance.now();try{this.#F(),this.#i&&this.#i.updateAudioContext(this.#e),this.#v();let e=await this.#V();await this.#q(e),await this.#X(),await this.#K()}catch(e){throw this.#E=!1,this.#p=null,console.error("[SuperSonic] Partial init failed:",e),this.#f.emit("error",e),e}}getRawTree(){if(!this.#d)return{nodeCount:0,version:0,droppedCount:0,nodes:[]};let e=this.#h.bufferConstants;if(!e)return{nodeCount:0,version:0,droppedCount:0,nodes:[]};let t,s;if(this.#t.mode==="postMessage"){let r=this.#h.getSnapshotBuffer();if(!r)return{nodeCount:0,version:0,droppedCount:0,nodes:[]};t=r,s=e.METRICS_SIZE}else{let r=this.#h.sharedBuffer;if(!r)return{nodeCount:0,version:0,droppedCount:0,nodes:[]};t=r,s=this.#h.ringBufferBase+e.NODE_TREE_START}return Ht(t,s,e)}getTree(){let e=this.getRawTree(),t=new Map,s=null;for(let a of e.nodes){let c={id:a.uuid||a.id,type:a.isGroup?"group":"synth",defName:a.defName,children:[]};t.set(a.id,{raw:a,tree:c}),(a.parentId===-1||a.parentId===0&&a.id===0)&&(s=a)}let r=t.size,n=a=>{let c=t.get(a);if(!c||!c.raw.isGroup)return;let u=c.raw.headId,l=0;for(;u!==-1&&u!==0&&l<r;){let f=t.get(u);if(!f)break;c.tree.children.push(f.tree),f.raw.isGroup&&n(u),u=f.raw.nextId,l++}},o=s?t.get(s.id).tree:null;return s&&n(s.id),{nodeCount:e.nodeCount,version:e.version,droppedCount:e.droppedCount,root:o||{id:0,type:"group",defName:"",children:[]}}}#N(e){this.#U||(this.#U=new Array(this.#h.bufferConstants.SHM_SCOPE_MAX_SCOPES));let t=this.#U[e];if(t)return t;let s=this.#h.bufferConstants,r=this.#h.sharedBuffer,o=this.#h.ringBufferBase+s.SHM_SCOPE_START+s.SHM_SCOPE_HEADER_SIZE+e*s.SHM_SCOPE_SLOT_SIZE,a=s.SHM_SCOPE_FRAMES_PER_SCOPE,c=a*s.SHM_SCOPE_CHANNELS,u=o+s.SHM_SCOPE_SLOT_HEADER_SIZE,l=[];for(let f=0;f<3;f++){let h=new Float32Array(r,u+f*c*4,c);l.push({left:h.subarray(0,a),right:h.subarray(a,a*2)})}return t={meta:new Uint32Array(r,o,4),stage:new Int32Array(r,o+8,1),framesPerScope:a,regions:l},this.#U[e]=t,t}getScope(e){if(!this.#d)return null;let t=this.#h.bufferConstants;if(!t||t.SHM_SCOPE_START==null||t.SHM_SCOPE_MAX_SCOPES==null||e<0||e>=t.SHM_SCOPE_MAX_SCOPES||!this.#h.sharedBuffer)return null;let s=this.#N(e);if(s.meta[0]===0)return null;let r=s.meta[1],n=Atomics.load(s.stage,0);if(n<0||n>2)return null;let o=s.regions[n];return{frames:s.framesPerScope,channels:r,left:o.left,right:r>=2?o.right:null}}getScopes(){if(!this.#d)return[];let e=this.#h.bufferConstants;if(!e||e.SHM_SCOPE_START==null||e.SHM_SCOPE_MAX_SCOPES==null)return[];if(!this.#h.sharedBuffer)return[];let t=[];for(let s=0;s<e.SHM_SCOPE_MAX_SCOPES;s++){let r=this.#N(s);r.meta[0]!==0&&t.push({index:s,channels:r.meta[1]})}return t}static getScopeSchema(){return{maxScopes:32,framesPerScope:1024,channels:2}}startCapture(){if(this.#M("start capture"),!this.#b.isAvailable())throw new Error("Audio capture is only available in SAB mode (set mode: 'sab').");this.#b.start()}stopCapture(){return this.#M("stop capture"),this.#b.stop()}isCaptureEnabled(){return this.#b.isEnabled()}getCaptureFrames(){return this.#b.getFrameCount()}getMaxCaptureDuration(){return this.#b.getMaxDuration()}send(e,...t){this.#M("send OSC messages");let s={"/d_load":"Use loadSynthDef() or send /d_recv with synthdef bytes instead.","/d_loadDir":"Use loadSynthDef() or send /d_recv with synthdef bytes instead.","/b_read":"Use loadSample() to load audio into a buffer.","/b_readChannel":"Use loadSample() to load audio into a buffer.","/b_write":"Writing audio files is not available in the browser.","/b_close":"Writing audio files is not available in the browser.","/clearSched":"Use purge() to clear both the JS prescheduler and WASM scheduler.","/error":"SuperSonic always enables error notifications so you never miss a /fail message.","/quit":"Use destroy() to shut down SuperSonic."};if(s[e])throw new Error(`${e} is not supported in SuperSonic. ${s[e]}`);if(e==="/d_recv"){let o=t[0];if(o instanceof Uint8Array||o instanceof ArrayBuffer){let a=o instanceof ArrayBuffer?new Uint8Array(o):o,c=H(a)||"unknown";this.loadedSynthDefs.set(c,a)}}if(e==="/d_free")for(let o of t)typeof o=="string"&&this.loadedSynthDefs.delete(o);else e==="/d_freeAll"&&this.loadedSynthDefs.clear();let r=t.map(o=>o instanceof ArrayBuffer?new Uint8Array(o):o);if(Gr.has(e)){this.#oe(e,r),this.#ae(e,r);return}let n=i.osc.encodeMessage(e,r);this.sendOSC(n)}sendOSC(e,t={}){this.#M("send OSC data");let s=this.#ne(e);this.#Q(s,t)}cancelTag(e){this.#M("cancel by tag"),this.#o.cancelTag(e)}cancelSession(e){this.#M("cancel by session"),this.#o.cancelSession(e)}cancelSessionTag(e,t){this.#M("cancel by session and tag"),this.#o.cancelSessionTag(e,t)}cancelAll(){this.#M("cancel all scheduled"),this.#o.cancelAll()}async purge(){this.#M("purge");let e=this.#o.cancelAllWithAck(),t=new Promise(s=>{let r=n=>{n.data.type==="clearSchedAck"&&(this.#s.port.removeEventListener("message",r),s())};this.#s.port.addEventListener("message",r),this.#s.port.postMessage({type:"clearSched",ack:!0})});await Promise.all([e,t])}createOscChannel(e={}){return this.#M("create OSC channel"),this.#o.createOscChannel(e)}nextNodeId(){return this.#M("allocate node IDs"),this.#w.nextNodeId()}async loadSynthDef(e){this.#M("load synthdef");let t,s;if(typeof e=="string"){let r;if(this.#ie(e))r=e;else{if(!this.#y)throw new Error("synthdefBaseURL not configured.");r=`${this.#y}${e}.scsyndef`}let n=H(r),o=await this.#g.fetch(r,{type:"synthdef",name:n});t=new Uint8Array(o),s=H(t)||n}else if(e instanceof ArrayBuffer||ArrayBuffer.isView(e)){if(t=e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength),s=H(t),!s)throw new Error("Could not extract synthdef name from binary data. Make sure it's a valid .scsyndef file.")}else if(e instanceof Blob){let r=await e.arrayBuffer();if(t=new Uint8Array(r),s=H(t),!s)throw new Error("Could not extract synthdef name from file. Make sure it's a valid .scsyndef file.")}else throw new Error("loadSynthDef source must be a name, path/URL string, ArrayBuffer, Uint8Array, or File/Blob");return await this.send("/d_recv",t),{name:s,size:t.length}}async loadSynthDefs(e){this.#M("load synthdefs");let t={};return await Promise.all(e.map(async s=>{try{await this.loadSynthDef(s),t[s]={success:!0}}catch(r){t[s]={success:!1,error:r.message}}})),t}async loadSample(e,t,s=0,r=0){this.#M("load samples");let n;if(typeof t=="string")n=await this.#i.prepareFromFile({bufnum:e,path:t,startFrame:s,numFrames:r});else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))n=await this.#i.prepareFromBlob({bufnum:e,blob:t,startFrame:s,numFrames:r});else if(t instanceof Blob){let u=await t.arrayBuffer();n=await this.#i.prepareFromBlob({bufnum:e,blob:u,startFrame:s,numFrames:r})}else throw new Error("loadSample source must be a path/URL string, ArrayBuffer, TypedArray, or File/Blob");await this.send("/b_allocPtr",e,n.ptr,n.numFrames,n.numChannels,n.sampleRate,n.uuid),await n.allocationComplete;let{numFrames:o,numChannels:a,sampleRate:c}=n;return{bufnum:e,hash:n.hash,source:typeof t=="string"?t:null,numFrames:o,numChannels:a,sampleRate:c,duration:c>0?o/c:0}}getLoadedBuffers(){return this.#M("get loaded buffers"),(this.#i?.getAllocatedBuffers()||[]).map(({bufnum:t,numFrames:s,numChannels:r,sampleRate:n,source:o,hash:a})=>({bufnum:t,hash:a||null,source:o?.path||o?.name||null,numFrames:s,numChannels:r,sampleRate:n,duration:n>0?s/n:0}))}async sampleInfo(e,t=0,s=0){this.#M("get sample info");let r;if(typeof e=="string")r=e;else if(e instanceof ArrayBuffer||ArrayBuffer.isView(e))r=e;else if(e instanceof Blob)r=await e.arrayBuffer();else throw new Error("sampleInfo source must be a path/URL string, ArrayBuffer, TypedArray, or File/Blob");return this.#i.sampleInfo({source:r,startFrame:t,numFrames:s})}async sync(e=Math.floor(Math.random()*2147483647)){this.#M("sync"),await this.#ce();let t=new Promise((s,r)=>{let n=setTimeout(()=>{this.#u?.delete(e),r(new Error("Timeout waiting for /synced response"))},Fr),o=()=>{clearTimeout(n),this.#u.delete(e),s()};this.#u||(this.#u=new Map),this.#u.set(e,o)});this.send("/sync",e),await t,this.#t.mode==="postMessage"&&await new Promise(s=>setTimeout(s,this.#t.snapshotIntervalMs*2))}getInfo(){return this.#M("get info"),{sampleRate:this.#e.sampleRate,numBuffers:this.#t.worldOptions.numBuffers,totalMemory:this.#t.memory.totalMemory,wasmHeapSize:this.#t.memory.wasmHeapSize,bufferPoolSize:this.#t.memory.bufferPoolSize,bootTimeMs:this.bootStats.initDuration,capabilities:{...this.#_},version:this.#T}}async shutdown(){!this.#d&&!this.#E||(this.#f.emit("shutdown"),this.#m?.stopDriftTimer(),this.#A?.reset(),this.#A=null,this.#u?.clear(),this.#u=null,this.#o&&(this.#o.cancelAll(),this.#o.dispose(),this.#o=null),this.#P=null,this.#s&&(this.#s.disconnect(),this.#s=null),this.#e&&(await this.#e.close(),this.#e=null),this.#i&&(this.#i.destroy(),this.#i=null),this.#n=null,this.#w=null,this.#D=Promise.resolve(),this.#d=!1,this.#U=null,this.loadedSynthDefs.clear(),this.#p=null,this.#c=null,this.#m?.reset(),this.bootStats={initStartTime:null,initDuration:null})}async destroy(){this.#f.emit("destroy"),await this.shutdown(),this.#B=null,this.#f.removeAllListeners()}async reset(){await this.shutdown(),await this.init()}#z(){this.#_={audioWorklet:typeof AudioWorklet<"u",sharedArrayBuffer:typeof SharedArrayBuffer<"u",crossOriginIsolated:window.crossOriginIsolated===!0,atomics:typeof Atomics<"u",webWorker:typeof Worker<"u",playbackStats:typeof AudioContext<"u"&&"playbackStats"in AudioContext.prototype};let e=this.#t.mode,t=["audioWorklet","webWorker"];e==="sab"&&t.push("sharedArrayBuffer","crossOriginIsolated","atomics");let s=t.filter(r=>!this.#_[r]);if(s.length>0){let r=new Error(`Missing required features for ${e} mode: ${s.join(", ")}`);throw e==="sab"&&!this.#_.crossOriginIsolated&&(r.message+=`
|
|
17
|
+
See: https://github.com/samaaron/supersonic#configuration`);let o={...Ze,...e.scsynthOptions};this.#x(o);let a=e.mode||"postMessage";this.#t={mode:a,snapshotIntervalMs:e.snapshotIntervalMs??Hr,wasmBytes:e.wasmBytes??null,wasmUrl:e.wasmUrl||n+"scsynth-nrt.wasm",wasmBaseURL:n,workletUrl:e.workletUrl||(s?`${s}workers/scsynth_audio_worklet.js`:r+"scsynth_audio_worklet.js"),workerBaseURL:r,audioContext:e.audioContext||null,autoConnect:e.autoConnect!==!1,audioContextOptions:{latencyHint:"interactive",sampleRate:48e3,...e.audioContextOptions},memory:this.#L(e.memory,e.scsynthOptions),worldOptions:o,preschedulerCapacity:e.preschedulerCapacity||65536,bypassLookaheadMs:e.bypassLookaheadMs??500,activityEvent:{maxLineLength:e.activityEvent?.maxLineLength??200,scsynthMaxLineLength:e.activityEvent?.scsynthMaxLineLength??null,oscInMaxLineLength:e.activityEvent?.oscInMaxLineLength??null,oscOutMaxLineLength:e.activityEvent?.oscOutMaxLineLength??null},debug:e.debug??!1,debugScsynth:e.debugScsynth??!1,debugOscIn:e.debugOscIn??!1,debugOscOut:e.debugOscOut??!1,bufferGrowIncrement:e.bufferGrowIncrement??32*1024*1024},this.#t.effectiveMaxBufferMemory=e.maxBufferMemory||this.#t.memory.maxBufferPoolSize||this.#t.memory.bufferPoolSize,this.#l=e.sampleBaseURL||(t?`${t}samples/`:null),this.#y=e.synthdefBaseURL||(t?`${t}synthdefs/`:null),this.#S={maxRetries:e.fetchMaxRetries??3,baseDelay:e.fetchRetryDelay??1e3},this.#_=new te({onLoadingEvent:(c,u)=>this.#f.emit(c,u),maxRetries:this.#S.maxRetries,baseDelay:this.#S.baseDelay,skipHeadRequests:e.skipHeadRequests??!1}),this.bootStats={initStartTime:null,initDuration:null}}get initialized(){return this.#d}get initializing(){return this.#E}isRunning(){return this.#d}getEngineState(){return this.#E?"booting":this.#d?"running":"stopped"}get audioContext(){return this.#e}get superClock(){return this.#m}get mode(){return this.#t.mode}get bufferConstants(){return this.#h.bufferConstants}get ringBufferBase(){return this.#h.ringBufferBase}get sharedBuffer(){return this.#h.sharedBuffer}get node(){return this.#a}get osc(){return this.#o}get initTime(){return this.#m?.getNTPStartTime()??0}on(e,t){return this.#f.on(e,t)}off(e,t){return this.#f.off(e,t),this}once(e,t){return this.#f.once(e,t)}removeAllListeners(e){return this.#f.removeAllListeners(e),this}async init(){if(!this.#d)return this.#p?this.#p:(this.#p=this.#k(),this.#p)}async#k(){this.#E=!0,this.bootStats.initStartTime=performance.now();try{this.#z(),this.#Y(),this.#F(),this.#$(),this.#v();let e=await this.#V();await this.#q(e),await this.#X(),await this.#K()}catch(e){throw this.#E=!1,this.#p=null,console.error("[SuperSonic] Initialization failed:",e),this.#f.emit("error",e),e}}getMetrics(){return this.#W()}getMetricsArray(){return this.#re(),this.#h.getMergedArray()}getSnapshot(){let e=this.#W(),t=i.getMetricsSchema()?.metrics||{},s={};for(let[n,o]of Object.entries(e)){let a=t[n];a?.description?s[n]={value:o,description:a.description}:s[n]={value:o}}let r=null;return typeof performance<"u"&&performance.memory&&(r={usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize,jsHeapSizeLimit:performance.memory.jsHeapSizeLimit}),{timestamp:new Date().toISOString(),metrics:s,nodeTree:this.getRawTree(),memory:r}}getSystemReport(){this.#M("get system report");let e=this.#W(),t=[],s={userAgent:navigator.userAgent,hardwareConcurrency:navigator.hardwareConcurrency??null,deviceMemory:navigator.deviceMemory??null,platform:navigator.platform},r={sampleRate:this.#e.sampleRate,baseLatency:this.#e.baseLatency??null,outputLatency:this.#e.outputLatency??null,state:this.#e.state,channelCount:this.#t.worldOptions.numOutputBusChannels},n=this.#g.playbackStats?this.#e.playbackStats:null,o=n?{glitchCount:n.fallbackFramesEvents,glitchDurationS:n.fallbackFramesDuration,totalDurationS:n.totalFramesDuration,averageLatencyS:n.averageLatency,maximumLatencyS:n.maximumLatency}:null,a=this.#A?.getHealth()?.healthPct??100;a<95&&t.push({severity:a<80?"critical":"warning",message:`Audio health at ${a}% \u2014 audio thread may be falling behind`}),e.scsynthSchedulerLates>0&&t.push({severity:"warning",message:`${e.scsynthSchedulerLates} late bundles in scsynth scheduler`}),e.scsynthWasmErrors>0&&t.push({severity:"error",message:`${e.scsynthWasmErrors} WASM errors detected`}),n?.fallbackFramesEvents>0&&t.push({severity:"warning",message:`${n.fallbackFramesEvents} audio glitch events (${(n.fallbackFramesDuration*1e3).toFixed(1)}ms total silence)`}),e.driftOffsetMs!==void 0&&Math.abs(e.driftOffsetMs)>10&&t.push({severity:"warning",message:`Clock drift: ${e.driftOffsetMs}ms between AudioContext and wall clock`});let c=t.length===0?`Audio health: ${a}% \u2014 no issues detected`:`Audio health: ${a}% \u2014 ${t.length} issue(s): ${t.map(u=>u.message).join("; ")}`;return{timestamp:new Date().toISOString(),system:s,audio:r,playbackStats:o,engine:{mode:this.mode,version:this.#T,bootTimeMs:this.bootStats.initDuration},health:{audioHealthPct:a,issues:t,summary:c},metrics:e}}setClockOffset(e){this.#M("set clock offset"),this.#m?.setClockOffset(e)}async recover(){return this.#d?await this.resume()?!0:await this.reload():!1}async resume(){if(!this.#d||!this.#e)return!1;await this.purge();try{await this.#e.resume()}catch{}this.#m?.startDriftTimer();let e=this.#j();if(e===null){let r=this.#e.state==="running";return r&&(this.#m?.resync(),this.#f.emit("resumed")),r}await new Promise(r=>setTimeout(r,200));let t=this.#j(),s=t!==null&&t>e;return s&&(this.#m?.resync(),this.#f.emit("resumed")),s}async suspend(){if(this.#d){this.#m?.stopDriftTimer();try{await this.#e?.suspend()}catch{}}}async reload(){if(!this.#d)return!1;this.#f.emit("reload:start");let e=new Map(this.loadedSynthDefs),t=this.#i?.getAllocatedBuffers()||[];await this.#H(),await this.#G();for(let[s,r]of e)try{await this.send("/d_recv",r)}catch(n){console.error(`[SuperSonic] Failed to restore synthdef ${s}:`,n)}for(let s of t)try{if(this.#t.mode==="postMessage"&&s.source)s.source.type==="file"&&await this.loadSample(s.bufnum,s.source.path,s.source.startFrame||0,s.source.numFrames||0);else{let r=crypto.randomUUID();await this.send("/b_allocPtr",s.bufnum,s.ptr,s.numFrames,s.numChannels,s.sampleRate,r)}}catch(r){console.error(`[SuperSonic] Failed to restore buffer ${s.bufnum}:`,r)}return(e.size>0||t.length>0)&&await this.sync(),this.#f.emit("reload:complete",{success:!0}),!0}async#H(){this.#m?.stopDriftTimer(),this.#u?.clear(),this.#u=null,this.#o&&(this.#o.cancelAll(),this.#o.dispose(),this.#o=null),this.#P=null,this.#s&&(this.#s.disconnect(),this.#s=null),this.#e&&(await this.#e.close(),this.#e=null),this.#d=!1,this.#U=null,this.loadedSynthDefs.clear(),this.#p=null,this.#w=null,this.#m?.reset(),this.#A?.reset()}async#G(){this.#E=!0,this.bootStats.initStartTime=performance.now();try{this.#F(),this.#i&&this.#i.updateAudioContext(this.#e),this.#v();let e=await this.#V();await this.#q(e),await this.#X(),await this.#K()}catch(e){throw this.#E=!1,this.#p=null,console.error("[SuperSonic] Partial init failed:",e),this.#f.emit("error",e),e}}getRawTree(){if(!this.#d)return{nodeCount:0,version:0,droppedCount:0,nodes:[]};let e=this.#h.bufferConstants;if(!e)return{nodeCount:0,version:0,droppedCount:0,nodes:[]};let t,s;if(this.#t.mode==="postMessage"){let r=this.#h.getSnapshotBuffer();if(!r)return{nodeCount:0,version:0,droppedCount:0,nodes:[]};t=r,s=e.METRICS_SIZE}else{let r=this.#h.sharedBuffer;if(!r)return{nodeCount:0,version:0,droppedCount:0,nodes:[]};t=r,s=this.#h.ringBufferBase+e.NODE_TREE_START}return Ht(t,s,e)}getTree(){let e=this.getRawTree(),t=new Map,s=null;for(let a of e.nodes){let c={id:a.uuid||a.id,type:a.isGroup?"group":"synth",defName:a.defName,children:[]};t.set(a.id,{raw:a,tree:c}),(a.parentId===-1||a.parentId===0&&a.id===0)&&(s=a)}let r=t.size,n=a=>{let c=t.get(a);if(!c||!c.raw.isGroup)return;let u=c.raw.headId,l=0;for(;u!==-1&&u!==0&&l<r;){let f=t.get(u);if(!f)break;c.tree.children.push(f.tree),f.raw.isGroup&&n(u),u=f.raw.nextId,l++}},o=s?t.get(s.id).tree:null;return s&&n(s.id),{nodeCount:e.nodeCount,version:e.version,droppedCount:e.droppedCount,root:o||{id:0,type:"group",defName:"",children:[]}}}#N(e){this.#U||(this.#U=new Array(this.#h.bufferConstants.SHM_SCOPE_MAX_SCOPES));let t=this.#U[e];if(t)return t;let s=this.#h.bufferConstants,r=this.#h.sharedBuffer,o=this.#h.ringBufferBase+s.SHM_SCOPE_START+s.SHM_SCOPE_HEADER_SIZE+e*s.SHM_SCOPE_SLOT_SIZE,a=s.SHM_SCOPE_FRAMES_PER_SCOPE,c=a*s.SHM_SCOPE_CHANNELS,u=o+s.SHM_SCOPE_SLOT_HEADER_SIZE,l=[];for(let f=0;f<3;f++){let h=new Float32Array(r,u+f*c*4,c);l.push({left:h.subarray(0,a),right:h.subarray(a,a*2)})}return t={meta:new Uint32Array(r,o,4),stage:new Int32Array(r,o+8,1),framesPerScope:a,regions:l},this.#U[e]=t,t}getScope(e){if(!this.#d)return null;let t=this.#h.bufferConstants;if(!t||t.SHM_SCOPE_START==null||t.SHM_SCOPE_MAX_SCOPES==null||e<0||e>=t.SHM_SCOPE_MAX_SCOPES||!this.#h.sharedBuffer)return null;let s=this.#N(e);if(s.meta[0]===0)return null;let r=s.meta[1],n=Atomics.load(s.stage,0);if(n<0||n>2)return null;let o=s.regions[n];return{frames:s.framesPerScope,channels:r,left:o.left,right:r>=2?o.right:null}}getScopes(){if(!this.#d)return[];let e=this.#h.bufferConstants;if(!e||e.SHM_SCOPE_START==null||e.SHM_SCOPE_MAX_SCOPES==null)return[];if(!this.#h.sharedBuffer)return[];let t=[];for(let s=0;s<e.SHM_SCOPE_MAX_SCOPES;s++){let r=this.#N(s);r.meta[0]!==0&&t.push({index:s,channels:r.meta[1]})}return t}static getScopeSchema(){return{maxScopes:32,framesPerScope:1024,channels:2}}startCapture(){if(this.#M("start capture"),!this.#b.isAvailable())throw new Error("Audio capture is only available in SAB mode (set mode: 'sab').");this.#b.start()}stopCapture(){return this.#M("stop capture"),this.#b.stop()}isCaptureEnabled(){return this.#b.isEnabled()}getCaptureFrames(){return this.#b.getFrameCount()}getMaxCaptureDuration(){return this.#b.getMaxDuration()}send(e,...t){this.#M("send OSC messages");let s={"/d_load":"Use loadSynthDef() or send /d_recv with synthdef bytes instead.","/d_loadDir":"Use loadSynthDef() or send /d_recv with synthdef bytes instead.","/b_read":"Use loadSample() to load audio into a buffer.","/b_readChannel":"Use loadSample() to load audio into a buffer.","/b_write":"Writing audio files is not available in the browser.","/b_close":"Writing audio files is not available in the browser.","/clearSched":"Use purge() to clear both the JS prescheduler and WASM scheduler.","/error":"SuperSonic always enables error notifications so you never miss a /fail message.","/quit":"Use destroy() to shut down SuperSonic."};if(s[e])throw new Error(`${e} is not supported in SuperSonic. ${s[e]}`);if(e==="/d_recv"){let o=t[0];if(o instanceof Uint8Array||o instanceof ArrayBuffer){let a=o instanceof ArrayBuffer?new Uint8Array(o):o,c=H(a)||"unknown";this.loadedSynthDefs.set(c,a)}}if(e==="/d_free")for(let o of t)typeof o=="string"&&this.loadedSynthDefs.delete(o);else e==="/d_freeAll"&&this.loadedSynthDefs.clear();let r=t.map(o=>o instanceof ArrayBuffer?new Uint8Array(o):o);if(Gr.has(e)){this.#oe(e,r),this.#ae(e,r);return}let n=i.osc.encodeMessage(e,r);this.sendOSC(n)}sendOSC(e,t={}){this.#M("send OSC data");let s=this.#ne(e);this.#Q(s,t)}cancelTag(e){this.#M("cancel by tag"),this.#o.cancelTag(e)}cancelSession(e){this.#M("cancel by session"),this.#o.cancelSession(e)}cancelSessionTag(e,t){this.#M("cancel by session and tag"),this.#o.cancelSessionTag(e,t)}cancelAll(){this.#M("cancel all scheduled"),this.#o.cancelAll()}async purge(){this.#M("purge");let e=this.#o.cancelAllWithAck(),t=new Promise(s=>{let r=n=>{n.data.type==="clearSchedAck"&&(this.#s.port.removeEventListener("message",r),s())};this.#s.port.addEventListener("message",r),this.#s.port.postMessage({type:"clearSched",ack:!0})});await Promise.all([e,t])}createOscChannel(e={}){return this.#M("create OSC channel"),this.#o.createOscChannel(e)}nextNodeId(){return this.#M("allocate node IDs"),this.#w.nextNodeId()}async loadSynthDef(e){this.#M("load synthdef");let t,s;if(typeof e=="string"){let r;if(this.#ie(e))r=e;else{if(!this.#y)throw new Error("synthdefBaseURL not configured.");r=`${this.#y}${e}.scsyndef`}let n=H(r),o=await this.#_.fetch(r,{type:"synthdef",name:n});t=new Uint8Array(o),s=H(t)||n}else if(e instanceof ArrayBuffer||ArrayBuffer.isView(e)){if(t=e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength),s=H(t),!s)throw new Error("Could not extract synthdef name from binary data. Make sure it's a valid .scsyndef file.")}else if(e instanceof Blob){let r=await e.arrayBuffer();if(t=new Uint8Array(r),s=H(t),!s)throw new Error("Could not extract synthdef name from file. Make sure it's a valid .scsyndef file.")}else throw new Error("loadSynthDef source must be a name, path/URL string, ArrayBuffer, Uint8Array, or File/Blob");return await this.send("/d_recv",t),{name:s,size:t.length}}async loadSynthDefs(e){this.#M("load synthdefs");let t={};return await Promise.all(e.map(async s=>{try{await this.loadSynthDef(s),t[s]={success:!0}}catch(r){t[s]={success:!1,error:r.message}}})),t}async loadSample(e,t,s=0,r=0){this.#M("load samples");let n;if(typeof t=="string")n=await this.#i.prepareFromFile({bufnum:e,path:t,startFrame:s,numFrames:r});else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))n=await this.#i.prepareFromBlob({bufnum:e,blob:t,startFrame:s,numFrames:r});else if(t instanceof Blob){let u=await t.arrayBuffer();n=await this.#i.prepareFromBlob({bufnum:e,blob:u,startFrame:s,numFrames:r})}else throw new Error("loadSample source must be a path/URL string, ArrayBuffer, TypedArray, or File/Blob");await this.send("/b_allocPtr",e,n.ptr,n.numFrames,n.numChannels,n.sampleRate,n.uuid),await n.allocationComplete;let{numFrames:o,numChannels:a,sampleRate:c}=n;return{bufnum:e,hash:n.hash,source:typeof t=="string"?t:null,numFrames:o,numChannels:a,sampleRate:c,duration:c>0?o/c:0}}getLoadedBuffers(){return this.#M("get loaded buffers"),(this.#i?.getAllocatedBuffers()||[]).map(({bufnum:t,numFrames:s,numChannels:r,sampleRate:n,source:o,hash:a})=>({bufnum:t,hash:a||null,source:o?.path||o?.name||null,numFrames:s,numChannels:r,sampleRate:n,duration:n>0?s/n:0}))}async sampleInfo(e,t=0,s=0){this.#M("get sample info");let r;if(typeof e=="string")r=e;else if(e instanceof ArrayBuffer||ArrayBuffer.isView(e))r=e;else if(e instanceof Blob)r=await e.arrayBuffer();else throw new Error("sampleInfo source must be a path/URL string, ArrayBuffer, TypedArray, or File/Blob");return this.#i.sampleInfo({source:r,startFrame:t,numFrames:s})}async sync(e=Math.floor(Math.random()*2147483647)){this.#M("sync"),await this.#ce();let t=new Promise((s,r)=>{let n=setTimeout(()=>{this.#u?.delete(e),r(new Error("Timeout waiting for /synced response"))},Fr),o=()=>{clearTimeout(n),this.#u.delete(e),s()};this.#u||(this.#u=new Map),this.#u.set(e,o)});this.send("/sync",e),await t,this.#t.mode==="postMessage"&&await new Promise(s=>setTimeout(s,this.#t.snapshotIntervalMs*2))}getInfo(){return this.#M("get info"),{sampleRate:this.#e.sampleRate,numBuffers:this.#t.worldOptions.numBuffers,totalMemory:this.#t.memory.totalMemory,wasmHeapSize:this.#t.memory.wasmHeapSize,bufferPoolSize:this.#t.memory.bufferPoolSize,bootTimeMs:this.bootStats.initDuration,capabilities:{...this.#g},version:this.#T}}async shutdown(){!this.#d&&!this.#E||(this.#f.emit("shutdown"),this.#m?.stopDriftTimer(),this.#A?.reset(),this.#A=null,this.#u?.clear(),this.#u=null,this.#o&&(this.#o.cancelAll(),this.#o.dispose(),this.#o=null),this.#P=null,this.#s&&(this.#s.disconnect(),this.#s=null),this.#e&&(await this.#e.close(),this.#e=null),this.#i&&(this.#i.destroy(),this.#i=null),this.#n=null,this.#w=null,this.#D=Promise.resolve(),this.#d=!1,this.#U=null,this.loadedSynthDefs.clear(),this.#p=null,this.#c=null,this.#m?.reset(),this.bootStats={initStartTime:null,initDuration:null})}async destroy(){this.#f.emit("destroy"),await this.shutdown(),this.#B=null,this.#f.removeAllListeners()}async reset(){await this.shutdown(),await this.init()}#z(){this.#g={audioWorklet:typeof AudioWorklet<"u",sharedArrayBuffer:typeof SharedArrayBuffer<"u",crossOriginIsolated:window.crossOriginIsolated===!0,atomics:typeof Atomics<"u",webWorker:typeof Worker<"u",playbackStats:typeof AudioContext<"u"&&"playbackStats"in AudioContext.prototype};let e=this.#t.mode,t=["audioWorklet","webWorker"];e==="sab"&&t.push("sharedArrayBuffer","crossOriginIsolated","atomics");let s=t.filter(r=>!this.#g[r]);if(s.length>0){let r=new Error(`Missing required features for ${e} mode: ${s.join(", ")}`);throw e==="sab"&&!this.#g.crossOriginIsolated&&(r.message+=`
|
|
18
18
|
|
|
19
|
-
Consider using mode: 'postMessage' which doesn't require COOP/COEP headers.`),r}if(e!=="sab"&&e!=="postMessage")throw new Error(`Invalid mode: '${e}'. Use 'sab' or 'postMessage'.`)}#Y(){let e=this.#t.memory;if(this.#t.mode==="sab"){let s=U.totalPages,r=Math.max(Math.ceil(e.totalMemory/65536),s),n=Math.ceil(e.maxTotalMemory/65536);this.#c=new WebAssembly.Memory({initial:r,maximum:n,shared:!0})}else this.#c=null}#F(){this.#t.audioContext?this.#e=this.#t.audioContext:this.#e=new AudioContext(this.#t.audioContextOptions),this.#e.addEventListener("statechange",()=>{let e=this.#e?.state;if(!e)return;let t=this.#R;this.#R=e,e==="running"&&(t==="suspended"||t==="interrupted")&&this.#m?.resync(),this.#f.emit("audiocontext:statechange",{state:e}),e==="suspended"?(this.#f.emit("audiocontext:suspended"),this.#A?.reset()):e==="running"?(this.#f.emit("audiocontext:resumed"),this.#A?.reset()):e==="interrupted"&&(this.#f.emit("audiocontext:interrupted"),this.#A?.reset())}),this.#A=new ue({audioContext:this.#e})}#$(){let e=this.#t.mode==="sab"?this.#c.buffer:null;this.#i=new ee({mode:this.#t.mode,audioContext:this.#e,sharedBuffer:e,bufferPoolConfig:{start:this.#t.memory.bufferPoolOffset,size:this.#t.memory.bufferPoolSize,maxSize:this.#t.effectiveMaxBufferMemory},sampleBaseURL:this.#l,maxBuffers:this.#t.worldOptions.numBuffers,assetLoader:this.#g,wasmMemory:this.#c,maxBufferMemory:this.#t.effectiveMaxBufferMemory,bufferGrowIncrement:this.#t.bufferGrowIncrement,growFn:this.#t.mode==="postMessage"?t=>this.#te(t):null,onBufferPoolGrowth:t=>{this.#f.emit("buffer:pool:grown",t)}})}#v(){this.#n=new se({bufferManager:this.#i,getDefaultSampleRate:()=>this.#e?.sampleRate||44100})}async#V(){if(this.#B)return this.#B;let e=this.#t.wasmUrl.split("/").pop();if(this.#t.wasmBytes){let s=this.#t.wasmBytes;return this.#f.emit("loading:start",{type:"wasm",name:e,size:s.byteLength}),this.#f.emit("loading:complete",{type:"wasm",name:e,size:s.byteLength}),this.#B=s,s}let t=await this.#g.fetch(this.#t.wasmUrl,{type:"wasm",name:e});return this.#B=t,t}async#q(e){await st(this.#e.audioWorklet,this.#t.workletUrl);let t=this.#t.worldOptions.numOutputBusChannels;if(this.#s=new AudioWorkletNode(this.#e,"scsynth-processor",{numberOfInputs:1,numberOfOutputs:1,outputChannelCount:[t]}),this.#t.autoConnect){let o=this.#e.destination;t>2&&(o.channelCount=Math.min(t,o.maxChannelCount),o.channelInterpretation="discrete"),this.#s.connect(o)}this.#a=this.#J(),this.#s.port.start(),this.#se();let s=this.#t.mode,r=s==="sab"?this.#c.buffer:null;this.#s.port.postMessage({type:"init",mode:s,sharedBuffer:r,snapshotIntervalMs:this.#t.snapshotIntervalMs});let n={type:"loadWasm",wasmBytes:e,worldOptions:{...this.#t.worldOptions,rtPoolOffset:this.#t.memory.rtPoolOffset},sampleRate:this.#e.sampleRate};if(s==="sab")n.wasmMemory=this.#c;else{let o=U.totalPages;n.memoryPages=Math.max(Math.ceil(this.#t.memory.totalMemory/65536),o),n.maxMemoryPages=Math.ceil(this.#t.memory.maxTotalMemory/65536)}this.#s.port.postMessage(n),await this.#ee(),this.#i.setWorkletPort(this.#s.port)}#J(){let e=this.#s;return Object.freeze({connect:(...t)=>e.connect(...t),disconnect:(...t)=>e.disconnect(...t),get context(){return e.context},get numberOfOutputs(){return e.numberOfOutputs},get numberOfInputs(){return e.numberOfInputs},get channelCount(){return e.channelCount},get input(){return e}})}async#X(){let e=this.#t.mode,t=this.#h.bufferConstants,s=this.#h.ringBufferBase,r=this.#h.sharedBuffer,n={workerBaseURL:this.#t.workerBaseURL,preschedulerCapacity:this.#t.preschedulerCapacity,snapshotIntervalMs:this.#t.snapshotIntervalMs,bypassLookaheadS:this.#t.bypassLookaheadMs/1e3,getAudioContextTime:()=>this.#e?.currentTime??0,getNTPStartTime:()=>this.#m?.getNTPStartTime()??0};if(e==="sab"){if(n.sharedBuffer=r,n.ringBufferBase=s,n.bufferConstants=t,t?.NODE_ID_COUNTER_START!==void 0){let o=s+t.NODE_ID_COUNTER_START,a=new Int32Array(r,o,1);Atomics.store(a,0,1e3)}}else{this.#C=1e3,n.nodeIdSource=l=>{let f=this.#C;return this.#C+=l,{from:f,to:f+l}};let o=1e4,a=n.nodeIdSource(o),c=new MessageChannel,u=n.nodeIdSource;c.port1.onmessage=l=>{if(l.data.type==="requestNodeIdRange"){let f=u(o);c.port1.postMessage({type:"nodeIdRange",from:f.from,to:f.to})}},this.#s.port.postMessage({type:"nodeIdRange",from:a.from,to:a.to},[c.port2])}if(this.#o=lt(e,n),this.#o.onReply((o,a,c)=>{let u=Ke(o)||null;this.#f.emit("in:osc",{oscData:o,sequence:a,timestamp:c,scheduledTime:u});try{let l=V(o),f=l[0],h=l.slice(1);if(f==="/supersonic/buffer/freed")this.#i?.handleBufferFreed(h);else if(f==="/supersonic/buffer/allocated")this.#i?.handleBufferAllocated(h);else if(f==="/synced"&&h.length>0){let y=h[0];this.#u?.has(y)&&this.#u.get(y)(l)}if(this.#f.emit("in",l),this.#f.hasListeners("in:text")||this.#t.debug||this.#t.debugOscIn){let y=this.#t.activityEvent.oscInMaxLineLength??this.#t.activityEvent.maxLineLength,p=h.map(m=>ss(m,y)).join(", ")||"",d=`${f}${p?" "+p:""}`;this.#f.emit("in:text",{text:d,sequence:a,timestamp:c})}if(this.#f.hasListeners("in:html")){let y=je(l,a,c,this.initTime);this.#f.emit("in:html",{html:y,sequence:a,timestamp:c})}}catch(l){console.error("[SuperSonic] Failed to decode OSC message:",l)}}),this.#o.onDebug(o=>{let a=this.#t.activityEvent.scsynthMaxLineLength??this.#t.activityEvent.maxLineLength;a>0&&o.text?.length>a&&(o={...o,text:o.text.slice(0,a)+"..."}),this.#f.emit("debug",o)}),this.#o.onError((o,a)=>{console.error(`[SuperSonic] ${a} error:`,o),this.#f.emit("error",new Error(`${a}: ${o}`))}),this.#o.onOscLog(o=>{for(let a of o){let c=Ke(a.oscData)||null;if(this.#f.emit("out:osc",{oscData:a.oscData,sourceId:a.sourceId,sequence:a.sequence,timestamp:a.timestamp,scheduledTime:c}),this.#f.hasListeners("out")||this.#f.hasListeners("out:text")||this.#f.hasListeners("out:html")||this.#t.debug||this.#t.debugOscOut)try{let l=V(a.oscData);if(this.#f.emit("out",l),this.#f.hasListeners("out:text")||this.#t.debug||this.#t.debugOscOut){let f=this.#t.activityEvent.oscOutMaxLineLength??this.#t.activityEvent.maxLineLength,h=l[0],p=l.slice(1).map(m=>ss(m,f)).join(", "),d=`${h}${p?" "+p:""}`;this.#f.emit("out:text",{text:d,sequence:a.sequence,timestamp:a.timestamp})}if(this.#f.hasListeners("out:html")){let f=Yr(l,a.sequence,a.timestamp,this.initTime,a.sourceId);this.#f.emit("out:html",{html:f,sequence:a.sequence,timestamp:a.timestamp})}}catch{}}}),(this.#t.debug||this.#t.debugOscIn)&&this.on("in:text",({text:o})=>console.log(`[\u2190 OSC] ${o}`)),(this.#t.debug||this.#t.debugOscOut)&&this.on("out:text",({text:o})=>console.log(`[OSC \u2192] ${o}`)),(this.#t.debug||this.#t.debugScsynth)&&this.on("debug",o=>console.log(`[synth] ${o.text}`)),e==="sab")await this.#o.initialize();else{if(await this.#o.initialize(this.#s.port),this.#o.setBufferConstants(t),this.#O?.length>0)for(let o of this.#O)this.#o.handleDebugRaw(o);this.#P=o=>this.#o?.handleDebugRaw(o),this.#O=[]}this.#w=this.#o.createOscChannel({sourceId:0})}async#K(){this.#w&&this.#m&&(this.#w.getCurrentNTP=()=>this.#m.wallNow()),this.#d=!0,this.#E=!1,this.bootStats.initDuration=performance.now()-this.bootStats.initStartTime,await this.#f.emitAsync("setup"),this.#f.emit("ready",{capabilities:this.#_,bootStats:this.bootStats})}#ee(){return new Promise((e,t)=>{let s=setTimeout(()=>{t(new Error("AudioWorklet initialization timeout"))},vr),r=async n=>{if(n.data.type==="error"){clearTimeout(s),this.#s.port.removeEventListener("message",r),t(new Error(n.data.error||"AudioWorklet error"));return}if(n.data.type==="initialized")if(clearTimeout(s),this.#s.port.removeEventListener("message",r),n.data.success){let o=n.data.ringBufferBase??0,a=n.data.bufferConstants,c=this.#t.mode==="sab"?this.#c.buffer:null;this.#h.initSharedViews(c,o,a);let u=this.#t.worldOptions?.maxNodes??1024,l=a?.NODE_TREE_MIRROR_MAX_NODES??1024;u>l&&console.warn(`SuperSonic: maxNodes (${u}) exceeds NODE_TREE_MIRROR_MAX_NODES (${l}). The node tree mirror will not show all nodes. Rebuild with NODE_TREE_MIRROR_MAX_NODES=${u} to fix.`),this.#m=new le({mode:this.#t.mode,audioContext:this.#e,workletPort:this.#s.port}),this.#m.initSharedViews(c,o,a),await this.#m.initialize(),this.#m.startDriftTimer(),this.#t.mode==="sab"&&this.#b.update(c,o,a),this.#t.mode==="postMessage"&&n.data.initialSnapshot&&this.#h.updateSnapshot(n.data.initialSnapshot),e()}else t(new Error(n.data.error||"AudioWorklet initialization failed"))};this.#s.port.addEventListener("message",r),this.#s.port.start()})}#te(e){return new Promise(t=>{let s=crypto.randomUUID(),r=n=>{n.data.type==="memoryGrown"&&n.data.growId===s&&(this.#s.port.removeEventListener("message",r),t(n.data.success))};this.#s.port.addEventListener("message",r),this.#s.port.postMessage({type:"growMemory",growId:s,pages:e})})}#se(){this.#s.port.addEventListener("message",e=>{let{data:t}=e;switch(t.type){case"error":console.error("[Worklet] Error:",t.error),this.#f.emit("error",new Error(t.error));break;case"version":this.#T=t.version;break;case"snapshot":t.buffer&&(this.#h.updateSnapshot(t.buffer),this.#I=t.snapshotsSent);break;case"debugRawBatch":this.#P?this.#P(t):this.#O&&this.#O.push(t);break}})}#Z(){return{preschedulerMetrics:this.#o?.getPreschedulerMetrics(),transportMetrics:this.#o?.getMetrics(),driftOffsetMs:this.#m?.getDriftOffset()??0,ntpStartTime:this.#m?.getNTPStartTime()??0,clockOffsetMs:this.#m?.getClockOffset()??0,audioContextState:this.#e?.state||"unknown",bufferPoolStats:this.#i?.getStats(),bufferPoolGrowthStats:this.#i?.getGrowthStats(),loadedSynthDefsCount:this.loadedSynthDefs?.size||0,preschedulerCapacity:this.#t.preschedulerCapacity,audioHealthPct:this.#A?.update()??100,playbackStats:this.#_.playbackStats?this.#e?.playbackStats:null}}#W(){return this.#h.gatherMetrics(this.#Z())}#re(){this.#h.updateMergedArray(this.#Z())}#j(){if(this.#t.mode==="sab"){let t=this.#h.getMetricsView();return t?t[0]:null}let e=this.#h.getSnapshotBuffer();return e?new Uint32Array(e,0,1)[0]:null}#M(e="perform this operation"){if(!this.#d)throw new Error(`SuperSonic not initialized. Call init() before attempting to ${e}.`)}#ie(e){return e.includes("/")||e.includes("://")}#ne(e){if(e instanceof Uint8Array)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);throw new Error("oscData must be ArrayBuffer or Uint8Array")}#Q(e,t={}){let s=this.#w.classify(e);if(Z(s))this.#t.mode==="sab"?this.#w.send(e):this.#o.sendImmediate(e,s);else{let r=this.#h.bufferConstants,n=r?Math.min(r.IN_BUFFER_SIZE||1/0,r.scheduler_data_pool_size||1/0):1/0;if(e.length>n)throw new Error(`OSC bundle too large to schedule (${e.length} > ${n} bytes).`);this.#o.sendWithOptions(e,t)}}#oe(e,t){let s=(o,a)=>{let c=t[o];if(!Number.isFinite(c))throw new Error(a)},r=(o,a)=>{if(typeof t[o]!="string")throw new Error(a)},n=(o,a)=>{let c=t[o];if(!(c instanceof Uint8Array||c instanceof ArrayBuffer))throw new Error(a)};switch(e){case"/b_alloc":s(0,"/b_alloc requires a buffer number"),s(1,"/b_alloc requires a frame count");break;case"/b_allocRead":s(0,"/b_allocRead requires a buffer number"),r(1,"/b_allocRead requires a file path");break;case"/b_allocReadChannel":s(0,"/b_allocReadChannel requires a buffer number"),r(1,"/b_allocReadChannel requires a file path");break;case"/b_allocFile":s(0,"/b_allocFile requires a buffer number"),n(1,"/b_allocFile requires audio file data as blob");break}}#ae(e,t){this.#D=this.#D.then(async()=>{let s=[e,...t],{packet:r}=await this.#n.rewritePacket(s),n=i.osc.encodeMessage(r[0],r.slice(1));this.#Q(n)}).catch(s=>{console.error(`[SuperSonic] Buffer command ${e} failed:`,s),this.#f.emit("error",s)})}#ce(){return this.#D}},mn=Qe.osc;export{O as OscChannel,Qe as SuperSonic,mn as osc};
|
|
19
|
+
Consider using mode: 'postMessage' which doesn't require COOP/COEP headers.`),r}if(e!=="sab"&&e!=="postMessage")throw new Error(`Invalid mode: '${e}'. Use 'sab' or 'postMessage'.`)}#Y(){let e=this.#t.memory;if(this.#t.mode==="sab"){let s=U.totalPages,r=Math.max(Math.ceil(e.totalMemory/65536),s),n=Math.ceil(e.maxTotalMemory/65536);this.#c=new WebAssembly.Memory({initial:r,maximum:n,shared:!0})}else this.#c=null}#F(){this.#t.audioContext?this.#e=this.#t.audioContext:this.#e=new AudioContext(this.#t.audioContextOptions),this.#e.addEventListener("statechange",()=>{let e=this.#e?.state;if(!e)return;let t=this.#R;this.#R=e,e==="running"&&(t==="suspended"||t==="interrupted")&&this.#m?.resync(),this.#f.emit("audiocontext:statechange",{state:e}),e==="suspended"?(this.#f.emit("audiocontext:suspended"),this.#A?.reset()):e==="running"?(this.#f.emit("audiocontext:resumed"),this.#A?.reset()):e==="interrupted"&&(this.#f.emit("audiocontext:interrupted"),this.#A?.reset())}),this.#A=new ue({audioContext:this.#e})}#$(){let e=this.#t.mode==="sab"?this.#c.buffer:null;this.#i=new ee({mode:this.#t.mode,audioContext:this.#e,sharedBuffer:e,bufferPoolConfig:{start:this.#t.memory.bufferPoolOffset,size:this.#t.memory.bufferPoolSize,maxSize:this.#t.effectiveMaxBufferMemory},sampleBaseURL:this.#l,maxBuffers:this.#t.worldOptions.numBuffers,assetLoader:this.#_,wasmMemory:this.#c,maxBufferMemory:this.#t.effectiveMaxBufferMemory,bufferGrowIncrement:this.#t.bufferGrowIncrement,growFn:this.#t.mode==="postMessage"?t=>this.#te(t):null,onBufferPoolGrowth:t=>{this.#f.emit("buffer:pool:grown",t)}})}#v(){this.#n=new se({bufferManager:this.#i,getDefaultSampleRate:()=>this.#e?.sampleRate||44100})}async#V(){if(this.#B)return this.#B;let e=this.#t.wasmUrl.split("/").pop();if(this.#t.wasmBytes){let s=this.#t.wasmBytes;return this.#f.emit("loading:start",{type:"wasm",name:e,size:s.byteLength}),this.#f.emit("loading:complete",{type:"wasm",name:e,size:s.byteLength}),this.#B=s,s}let t=await this.#_.fetch(this.#t.wasmUrl,{type:"wasm",name:e});return this.#B=t,t}async#q(e){await st(this.#e.audioWorklet,this.#t.workletUrl);let t=this.#t.worldOptions.numOutputBusChannels;if(this.#s=new AudioWorkletNode(this.#e,"scsynth-processor",{numberOfInputs:1,numberOfOutputs:1,outputChannelCount:[t]}),this.#t.autoConnect){let o=this.#e.destination;t>2&&(o.channelCount=Math.min(t,o.maxChannelCount),o.channelInterpretation="discrete"),this.#s.connect(o)}this.#a=this.#J(),this.#s.port.start(),this.#se();let s=this.#t.mode,r=s==="sab"?this.#c.buffer:null;this.#s.port.postMessage({type:"init",mode:s,sharedBuffer:r,snapshotIntervalMs:this.#t.snapshotIntervalMs});let n={type:"loadWasm",wasmBytes:e,worldOptions:{...this.#t.worldOptions,rtPoolOffset:this.#t.memory.rtPoolOffset},sampleRate:this.#e.sampleRate};if(s==="sab")n.wasmMemory=this.#c;else{let o=U.totalPages;n.memoryPages=Math.max(Math.ceil(this.#t.memory.totalMemory/65536),o),n.maxMemoryPages=Math.ceil(this.#t.memory.maxTotalMemory/65536)}this.#s.port.postMessage(n),await this.#ee(),this.#i.setWorkletPort(this.#s.port)}#J(){let e=this.#s;return Object.freeze({connect:(...t)=>e.connect(...t),disconnect:(...t)=>e.disconnect(...t),get context(){return e.context},get numberOfOutputs(){return e.numberOfOutputs},get numberOfInputs(){return e.numberOfInputs},get channelCount(){return e.channelCount},get input(){return e}})}async#X(){let e=this.#t.mode,t=this.#h.bufferConstants,s=this.#h.ringBufferBase,r=this.#h.sharedBuffer,n={workerBaseURL:this.#t.workerBaseURL,preschedulerCapacity:this.#t.preschedulerCapacity,snapshotIntervalMs:this.#t.snapshotIntervalMs,bypassLookaheadS:this.#t.bypassLookaheadMs/1e3,getAudioContextTime:()=>this.#e?.currentTime??0,getNTPStartTime:()=>this.#m?.getNTPStartTime()??0};if(e==="sab"){if(n.sharedBuffer=r,n.ringBufferBase=s,n.bufferConstants=t,t?.NODE_ID_COUNTER_START!==void 0){let o=s+t.NODE_ID_COUNTER_START,a=new Int32Array(r,o,1);Atomics.store(a,0,1e3)}}else{this.#C=1e3,n.nodeIdSource=l=>{let f=this.#C;return this.#C+=l,{from:f,to:f+l}};let o=1e4,a=n.nodeIdSource(o),c=new MessageChannel,u=n.nodeIdSource;c.port1.onmessage=l=>{if(l.data.type==="requestNodeIdRange"){let f=u(o);c.port1.postMessage({type:"nodeIdRange",from:f.from,to:f.to})}},this.#s.port.postMessage({type:"nodeIdRange",from:a.from,to:a.to},[c.port2])}if(this.#o=lt(e,n),this.#o.onReply((o,a,c)=>{let u=Ke(o)||null;this.#f.emit("in:osc",{oscData:o,sequence:a,timestamp:c,scheduledTime:u});try{let l=V(o),f=l[0],h=l.slice(1);if(f==="/supersonic/buffer/freed")this.#i?.handleBufferFreed(h);else if(f==="/supersonic/buffer/allocated")this.#i?.handleBufferAllocated(h);else if(f==="/synced"&&h.length>0){let y=h[0];this.#u?.has(y)&&this.#u.get(y)(l)}if(this.#f.emit("in",l),this.#f.hasListeners("in:text")||this.#t.debug||this.#t.debugOscIn){let y=this.#t.activityEvent.oscInMaxLineLength??this.#t.activityEvent.maxLineLength,p=h.map(m=>ss(m,y)).join(", ")||"",d=`${f}${p?" "+p:""}`;this.#f.emit("in:text",{text:d,sequence:a,timestamp:c})}if(this.#f.hasListeners("in:html")){let y=je(l,a,c,this.initTime);this.#f.emit("in:html",{html:y,sequence:a,timestamp:c})}}catch(l){console.error("[SuperSonic] Failed to decode OSC message:",l)}}),this.#o.onDebug(o=>{let a=this.#t.activityEvent.scsynthMaxLineLength??this.#t.activityEvent.maxLineLength;a>0&&o.text?.length>a&&(o={...o,text:o.text.slice(0,a)+"..."}),this.#f.emit("debug",o)}),this.#o.onError((o,a)=>{console.error(`[SuperSonic] ${a} error:`,o),this.#f.emit("error",new Error(`${a}: ${o}`))}),this.#o.onOscLog(o=>{for(let a of o){let c=Ke(a.oscData)||null;if(this.#f.emit("out:osc",{oscData:a.oscData,sourceId:a.sourceId,sequence:a.sequence,timestamp:a.timestamp,scheduledTime:c}),this.#f.hasListeners("out")||this.#f.hasListeners("out:text")||this.#f.hasListeners("out:html")||this.#t.debug||this.#t.debugOscOut)try{let l=V(a.oscData);if(this.#f.emit("out",l),this.#f.hasListeners("out:text")||this.#t.debug||this.#t.debugOscOut){let f=this.#t.activityEvent.oscOutMaxLineLength??this.#t.activityEvent.maxLineLength,h=l[0],p=l.slice(1).map(m=>ss(m,f)).join(", "),d=`${h}${p?" "+p:""}`;this.#f.emit("out:text",{text:d,sequence:a.sequence,timestamp:a.timestamp})}if(this.#f.hasListeners("out:html")){let f=Yr(l,a.sequence,a.timestamp,this.initTime,a.sourceId);this.#f.emit("out:html",{html:f,sequence:a.sequence,timestamp:a.timestamp})}}catch{}}}),(this.#t.debug||this.#t.debugOscIn)&&this.on("in:text",({text:o})=>console.log(`[\u2190 OSC] ${o}`)),(this.#t.debug||this.#t.debugOscOut)&&this.on("out:text",({text:o})=>console.log(`[OSC \u2192] ${o}`)),(this.#t.debug||this.#t.debugScsynth)&&this.on("debug",o=>console.log(`[synth] ${o.text}`)),e==="sab")await this.#o.initialize();else{if(await this.#o.initialize(this.#s.port),this.#o.setBufferConstants(t),this.#O?.length>0)for(let o of this.#O)this.#o.handleDebugRaw(o);this.#P=o=>this.#o?.handleDebugRaw(o),this.#O=[]}this.#w=this.#o.createOscChannel({sourceId:0})}async#K(){this.#w&&this.#m&&(this.#w.getCurrentNTP=()=>this.#m.wallNow()),this.#d=!0,this.#E=!1,this.bootStats.initDuration=performance.now()-this.bootStats.initStartTime,await this.#f.emitAsync("setup"),this.#f.emit("ready",{capabilities:this.#g,bootStats:this.bootStats})}#ee(){return new Promise((e,t)=>{let s=setTimeout(()=>{t(new Error("AudioWorklet initialization timeout"))},vr),r=async n=>{if(n.data.type==="error"){clearTimeout(s),this.#s.port.removeEventListener("message",r),t(new Error(n.data.error||"AudioWorklet error"));return}if(n.data.type==="initialized")if(clearTimeout(s),this.#s.port.removeEventListener("message",r),n.data.success){let o=n.data.ringBufferBase??0,a=n.data.bufferConstants,c=this.#t.mode==="sab"?this.#c.buffer:null;this.#h.initSharedViews(c,o,a);let u=this.#t.worldOptions?.maxNodes??1024,l=a?.NODE_TREE_MIRROR_MAX_NODES??1024;u>l&&console.warn(`SuperSonic: maxNodes (${u}) exceeds NODE_TREE_MIRROR_MAX_NODES (${l}). The node tree mirror will not show all nodes. Rebuild with NODE_TREE_MIRROR_MAX_NODES=${u} to fix.`),this.#m=new le({mode:this.#t.mode,audioContext:this.#e,workletPort:this.#s.port}),this.#m.initSharedViews(c,o,a),await this.#m.initialize(),this.#m.startDriftTimer(),this.#t.mode==="sab"&&this.#b.update(c,o,a),this.#t.mode==="postMessage"&&n.data.initialSnapshot&&this.#h.updateSnapshot(n.data.initialSnapshot),e()}else t(new Error(n.data.error||"AudioWorklet initialization failed"))};this.#s.port.addEventListener("message",r),this.#s.port.start()})}#te(e){return new Promise(t=>{let s=crypto.randomUUID(),r=n=>{n.data.type==="memoryGrown"&&n.data.growId===s&&(this.#s.port.removeEventListener("message",r),t(n.data.success))};this.#s.port.addEventListener("message",r),this.#s.port.postMessage({type:"growMemory",growId:s,pages:e})})}#se(){this.#s.port.addEventListener("message",e=>{let{data:t}=e;switch(t.type){case"error":console.error("[Worklet] Error:",t.error),this.#f.emit("error",new Error(t.error));break;case"version":this.#T=t.version;break;case"snapshot":t.buffer&&(this.#h.updateSnapshot(t.buffer),this.#I=t.snapshotsSent);break;case"debugRawBatch":this.#P?this.#P(t):this.#O&&this.#O.push(t);break}})}#Z(){return{preschedulerMetrics:this.#o?.getPreschedulerMetrics(),transportMetrics:this.#o?.getMetrics(),driftOffsetMs:this.#m?.getDriftOffset()??0,ntpStartTime:this.#m?.getNTPStartTime()??0,clockOffsetMs:this.#m?.getClockOffset()??0,audioContextState:this.#e?.state||"unknown",bufferPoolStats:this.#i?.getStats(),bufferPoolGrowthStats:this.#i?.getGrowthStats(),loadedSynthDefsCount:this.loadedSynthDefs?.size||0,preschedulerCapacity:this.#t.preschedulerCapacity,audioHealthPct:this.#A?.update()??100,playbackStats:this.#g.playbackStats?this.#e?.playbackStats:null}}#W(){return this.#h.gatherMetrics(this.#Z())}#re(){this.#h.updateMergedArray(this.#Z())}#j(){if(this.#t.mode==="sab"){let t=this.#h.getMetricsView();return t?t[0]:null}let e=this.#h.getSnapshotBuffer();return e?new Uint32Array(e,0,1)[0]:null}#M(e="perform this operation"){if(!this.#d)throw new Error(`SuperSonic not initialized. Call init() before attempting to ${e}.`)}#ie(e){return e.includes("/")||e.includes("://")}#ne(e){if(e instanceof Uint8Array)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);throw new Error("oscData must be ArrayBuffer or Uint8Array")}#Q(e,t={}){let s=this.#w.classify(e);if(Z(s))this.#t.mode==="sab"?this.#w.send(e):this.#o.sendImmediate(e,s);else{let r=this.#h.bufferConstants,n=r?Math.min(r.IN_BUFFER_SIZE||1/0,r.scheduler_data_pool_size||1/0):1/0;if(e.length>n)throw new Error(`OSC bundle too large to schedule (${e.length} > ${n} bytes).`);this.#o.sendWithOptions(e,t)}}#oe(e,t){let s=(o,a)=>{let c=t[o];if(!Number.isFinite(c))throw new Error(a)},r=(o,a)=>{if(typeof t[o]!="string")throw new Error(a)},n=(o,a)=>{let c=t[o];if(!(c instanceof Uint8Array||c instanceof ArrayBuffer))throw new Error(a)};switch(e){case"/b_alloc":s(0,"/b_alloc requires a buffer number"),s(1,"/b_alloc requires a frame count");break;case"/b_allocRead":s(0,"/b_allocRead requires a buffer number"),r(1,"/b_allocRead requires a file path");break;case"/b_allocReadChannel":s(0,"/b_allocReadChannel requires a buffer number"),r(1,"/b_allocReadChannel requires a file path");break;case"/b_allocFile":s(0,"/b_allocFile requires a buffer number"),n(1,"/b_allocFile requires audio file data as blob");break}}#ae(e,t){this.#D=this.#D.then(async()=>{let s=[e,...t],{packet:r}=await this.#n.rewritePacket(s),n=i.osc.encodeMessage(r[0],r.slice(1));this.#Q(n)}).catch(s=>{console.error(`[SuperSonic] Buffer command ${e} failed:`,s),this.#f.emit("error",s)})}#ce(){return this.#D}},mn=Qe.osc;export{O as OscChannel,Qe as SuperSonic,mn as osc};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(()=>{function L({uint8View:
|
|
2
|
-
`)&&(A=A.slice(0,-1)),A}function
|
|
3
|
-
`)&&(t=t.slice(0,-1)),o.push({text:t,timestamp:performance.now(),sequence:c.sequence})}catch(t){console.error("[DebugWorker] Failed to decode message:",t)}o.length>0&&self.postMessage({type:"debug",messages:o})}x({name:"DebugWorker",calculateControlIndices:N,headIndex:
|
|
1
|
+
(()=>{function L({uint8View:s,dataView:o,bufferStart:c,bufferSize:t,head:A,tail:T,messageMagic:C,paddingMagic:R,headerSize:i,maxMessages:U=1/0,onMessage:e,onCorruption:S}){let E=T,I=0,a=D=>{let r=D;if(r+4<=t)return o.getUint32(c+r,!0);let _=0;for(let n=0;n<4;n++)_|=s[c+(r+n)%t]<<n*8;return _};for(;E!==A&&I<U;){let D=t-E,r;if(D>=4?r=o.getUint32(c+E,!0):r=a(E),r===R){E=0;continue}if(r!==C){S&&S(E),E=(E+1)%t;continue}let _=a((E+4)%t),n=a((E+8)%t),p=a((E+12)%t);if(_<i||_>t){S&&S(E),E=(E+1)%t;continue}let l=_-i,u=c+(E+i)%t;e(u,l,n,p),E=(E+_)%t,I++}return{newTail:E,messagesRead:I}}function N(s,o){let c=s+o;return{DEBUG_HEAD:(c+16)/4,DEBUG_TAIL:(c+20)/4}}function x(s){let{name:o,calculateControlIndices:c,headIndex:t,tailIndex:A,readMessages:T,postResults:C,initMetrics:R=!0,onInit:i,extraHandlers:U}=s,e={sharedBuffer:null,ringBufferBase:null,bufferConstants:null,atomicView:null,dataView:null,uint8View:null,metricsView:null,CONTROL_INDICES:{}},S=!1;function E(r,_,n){if(e.sharedBuffer=r,e.ringBufferBase=_,e.bufferConstants=n,e.atomicView=new Int32Array(r),e.dataView=new DataView(r),e.uint8View=new Uint8Array(r),e.CONTROL_INDICES=c(_,n.CONTROL_START),R){let p=_+n.METRICS_START;e.metricsView=new Uint32Array(r,p,n.METRICS_SIZE/4)}i?.(e)}function I(){let r=t(e.CONTROL_INDICES),_=A(e.CONTROL_INDICES);for(;S;)try{let n=Atomics.load(e.atomicView,r),p=Atomics.load(e.atomicView,_);n===p&&Atomics.wait(e.atomicView,r,n);let l=T(e);l&&l.length>0&&C(l)}catch(n){console.error(`[${o}] Error in wait loop:`,n),self.postMessage({type:"error",error:n.message}),Atomics.wait(e.atomicView,0,e.atomicView[0],10)}}function a(){if(!e.sharedBuffer){console.error(`[${o}] Cannot start - not initialized`);return}S||(S=!0,I())}function D(){S=!1}self.addEventListener("message",r=>{let{data:_}=r;try{if(U?.[_.type]){U[_.type](_,e);return}switch(_.type){case"init":_.sharedBuffer&&E(_.sharedBuffer,_.ringBufferBase,_.bufferConstants),self.postMessage({type:"initialized"});break;case"start":e.sharedBuffer&&a();break;case"stop":D();break;default:}}catch(n){console.error(`[${o}] Error:`,n),self.postMessage({type:"error",error:n.message})}})}var O=new TextDecoder("utf-8");function H(s,o,c){let t=new Uint8Array(c);for(let T=0;T<c;T++)t[T]=s[o+T];let A=O.decode(t);return A.endsWith(`
|
|
2
|
+
`)&&(A=A.slice(0,-1)),A}function d(s){let{atomicView:o,uint8View:c,dataView:t,ringBufferBase:A,bufferConstants:T,metricsView:C,CONTROL_INDICES:R}=s,i=Atomics.load(o,R.DEBUG_HEAD),U=Atomics.load(o,R.DEBUG_TAIL);if(i===U)return[];let e=[],{newTail:S,messagesRead:E}=L({uint8View:c,dataView:t,bufferStart:A+T.DEBUG_BUFFER_START,bufferSize:T.DEBUG_BUFFER_SIZE,head:i,tail:U,messageMagic:T.MESSAGE_MAGIC,paddingMagic:T.PADDING_MAGIC,headerSize:T.MESSAGE_HEADER_SIZE,maxMessages:1e3,onMessage:(I,a,D)=>{e.push({text:H(c,I,a),timestamp:performance.now(),sequence:D}),C&&(Atomics.add(C,30,1),Atomics.add(C,31,a))},onCorruption:I=>{console.error("[DebugWorker] Corrupted message at position",I)}});return E>0&&Atomics.store(o,R.DEBUG_TAIL,S),e}function M(s){let o=[];for(let c of s)try{let t=O.decode(new Uint8Array(c.bytes));t.endsWith(`
|
|
3
|
+
`)&&(t=t.slice(0,-1)),o.push({text:t,timestamp:performance.now(),sequence:c.sequence})}catch(t){console.error("[DebugWorker] Failed to decode message:",t)}o.length>0&&self.postMessage({type:"debug",messages:o})}x({name:"DebugWorker",calculateControlIndices:N,headIndex:s=>s.DEBUG_HEAD,tailIndex:s=>s.DEBUG_TAIL,readMessages:d,postResults:s=>self.postMessage({type:"debug",messages:s}),extraHandlers:{clear:(s,o)=>{o.sharedBuffer&&(Atomics.store(o.atomicView,o.CONTROL_INDICES.DEBUG_HEAD,0),Atomics.store(o.atomicView,o.CONTROL_INDICES.DEBUG_TAIL,0))},debugRaw:s=>{s.messages&&M(s.messages)}}});})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function
|
|
1
|
+
(()=>{function u(E,e,s){return(s-1-E+e)%s}function D({uint8View:E,dataView:e,bufferStart:s,bufferSize:_,head:A,payload:a,sequence:l,messageMagic:U,headerSize:I,sourceId:L=0,headerScratch:r=null,headerScratchView:p=null}){let c=a.length,C=I+c+3&-4,i=_-A;if(C>i){let o=r||new Uint8Array(I),n=p||new DataView(o.buffer);n.setUint32(0,U,!0),n.setUint32(4,C,!0),n.setUint32(8,l,!0),n.setUint32(12,L,!0);let t=s+A,S=s;if(i>=I){E.set(o,t);let R=i-I;for(let T=0;T<R;T++)E[t+I+T]=a[T];for(let T=R;T<c;T++)E[S+T-R]=a[T]}else{for(let T=0;T<i;T++)E[t+T]=o[T];for(let T=i;T<I;T++)E[S+T-i]=o[T];let R=I-i;E.set(a,S+R)}}else{let o=s+A;e.setUint32(o,U,!0),e.setUint32(o+4,C,!0),e.setUint32(o+8,l,!0),e.setUint32(o+12,L,!0),E.set(a,o+I)}return(A+C)%_}function d({uint8View:E,dataView:e,bufferStart:s,bufferSize:_,head:A,tail:a,messageMagic:l,paddingMagic:U,headerSize:I,maxMessages:L=1/0,onMessage:r,onCorruption:p}){let c=a,N=0,C=i=>{let o=i;if(o+4<=_)return e.getUint32(s+o,!0);let n=0;for(let t=0;t<4;t++)n|=E[s+(o+t)%_]<<t*8;return n};for(;c!==A&&N<L;){let i=_-c,o;if(i>=4?o=e.getUint32(s+c,!0):o=C(c),o===U){c=0;continue}if(o!==l){p&&p(c),c=(c+1)%_;continue}let n=C((c+4)%_),t=C((c+8)%_),S=C((c+12)%_);if(n<I||n>_){p&&p(c),c=(c+1)%_;continue}let R=n-I,T=s+(c+I)%_;r(T,R,t,S),c=(c+n)%_,N++}return{newTail:c,messagesRead:N}}function P(E,e,s,_){let A=E+e+_*s;return{controlBase:A,headIndex:(A+0)/4,tailIndex:(A+4)/4,activeIndex:(A+8)/4,dropsIndex:(A+12)/4}}function B(E,e){let s=E+e;return{OUT_HEAD:(s+8)/4,OUT_TAIL:(s+12)/4}}function H(){return(performance.timeOrigin+performance.now())/1e3+2208988800}function F(E){let{name:e,calculateControlIndices:s,headIndex:_,tailIndex:A,readMessages:a,postResults:l,initMetrics:U=!0,onInit:I,extraHandlers:L}=E,r={sharedBuffer:null,ringBufferBase:null,bufferConstants:null,atomicView:null,dataView:null,uint8View:null,metricsView:null,CONTROL_INDICES:{}},p=!1;function c(o,n,t){if(r.sharedBuffer=o,r.ringBufferBase=n,r.bufferConstants=t,r.atomicView=new Int32Array(o),r.dataView=new DataView(o),r.uint8View=new Uint8Array(o),r.CONTROL_INDICES=s(n,t.CONTROL_START),U){let S=n+t.METRICS_START;r.metricsView=new Uint32Array(o,S,t.METRICS_SIZE/4)}I?.(r)}function N(){let o=_(r.CONTROL_INDICES),n=A(r.CONTROL_INDICES);for(;p;)try{let t=Atomics.load(r.atomicView,o),S=Atomics.load(r.atomicView,n);t===S&&Atomics.wait(r.atomicView,o,t);let R=a(r);R&&R.length>0&&l(R)}catch(t){console.error(`[${e}] Error in wait loop:`,t),self.postMessage({type:"error",error:t.message}),Atomics.wait(r.atomicView,0,r.atomicView[0],10)}}function C(){if(!r.sharedBuffer){console.error(`[${e}] Cannot start - not initialized`);return}p||(p=!0,N())}function i(){p=!1}self.addEventListener("message",o=>{let{data:n}=o;try{if(L?.[n.type]){L[n.type](n,r);return}switch(n.type){case"init":n.sharedBuffer&&c(n.sharedBuffer,n.ringBufferBase,n.bufferConstants),self.postMessage({type:"initialized"});break;case"start":r.sharedBuffer&&C();break;case"stop":i();break;default:}}catch(t){console.error(`[${e}] Error:`,t),self.postMessage({type:"error",error:t.message})}})}var f=-1,x=null,O=null,M=null;function K(E){let{atomicView:e,uint8View:s,dataView:_,ringBufferBase:A,bufferConstants:a,metricsView:l,CONTROL_INDICES:U}=E,I=Atomics.load(e,U.OUT_HEAD),L=Atomics.load(e,U.OUT_TAIL);if(I===L)return[];let r=[],{newTail:p,messagesRead:c}=d({uint8View:s,dataView:_,bufferStart:A+a.OUT_BUFFER_START,bufferSize:a.OUT_BUFFER_SIZE,head:I,tail:L,messageMagic:a.MESSAGE_MAGIC,paddingMagic:a.PADDING_MAGIC,headerSize:a.MESSAGE_HEADER_SIZE,maxMessages:100,onMessage:(N,C,i,o)=>{if(f>=0){let t=f+1&4294967295;if(i!==t){let S=i-t+4294967296&4294967295;S<1e3&&(console.error("[OSCInWorker] Detected",S,"dropped messages (expected seq",t,"got",i,")"),l&&Atomics.add(l,28,S))}}f=i;let n=new Uint8Array(C);for(let t=0;t<C;t++)n[t]=s[N+t];if(r.push({oscData:n,sequence:i,timestamp:H()}),x)for(let t=0;t<x.length;t++){let S=x[t];if(Atomics.load(e,S.activeIndex)!==1)continue;let R=Atomics.load(e,S.headIndex),T=Atomics.load(e,S.tailIndex),g=u(R,T,S.bufferSize);if((a.MESSAGE_HEADER_SIZE+C+3&-4)>g){Atomics.add(e,S.dropsIndex,1);continue}let G=D({uint8View:s,dataView:_,bufferStart:S.bufferStart,bufferSize:S.bufferSize,head:R,payload:n,sequence:i,messageMagic:a.MESSAGE_MAGIC,headerSize:a.MESSAGE_HEADER_SIZE,headerScratch:O,headerScratchView:M});Atomics.store(e,S.headIndex,G),Atomics.notify(e,S.headIndex)}l&&(Atomics.add(l,26,1),Atomics.add(l,27,C))},onCorruption:N=>{console.error("[OSCInWorker] Corrupted message at position",N),l&&(Atomics.add(l,28,1),Atomics.add(l,29,1))}});return c>0&&Atomics.store(e,U.OUT_TAIL,p),r}F({name:"OSCInWorker",calculateControlIndices:B,headIndex:E=>E.OUT_HEAD,tailIndex:E=>E.OUT_TAIL,readMessages:K,postResults:E=>self.postMessage({type:"messages",messages:E}),onInit:E=>{let e=E.bufferConstants;if(!e.REPLY_CHANNEL_COUNT)return;O=new Uint8Array(e.MESSAGE_HEADER_SIZE),M=new DataView(O.buffer);let s=E.ringBufferBase;x=[];for(let _=0;_<e.REPLY_CHANNEL_COUNT;_++){let A=P(s,e.REPLY_CHANNELS_CONTROL_START,e.REPLY_CHANNEL_CONTROL_SIZE,_);x.push({bufferStart:s+e.REPLY_CHANNELS_BUFFER_START+_*e.REPLY_CHANNEL_BUFFER_SIZE,bufferSize:e.REPLY_CHANNEL_BUFFER_SIZE,headIndex:A.headIndex,tailIndex:A.tailIndex,activeIndex:A.activeIndex,dropsIndex:A.dropsIndex})}}});})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function Ce(t,e,n){return(n-1-t+e)%n}function Ie({uint8View:t,dataView:e,bufferStart:n,bufferSize:s,head:r,payload:o,sequence:u,messageMagic:p,headerSize:c,sourceId:T=0,headerScratch:X=null,headerScratchView:z=null}){let B=o.length,R=c+B+3&-4,h=s-r;if(R>h){let S=X||new Uint8Array(c),L=z||new DataView(S.buffer);L.setUint32(0,p,!0),L.setUint32(4,R,!0),L.setUint32(8,u,!0),L.setUint32(12,T,!0);let P=n+r,O=n;if(h>=c){t.set(S,P);let y=h-c;for(let l=0;l<y;l++)t[P+c+l]=o[l];for(let l=y;l<B;l++)t[O+l-y]=o[l]}else{for(let l=0;l<h;l++)t[P+l]=S[l];for(let l=h;l<c;l++)t[O+l-h]=S[l];let y=c-h;t.set(o,O+y)}}else{let S=n+r;e.setUint32(S,p,!0),e.setUint32(S+4,R,!0),e.setUint32(S+8,u,!0),e.setUint32(S+12,T,!0),t.set(o,S+c)}return(r+R)%s}function De(t,e,n=0,s=!1){for(let r=0;r<=n;r++)if(Atomics.compareExchange(t,e,0,1)===0)return!0;if(s){for(let o=0;o<100;o++)if(Atomics.wait(t,e,1,100),Atomics.compareExchange(t,e,0,1)===0)return!0;return console.error("[RingBuffer] Lock acquisition timeout after 10s - possible deadlock"),!1}return!1}function xe(t,e){Atomics.store(t,e,0),Atomics.notify(t,e,1)}function ne({atomicView:t,dataView:e,uint8View:n,bufferConstants:s,ringBufferBase:r,controlIndices:o,oscMessage:u,sourceId:p=0,maxSpins:c=0,useWait:T=!1,headerScratch:X=null,headerScratchView:z=null}){let B=u.length,v=s.MESSAGE_HEADER_SIZE+B;if(v>s.IN_BUFFER_SIZE-s.MESSAGE_HEADER_SIZE||!De(t,o.IN_WRITE_LOCK,c,T))return!1;try{let R=Atomics.load(t,o.IN_HEAD),h=Atomics.load(t,o.IN_TAIL),S=v+3&-4;if(Ce(R,h,s.IN_BUFFER_SIZE)<S)return!1;let P=Atomics.add(t,o.IN_SEQUENCE,1),O=Ie({uint8View:n,dataView:e,bufferStart:r+s.IN_BUFFER_START,bufferSize:s.IN_BUFFER_SIZE,head:R,payload:u,sequence:P,messageMagic:s.MESSAGE_MAGIC,headerSize:s.MESSAGE_HEADER_SIZE,sourceId:p,headerScratch:X,headerScratchView:z});return Atomics.load(t,o.IN_HEAD),Atomics.store(t,o.IN_HEAD,O),Atomics.notify(t,o.IN_HEAD,1),!0}finally{xe(t,o.IN_WRITE_LOCK)}}function se(t,e){let n=t+e;return{IN_HEAD:(n+0)/4,IN_TAIL:(n+4)/4,IN_SEQUENCE:(n+24)/4,IN_WRITE_LOCK:(n+40)/4,IN_LOG_TAIL:(n+44)/4}}function re(t){return t.length>=8&&t[0]===35&&t[1]===98&&t[2]===117&&t[3]===110&&t[4]===100&&t[5]===108&&t[6]===101&&t[7]===0}function oe(){return(performance.timeOrigin+performance.now())/1e3+2208988800}var Le=new Uint8Array(2097152),Je=new DataView(Le.buffer);var je=new TextDecoder,et=new TextEncoder;var Pe=4294967296,tt=new Uint8Array([35,98,117,110,100,108,101,0]);function Oe(t){return!t||t.length<8?!1:t[0]===35&&t[1]===98}function ie(t){if(!Oe(t))return null;let e=new DataView(t.buffer,t.byteOffset,t.byteLength),n=e.getUint32(8,!1),s=e.getUint32(12,!1);return n+s/Pe}var M=class{constructor({lookaheadS:e=.5,maxPending:n=1e3,maxFutureS:s=3600,poolBytes:r=524288}={}){this.lookaheadS=e,this.maxPending=n,this.maxFutureS=s,this.poolBytes=r,this._heap=[],this._seq=0,this.retryCount=0}size(){return this._heap.length}schedule(e,n){if(this._heap.length+this.retryCount>=this.maxPending)return{ok:!1,reason:"queue_full"};if(e.ntpTime==null)return{ok:!0,immediate:e};if((e.bytes||0)>this.poolBytes)return{ok:!1,reason:"too_large"};if(e.ntpTime-n>this.maxFutureS)return{ok:!1,reason:"too_far_future"};let r={ntpTime:e.ntpTime,seq:this._seq++,sessionId:e.sessionId||0,runTag:e.runTag||"",payload:e.payload};return this._push(r),{ok:!0,scheduled:r}}nextDueTime(){return this._heap.length?this._heap[0].ntpTime-this.lookaheadS:null}dispatchDue(e,n){let s=e+this.lookaheadS,r=0;for(;this._heap.length&&this._heap[0].ntpTime<=s;)n(this._pop()),r++;return r}cancelBy(e){if(this._heap.length===0)return 0;let n=this._heap.length;this._heap=this._heap.filter(r=>!e(r));let s=n-this._heap.length;return s>0&&this._heapify(),s}cancelTag(e){return this.cancelBy(n=>n.runTag===e)}cancelSession(e){return this.cancelBy(n=>n.sessionId===e)}cancelSessionTag(e,n){return this.cancelBy(s=>s.sessionId===e&&s.runTag===n)}cancelAll(){let e=this._heap.length;return this._heap=[],e}_cmp(e,n){return e.ntpTime===n.ntpTime?e.seq-n.seq:e.ntpTime-n.ntpTime}_swap(e,n){let s=this._heap[e];this._heap[e]=this._heap[n],this._heap[n]=s}_push(e){this._heap.push(e),this._siftUp(this._heap.length-1)}_pop(){let e=this._heap[0],n=this._heap.pop();return this._heap.length&&(this._heap[0]=n,this._siftDown(0)),e}_siftUp(e){for(;e>0;){let n=e-1>>1;if(this._cmp(this._heap[e],this._heap[n])>=0)break;this._swap(e,n),e=n}}_siftDown(e){let n=this._heap.length;for(;;){let s=2*e+1,r=2*e+2,o=e;if(s<n&&this._cmp(this._heap[s],this._heap[o])<0&&(o=s),r<n&&this._cmp(this._heap[r],this._heap[o])<0&&(o=r),o===e)break;this._swap(e,o),e=o}}_heapify(){for(let e=(this._heap.length>>1)-1;e>=0;e--)this._siftDown(e)}};var A="sab",Z=null,H=524288,Fe=65536,Te=3600,he=4294967295,C=null,w=null,_=null,g=null,Ae=null,de=null,q=null,pe=null,b={},a=null,k=null,ue=null,V=150,I=(t,e)=>{a&&(A==="sab"?Atomics.store(a,t,e):a[t]=e)},j=t=>a?A==="sab"?Atomics.load(a,t):a[t]:0,d=(t,e)=>{a&&(A==="sab"?Atomics.add(a,t,e):a[t]+=e)},G=I,_e=j,He=()=>{if(A!=="postMessage"||ue!==null)return;let t=()=>{k&&a&&self.postMessage({type:"preschedulerMetrics",metrics:new Uint32Array(k.slice(0))}),ue=setTimeout(t,V)};t(),f("[PreScheduler] Started metrics sending (every "+V+"ms)")};var U=null,F=1/0,ae=!1,E=[],Q=!1,D=65536,$=.5,i=new M({lookaheadS:$,maxPending:D,maxFutureS:Te,poolBytes:H}),f=(...t)=>{},ee=oe,we=t=>ie(t),be=()=>{if(!C||!_){console.error("[PreScheduler] Cannot init - missing buffer or constants");return}g=new Int32Array(C),Ae=new DataView(C),de=new Uint8Array(C);let t=_.MESSAGE_HEADER_SIZE||16;q=new Uint8Array(t),pe=new DataView(q.buffer),b=se(w,_.CONTROL_START);let e=w+_.METRICS_START;a=new Uint32Array(C,e,_.METRICS_SIZE/4),f("[PreScheduler] SharedArrayBuffer initialized with direct ring buffer writing and metrics")},Y=()=>{if(!a)return;I(9,i.size());let t=i.size(),e=j(10);t>e&&I(10,t)},x=(t,e,n=0,s=!1)=>{if(A==="postMessage")return Z?(Z.postMessage({type:"osc",oscData:t,sourceId:n}),d(12,1),!0):(console.error("[PreScheduler] No worklet port available"),!1);if(!C||!g)return console.error("[PreScheduler] Not initialized for ring buffer writing"),!1;let r=t.length,o=_.MESSAGE_HEADER_SIZE+r;return o>_.IN_BUFFER_SIZE-_.MESSAGE_HEADER_SIZE?(console.error("[PreScheduler] Message too large:",o),!1):ne({atomicView:g,dataView:Ae,uint8View:de,bufferConstants:_,ringBufferBase:w,controlIndices:b,oscMessage:t,sourceId:n,maxSpins:10,useWait:s,headerScratch:q,headerScratchView:pe})?(d(12,1),!0):!1},m=(t,e,n=0)=>{let s=i.size()+E.length;if(s>=D){console.error("[PreScheduler] Backpressure: dropping retry ("+s+" pending)"),d(17,1);return}E.push({oscData:t,context:e||"unknown",queuedAt:performance.now(),sourceId:n}),I(18,E.length);let r=j(19);E.length>r&&I(19,E.length),f("[PreScheduler] Queued message for retry:",e,"queue size:",E.length),Ue()},Ue=()=>{if(Q||E.length===0||A!=="sab")return;Q=!0;let t=Atomics.load(g,b.IN_TAIL),e=Atomics.waitAsync(g,b.IN_TAIL,t),n=()=>{Q=!1,ke(),E.length>0&&Ue()};e.async?e.value.then(n):queueMicrotask(n)},ke=()=>{if(E.length===0)return;let t=0;for(let e=0;e<E.length;e++){let n=E[e];if(x(n.oscData,!0,n.sourceId,!0))t++,d(16,1);else break}t>0&&(E.splice(0,t),I(18,E.length))},fe=(t,e,n,s=0)=>{let r=we(t),o=ee();i.retryCount=E.length;let u=i.schedule({ntpTime:r,bytes:t.length,sessionId:e,runTag:n,payload:{oscData:t,sourceId:s}},o);if(!u.ok){let[p,c]={queue_full:["PRESCHEDULER_QUEUE_FULL",`Prescheduler queue full (${i.size()+E.length} >= ${D} max)`],too_large:["BUNDLE_TOO_LARGE",`Bundle too large for scheduler pool (${t.length} > ${H} bytes)`],too_far_future:["BUNDLE_TOO_FAR_FUTURE",`Bundle scheduled too far in future (${(r-o).toFixed(0)}s > ${Te}s max)`]}[u.reason];return console.error("[PreScheduler]",c),self.postMessage({type:"error",error:c,code:p}),!1}return u.immediate?(f("[PreScheduler] Non-bundle message, dispatching immediately"),x(t,!1,s,!0)||m(t,"immediate message",s),!0):(d(11,1),Y(),f("[PreScheduler] Scheduled bundle:","NTP="+r.toFixed(3),"current="+o.toFixed(3),"wait="+((r-o)*1e3).toFixed(1)+"ms","pending="+i.size()),N(),!0)},N=()=>{let t=i.nextDueTime();if(t===null){U!==null&&(clearTimeout(U),U=null,F=1/0);return}if(t<F){U!==null&&clearTimeout(U);let e=Math.max(0,(t-ee())*1e3);F=t,U=setTimeout(Ye,e)}},Ge=()=>{U===null&&(f("[PreScheduler] Starting demand-driven dispatching"),N())};var Ye=()=>{ae=!0;let t=ee(),e=0,n=s=>{Y();let{oscData:r,sourceId:o}=s.payload,u=s.ntpTime-t;if(d(21,1),u<0){let c=Math.round(-u*1e3);d(15,1);let T=_e(23);c>T&&G(23,c)}else{let c=Math.round(u*1e3),T=_e(14);(T===he||c<T)&&G(14,c)}f("[PreScheduler] Dispatching bundle:","NTP="+s.ntpTime.toFixed(3),"current="+t.toFixed(3),"early="+(u*1e3).toFixed(1)+"ms","remaining="+i.size()),x(r,!1,o,!0)||m(r,"scheduled bundle NTP="+s.ntpTime.toFixed(3),o),e++};i.dispatchDue(t,n),(e>0||i.size()>0||E.length>0)&&f("[PreScheduler] Dispatch cycle complete:","dispatched="+e,"pending="+i.size(),"retrying="+E.length),ae=!1,U=null,F=1/0,N()},te=t=>{t>0&&(d(13,t),Y(),f("[PreScheduler] Cancelled "+t+" events, "+i.size()+" remaining"),N())},Xe=(t,e)=>te(i.cancelSessionTag(t,e)),ze=t=>te(i.cancelSession(t)),ve=t=>te(i.cancelTag(t)),Qe=()=>{let t=i.cancelAll(),e=E.length;t===0&&e===0||(d(13,t+e),E=[],I(18,0),Y(),f("[PreScheduler] Cancelled all "+t+" events, "+e+" retries"),N())},Ke=re,We=t=>{let e=[],n=new DataView(t.buffer,t.byteOffset,t.byteLength),s=16;for(;s+4<=t.length;){let r=n.getInt32(s,!1);if(s+=4,r<=0||r>Fe||s+r>t.length)break;let o=t.slice(s,s+r);for(e.push(o),s+=r;s%4!==0&&s<t.length;)s++}return e},Ze=(t,e=0)=>{if(Ke(t)){let n=We(t);for(let s=0;s<n.length;s++)x(n[s],!1,e,!0)||m(n[s],"immediate bundle message "+s,e)}else x(t,!1,e,!0)||m(t,"immediate message",e)};self.addEventListener("message",t=>{let{data:e}=t;try{switch(e.type){case"init":if(A=e.mode||"sab",e.maxPendingMessages&&(D=e.maxPendingMessages),e.snapshotIntervalMs&&(V=e.snapshotIntervalMs),e.bypassLookaheadS!==void 0&&($=e.bypassLookaheadS),A==="sab")C=e.sharedBuffer,w=e.ringBufferBase,_=e.bufferConstants,be(),_&&_.scheduler_data_pool_size&&(H=_.scheduler_data_pool_size);else{Z=e.workletPort;let s=184;k=new ArrayBuffer(s),a=new Uint32Array(k),He()}G(14,he),G(23,0),i.maxPending=D,i.lookaheadS=$,i.poolBytes=H,Ge(),f("[OSCPreSchedulerWorker] Initialized with NTP-based scheduling, mode="+A+", capacity="+D),self.postMessage({type:"initialized"});break;case"addOscSource":let n=t.ports[0];n&&(n.onmessage=s=>{s.data.type==="osc"&&s.data.oscData&&fe(s.data.oscData,0,"",s.data.sourceId||0)},f("[OSCPreSchedulerWorker] Added external OSC source"));break;case"send":fe(e.oscData,e.sessionId||0,e.runTag||"",e.sourceId||0);break;case"sendImmediate":Ze(e.oscData,e.sourceId||0);break;case"directDispatch":x(e.oscData,!1,e.sourceId||0,!0)||m(e.oscData,"directDispatch fallback",e.sourceId||0);break;case"cancelSessionTag":e.runTag!==void 0&&e.runTag!==null&&e.runTag!==""&&Xe(e.sessionId||0,e.runTag);break;case"cancelSession":ze(e.sessionId||0);break;case"cancelTag":e.runTag!==void 0&&e.runTag!==null&&e.runTag!==""&&ve(e.runTag);break;case"cancelAll":Qe(),e.ack&&self.postMessage({type:"cancelAllAck"});break;default:}}catch(n){console.error("[OSCPreSchedulerWorker] Error:",n),self.postMessage({type:"error",error:n.message})}});f("[OSCPreSchedulerWorker] Script loaded");})();
|
|
1
|
+
(()=>{function Ce(t,e,n){return(n-1-t+e)%n}function Ie({uint8View:t,dataView:e,bufferStart:n,bufferSize:s,head:r,payload:o,sequence:_,messageMagic:d,headerSize:i,sourceId:T=0,headerScratch:X=null,headerScratchView:K=null}){let M=o.length,R=i+M+3&-4,A=s-r;if(R>A){let S=X||new Uint8Array(i),L=K||new DataView(S.buffer);L.setUint32(0,d,!0),L.setUint32(4,R,!0),L.setUint32(8,_,!0),L.setUint32(12,T,!0);let P=n+r,O=n;if(A>=i){t.set(S,P);let N=A-i;for(let l=0;l<N;l++)t[P+i+l]=o[l];for(let l=N;l<M;l++)t[O+l-N]=o[l]}else{for(let l=0;l<A;l++)t[P+l]=S[l];for(let l=A;l<i;l++)t[O+l-A]=S[l];let N=i-A;t.set(o,O+N)}}else{let S=n+r;e.setUint32(S,d,!0),e.setUint32(S+4,R,!0),e.setUint32(S+8,_,!0),e.setUint32(S+12,T,!0),t.set(o,S+i)}return(r+R)%s}function De(t,e,n=0,s=!1){for(let r=0;r<=n;r++)if(Atomics.compareExchange(t,e,0,1)===0)return!0;if(s){for(let o=0;o<100;o++)if(Atomics.wait(t,e,1,100),Atomics.compareExchange(t,e,0,1)===0)return!0;return console.error("[RingBuffer] Lock acquisition timeout after 10s - possible deadlock"),!1}return!1}function xe(t,e){Atomics.store(t,e,0),Atomics.notify(t,e,1)}function ne({atomicView:t,dataView:e,uint8View:n,bufferConstants:s,ringBufferBase:r,controlIndices:o,oscMessage:_,sourceId:d=0,maxSpins:i=0,useWait:T=!1,headerScratch:X=null,headerScratchView:K=null}){let M=_.length,z=s.MESSAGE_HEADER_SIZE+M;if(z>s.IN_BUFFER_SIZE-s.MESSAGE_HEADER_SIZE||!De(t,o.IN_WRITE_LOCK,i,T))return!1;try{let R=Atomics.load(t,o.IN_HEAD),A=Atomics.load(t,o.IN_TAIL),S=z+3&-4;if(Ce(R,A,s.IN_BUFFER_SIZE)<S)return!1;let P=Atomics.add(t,o.IN_SEQUENCE,1),O=Ie({uint8View:n,dataView:e,bufferStart:r+s.IN_BUFFER_START,bufferSize:s.IN_BUFFER_SIZE,head:R,payload:_,sequence:P,messageMagic:s.MESSAGE_MAGIC,headerSize:s.MESSAGE_HEADER_SIZE,sourceId:d,headerScratch:X,headerScratchView:K});return Atomics.load(t,o.IN_HEAD),Atomics.store(t,o.IN_HEAD,O),Atomics.notify(t,o.IN_HEAD,1),!0}finally{xe(t,o.IN_WRITE_LOCK)}}function se(t,e){let n=t+e;return{IN_HEAD:(n+0)/4,IN_TAIL:(n+4)/4,IN_SEQUENCE:(n+24)/4,IN_WRITE_LOCK:(n+40)/4,IN_LOG_TAIL:(n+44)/4}}function re(t){return t.length>=8&&t[0]===35&&t[1]===98&&t[2]===117&&t[3]===110&&t[4]===100&&t[5]===108&&t[6]===101&&t[7]===0}function oe(){return(performance.timeOrigin+performance.now())/1e3+2208988800}var Le=new Uint8Array(2097152),Je=new DataView(Le.buffer);var je=new TextDecoder,et=new TextEncoder;var Pe=4294967296,tt=new Uint8Array([35,98,117,110,100,108,101,0]);function Oe(t){return!t||t.length<8?!1:t[0]===35&&t[1]===98}function ce(t){if(!Oe(t))return null;let e=new DataView(t.buffer,t.byteOffset,t.byteLength),n=e.getUint32(8,!1),s=e.getUint32(12,!1);return n+s/Pe}var B=class{constructor({lookaheadS:e=.5,maxPending:n=1e3,maxFutureS:s=3600,poolBytes:r=524288}={}){this.lookaheadS=e,this.maxPending=n,this.maxFutureS=s,this.poolBytes=r,this._heap=[],this._seq=0,this.retryCount=0}size(){return this._heap.length}schedule(e,n){if(this._heap.length+this.retryCount>=this.maxPending)return{ok:!1,reason:"queue_full"};if(e.ntpTime==null)return{ok:!0,immediate:e};if((e.bytes||0)>this.poolBytes)return{ok:!1,reason:"too_large"};if(e.ntpTime-n>this.maxFutureS)return{ok:!1,reason:"too_far_future"};let r={ntpTime:e.ntpTime,seq:this._seq++,sessionId:e.sessionId||0,runTag:e.runTag||"",payload:e.payload};return this._push(r),{ok:!0,scheduled:r}}nextDueTime(){return this._heap.length?this._heap[0].ntpTime-this.lookaheadS:null}dispatchDue(e,n){let s=e+this.lookaheadS,r=0;for(;this._heap.length&&this._heap[0].ntpTime<=s;)n(this._pop()),r++;return r}cancelBy(e){if(this._heap.length===0)return 0;let n=this._heap.length;this._heap=this._heap.filter(r=>!e(r));let s=n-this._heap.length;return s>0&&this._heapify(),s}cancelTag(e){return this.cancelBy(n=>n.runTag===e)}cancelSession(e){return this.cancelBy(n=>n.sessionId===e)}cancelSessionTag(e,n){return this.cancelBy(s=>s.sessionId===e&&s.runTag===n)}cancelAll(){let e=this._heap.length;return this._heap=[],e}_cmp(e,n){return e.ntpTime===n.ntpTime?e.seq-n.seq:e.ntpTime-n.ntpTime}_swap(e,n){let s=this._heap[e];this._heap[e]=this._heap[n],this._heap[n]=s}_push(e){this._heap.push(e),this._siftUp(this._heap.length-1)}_pop(){let e=this._heap[0],n=this._heap.pop();return this._heap.length&&(this._heap[0]=n,this._siftDown(0)),e}_siftUp(e){for(;e>0;){let n=e-1>>1;if(this._cmp(this._heap[e],this._heap[n])>=0)break;this._swap(e,n),e=n}}_siftDown(e){let n=this._heap.length;for(;;){let s=2*e+1,r=2*e+2,o=e;if(s<n&&this._cmp(this._heap[s],this._heap[o])<0&&(o=s),r<n&&this._cmp(this._heap[r],this._heap[o])<0&&(o=r),o===e)break;this._swap(e,o),e=o}}_heapify(){for(let e=(this._heap.length>>1)-1;e>=0;e--)this._siftDown(e)}};var h="sab",W=null,F=524288,He=65536,Te=3600,Ae=4294967295,C=null,w=null,u=null,y=null,he=null,pe=null,q=null,de=null,b={},a=null,k=null,_e=null,V=150,I=(t,e)=>{a&&(h==="sab"?Atomics.store(a,t,e):a[t]=e)},j=t=>a?h==="sab"?Atomics.load(a,t):a[t]:0,p=(t,e)=>{a&&(h==="sab"?Atomics.add(a,t,e):a[t]+=e)},G=I,ue=j,Fe=()=>{if(h!=="postMessage"||_e!==null)return;let t=()=>{k&&a&&self.postMessage({type:"preschedulerMetrics",metrics:new Uint32Array(k.slice(0))}),_e=setTimeout(t,V)};t(),f("[PreScheduler] Started metrics sending (every "+V+"ms)")};var U=null,H=1/0,ae=!1,E=[],v=!1,D=65536,$=.5,c=new B({lookaheadS:$,maxPending:D,maxFutureS:Te,poolBytes:F}),f=(...t)=>{},ee=oe,we=t=>ce(t),be=()=>{if(!C||!u){console.error("[PreScheduler] Cannot init - missing buffer or constants");return}y=new Int32Array(C),he=new DataView(C),pe=new Uint8Array(C);let t=u.MESSAGE_HEADER_SIZE||16;q=new Uint8Array(t),de=new DataView(q.buffer),b=se(w,u.CONTROL_START);let e=w+u.METRICS_START;a=new Uint32Array(C,e,u.METRICS_SIZE/4),f("[PreScheduler] SharedArrayBuffer initialized with direct ring buffer writing and metrics")},Y=()=>{if(!a)return;I(9,c.size());let t=c.size(),e=j(10);t>e&&I(10,t)},x=(t,e,n=0,s=!1)=>{if(h==="postMessage")return W?(W.postMessage({type:"osc",oscData:t,sourceId:n}),p(12,1),!0):(console.error("[PreScheduler] No worklet port available"),!1);if(!C||!y)return console.error("[PreScheduler] Not initialized for ring buffer writing"),!1;let r=t.length,o=u.MESSAGE_HEADER_SIZE+r;return o>u.IN_BUFFER_SIZE-u.MESSAGE_HEADER_SIZE?(console.error("[PreScheduler] Message too large:",o),!1):ne({atomicView:y,dataView:he,uint8View:pe,bufferConstants:u,ringBufferBase:w,controlIndices:b,oscMessage:t,sourceId:n,maxSpins:10,useWait:s,headerScratch:q,headerScratchView:de})?(p(12,1),!0):!1},g=(t,e,n=0)=>{let s=c.size()+E.length;if(s>=D){console.error("[PreScheduler] Backpressure: dropping retry ("+s+" pending)"),p(17,1);return}E.push({oscData:t,context:e||"unknown",queuedAt:performance.now(),sourceId:n}),I(18,E.length);let r=j(19);E.length>r&&I(19,E.length),f("[PreScheduler] Queued message for retry:",e,"queue size:",E.length),Ue()},Ue=()=>{if(v||E.length===0||h!=="sab")return;v=!0;let t=Atomics.load(y,b.IN_TAIL),e=Atomics.waitAsync(y,b.IN_TAIL,t),n=()=>{v=!1,ke(),E.length>0&&Ue()};e.async?e.value.then(n):queueMicrotask(n)},ke=()=>{if(E.length===0)return;let t=0;for(let e=0;e<E.length;e++){let n=E[e];if(x(n.oscData,!0,n.sourceId,!0))t++,p(16,1);else break}t>0&&(E.splice(0,t),I(18,E.length))},fe=(t,e,n,s=0)=>{let r=we(t),o=ee();c.retryCount=E.length;let _=c.schedule({ntpTime:r,bytes:t.length,sessionId:e,runTag:n,payload:{oscData:t,sourceId:s}},o);if(!_.ok){let[d,i]={queue_full:["PRESCHEDULER_QUEUE_FULL",`Prescheduler queue full (${c.size()+E.length} >= ${D} max)`],too_large:["BUNDLE_TOO_LARGE",`Bundle too large for scheduler pool (${t.length} > ${F} bytes)`],too_far_future:["BUNDLE_TOO_FAR_FUTURE",`Bundle scheduled too far in future (${(r-o).toFixed(0)}s > ${Te}s max)`]}[_.reason];return console.error("[PreScheduler]",i),self.postMessage({type:"error",error:i,code:d}),!1}return _.immediate?(f("[PreScheduler] Non-bundle message, dispatching immediately"),x(t,!1,s,!0)||g(t,"immediate message",s),!0):(p(11,1),Y(),f("[PreScheduler] Scheduled bundle:","NTP="+r.toFixed(3),"current="+o.toFixed(3),"wait="+((r-o)*1e3).toFixed(1)+"ms","pending="+c.size()),m(),!0)},m=()=>{let t=c.nextDueTime();if(t===null){U!==null&&(clearTimeout(U),U=null,H=1/0);return}if(t<H){U!==null&&clearTimeout(U);let e=Math.max(0,(t-ee())*1e3);H=t,U=setTimeout(Ye,e)}},Ge=()=>{U===null&&(f("[PreScheduler] Starting demand-driven dispatching"),m())};var Ye=()=>{ae=!0;let t=ee(),e=0,n=s=>{Y();let{oscData:r,sourceId:o}=s.payload,_=s.ntpTime-t;if(p(21,1),_<0){let i=Math.round(-_*1e3);p(15,1);let T=ue(23);i>T&&G(23,i)}else{let i=Math.round(_*1e3),T=ue(14);(T===Ae||i<T)&&G(14,i)}f("[PreScheduler] Dispatching bundle:","NTP="+s.ntpTime.toFixed(3),"current="+t.toFixed(3),"early="+(_*1e3).toFixed(1)+"ms","remaining="+c.size()),x(r,!1,o,!0)||g(r,"scheduled bundle NTP="+s.ntpTime.toFixed(3),o),e++};c.dispatchDue(t,n),(e>0||c.size()>0||E.length>0)&&f("[PreScheduler] Dispatch cycle complete:","dispatched="+e,"pending="+c.size(),"retrying="+E.length),ae=!1,U=null,H=1/0,m()},te=t=>{t>0&&(p(13,t),Y(),f("[PreScheduler] Cancelled "+t+" events, "+c.size()+" remaining"),m())},Xe=(t,e)=>te(c.cancelSessionTag(t,e)),Ke=t=>te(c.cancelSession(t)),ze=t=>te(c.cancelTag(t)),ve=()=>{let t=c.cancelAll(),e=E.length;t===0&&e===0||(p(13,t+e),E=[],I(18,0),Y(),f("[PreScheduler] Cancelled all "+t+" events, "+e+" retries"),m())},Qe=re,Ze=t=>{let e=[],n=new DataView(t.buffer,t.byteOffset,t.byteLength),s=16;for(;s+4<=t.length;){let r=n.getInt32(s,!1);if(s+=4,r<=0||r>He||s+r>t.length)break;let o=t.slice(s,s+r);for(e.push(o),s+=r;s%4!==0&&s<t.length;)s++}return e},We=(t,e=0)=>{if(Qe(t)){let n=Ze(t);for(let s=0;s<n.length;s++)x(n[s],!1,e,!0)||g(n[s],"immediate bundle message "+s,e)}else x(t,!1,e,!0)||g(t,"immediate message",e)};self.addEventListener("message",t=>{let{data:e}=t;try{switch(e.type){case"init":if(h=e.mode||"sab",e.maxPendingMessages&&(D=e.maxPendingMessages),e.snapshotIntervalMs&&(V=e.snapshotIntervalMs),e.bypassLookaheadS!==void 0&&($=e.bypassLookaheadS),h==="sab")C=e.sharedBuffer,w=e.ringBufferBase,u=e.bufferConstants,be(),u&&u.scheduler_data_pool_size&&(F=u.scheduler_data_pool_size);else{W=e.workletPort;let s=184;k=new ArrayBuffer(s),a=new Uint32Array(k),Fe()}G(14,Ae),G(23,0),c.maxPending=D,c.lookaheadS=$,c.poolBytes=F,Ge(),f("[OSCPreSchedulerWorker] Initialized with NTP-based scheduling, mode="+h+", capacity="+D),self.postMessage({type:"initialized"});break;case"addOscSource":let n=t.ports[0];n&&(n.onmessage=s=>{s.data.type==="osc"&&s.data.oscData&&fe(s.data.oscData,0,"",s.data.sourceId||0)},f("[OSCPreSchedulerWorker] Added external OSC source"));break;case"send":fe(e.oscData,e.sessionId||0,e.runTag||"",e.sourceId||0);break;case"sendImmediate":We(e.oscData,e.sourceId||0);break;case"directDispatch":x(e.oscData,!1,e.sourceId||0,!0)||g(e.oscData,"directDispatch fallback",e.sourceId||0);break;case"cancelSessionTag":e.runTag!==void 0&&e.runTag!==null&&e.runTag!==""&&Xe(e.sessionId||0,e.runTag);break;case"cancelSession":Ke(e.sessionId||0);break;case"cancelTag":e.runTag!==void 0&&e.runTag!==null&&e.runTag!==""&&ze(e.runTag);break;case"cancelAll":ve(),e.ack&&self.postMessage({type:"cancelAllAck"});break;default:}}catch(n){console.error("[OSCPreSchedulerWorker] Error:",n),self.postMessage({type:"error",error:n.message})}});f("[OSCPreSchedulerWorker] Script loaded");})();
|
package/package.json
CHANGED