supersonic-scsynth-core 0.27.0 → 0.29.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "supersonic-scsynth-core",
3
- "version": "0.27.0",
3
+ "version": "0.29.0",
4
4
  "description": "SuperCollider scsynth WebAssembly engine and AudioWorklet for SuperSonic",
5
5
  "type": "module",
6
6
  "main": "index.js",
Binary file
@@ -1,3 +1,3 @@
1
- (()=>{function C({uint8View:t,dataView:e,bufferStart:s,bufferSize:o,head:i,tail:D,messageMagic:R,paddingMagic:m,headerSize:c,maxMessages:y=1/0,onMessage:b,onCorruption:f}){let r=D,T=0;for(;r!==i&&T<y;){if(o-r<c){r=0;continue}let g=s+r,d=e.getUint32(g,!0);if(d===m){r=0;continue}if(d!==R){f&&f(r),r=(r+1)%o;continue}let _=e.getUint32(g+4,!0),w=e.getUint32(g+8,!0);if(_<c||_>o){f&&f(r),r=(r+1)%o;continue}let x=_-c,L=g+c,B=new Uint8Array(x);for(let S=0;S<x;S++)B[S]=t[L+S];b(B,w,_),r=(r+_)%o,T++}return{newTail:r,messagesRead:T}}var p="sab",l=null,u=null,n=null,I=null,M=null,E=null,a={},U=null,A=!1,G=new TextDecoder("utf-8"),k=(...t)=>{},H=(t,e,s)=>{l=t,u=e,E=s,n=new Int32Array(l),I=new DataView(l),M=new Uint8Array(l),a={DEBUG_HEAD:(u+E.CONTROL_START+16)/4,DEBUG_TAIL:(u+E.CONTROL_START+20)/4};let o=u+E.METRICS_START;U=new Uint32Array(l,o,E.METRICS_SIZE/4)},h=()=>{let t=Atomics.load(n,a.DEBUG_HEAD),e=Atomics.load(n,a.DEBUG_TAIL);if(t===e)return null;let s=[],{newTail:o,messagesRead:i}=C({uint8View:M,dataView:I,bufferStart:u+E.DEBUG_BUFFER_START,bufferSize:E.DEBUG_BUFFER_SIZE,head:t,tail:e,messageMagic:E.MESSAGE_MAGIC,paddingMagic:E.PADDING_MAGIC,headerSize:E.MESSAGE_HEADER_SIZE,maxMessages:1e3,onMessage:(D,R,m)=>{let c=G.decode(D);c.endsWith(`
2
- `)&&(c=c.slice(0,-1)),s.push({text:c,timestamp:performance.now(),sequence:R}),U&&(Atomics.add(U,20,1),Atomics.add(U,21,D.length))},onCorruption:D=>{console.error("[DebugWorker] Corrupted message at position",D)}});return i>0&&Atomics.store(n,a.DEBUG_TAIL,o),s.length>0?s:null},W=()=>{for(;A;)try{let t=Atomics.load(n,a.DEBUG_HEAD),e=Atomics.load(n,a.DEBUG_TAIL);if(t===e){let o=Atomics.wait(n,a.DEBUG_HEAD,t,100);if(!(o==="ok"||o==="not-equal")){if(o==="timed-out")continue}}let s=h();s&&s.length>0&&self.postMessage({type:"debug",messages:s})}catch(t){console.error("[DebugWorker] Error in wait loop:",t),self.postMessage({type:"error",error:t.message}),Atomics.wait(n,0,n[0],10)}},F=()=>{if(!l){console.error("[DebugWorker] Cannot start - not initialized");return}if(A){console.warn("[DebugWorker] Already running");return}A=!0,W()},Q=()=>{A=!1},Y=()=>{l&&(Atomics.store(n,a.DEBUG_HEAD,0),Atomics.store(n,a.DEBUG_TAIL,0))},V=t=>{let e=[];for(let s of t)try{let o=new Uint8Array(s.bytes),i=G.decode(o);i.endsWith(`
3
- `)&&(i=i.slice(0,-1)),e.push({text:i,timestamp:performance.now(),sequence:s.sequence})}catch(o){console.error("[DebugWorker] Failed to decode message:",o)}e.length>0&&self.postMessage({type:"debug",messages:e})};self.addEventListener("message",t=>{let{data:e}=t;try{switch(e.type){case"init":p=e.mode||"sab",p==="sab"&&H(e.sharedBuffer,e.ringBufferBase,e.bufferConstants),self.postMessage({type:"initialized"});break;case"start":p==="sab"&&F();break;case"stop":Q();break;case"clear":p==="sab"&&Y();break;case"debugRaw":e.messages&&V(e.messages);break;default:console.warn("[DebugWorker] Unknown message type:",e.type)}}catch(s){console.error("[DebugWorker] Error:",s),self.postMessage({type:"error",error:s.message})}});k("[DebugWorker] Script loaded");})();
1
+ (()=>{function d({uint8View:t,dataView:e,bufferStart:s,bufferSize:o,head:S,tail:i,messageMagic:C,paddingMagic:A,headerSize:c,maxMessages:I=1/0,onMessage:M,onCorruption:R}){let r=i,g=0;for(;r!==S&&g<I;){if(o-r<c){r=0;continue}let U=s+r,x=e.getUint32(U,!0);if(x===A){r=0;continue}if(x!==C){R&&R(r),r=(r+1)%o;continue}let D=e.getUint32(U+4,!0),G=e.getUint32(U+8,!0);if(D<c||D>o){R&&R(r),r=(r+1)%o;continue}let m=D-c,N=U+c,B=new Uint8Array(m);for(let p=0;p<m;p++)B[p]=t[N+p];M(B,G,D),r=(r+D)%o,g++}return{newTail:r,messagesRead:g}}var u="sab",_=null,l=null,n=null,H=null,P=null,E=null,a={},T=null,f=!1,L=new TextDecoder("utf-8"),w=(...t)=>{},Y=(t,e,s)=>{_=t,l=e,E=s,n=new Int32Array(_),H=new DataView(_),P=new Uint8Array(_),a={DEBUG_HEAD:(l+E.CONTROL_START+16)/4,DEBUG_TAIL:(l+E.CONTROL_START+20)/4};let o=l+E.METRICS_START;T=new Uint32Array(_,o,E.METRICS_SIZE/4)},k=()=>{let t=Atomics.load(n,a.DEBUG_HEAD),e=Atomics.load(n,a.DEBUG_TAIL);if(t===e)return null;let s=[],{newTail:o,messagesRead:S}=d({uint8View:P,dataView:H,bufferStart:l+E.DEBUG_BUFFER_START,bufferSize:E.DEBUG_BUFFER_SIZE,head:t,tail:e,messageMagic:E.MESSAGE_MAGIC,paddingMagic:E.PADDING_MAGIC,headerSize:E.MESSAGE_HEADER_SIZE,maxMessages:1e3,onMessage:(i,C,A)=>{let c=L.decode(i);c.endsWith(`
2
+ `)&&(c=c.slice(0,-1)),s.push({text:c,timestamp:performance.now(),sequence:C}),T&&(Atomics.add(T,29,1),Atomics.add(T,30,i.length))},onCorruption:i=>{console.error("[DebugWorker] Corrupted message at position",i)}});return S>0&&Atomics.store(n,a.DEBUG_TAIL,o),s.length>0?s:null},F=()=>{for(;f;)try{let t=Atomics.load(n,a.DEBUG_HEAD),e=Atomics.load(n,a.DEBUG_TAIL);if(t===e){let o=Atomics.wait(n,a.DEBUG_HEAD,t,100);if(!(o==="ok"||o==="not-equal")){if(o==="timed-out")continue}}let s=k();s&&s.length>0&&self.postMessage({type:"debug",messages:s})}catch(t){console.error("[DebugWorker] Error in wait loop:",t),self.postMessage({type:"error",error:t.message}),Atomics.wait(n,0,n[0],10)}},h=()=>{if(!_){console.error("[DebugWorker] Cannot start - not initialized");return}if(f){console.warn("[DebugWorker] Already running");return}f=!0,F()},W=()=>{f=!1},V=()=>{_&&(Atomics.store(n,a.DEBUG_HEAD,0),Atomics.store(n,a.DEBUG_TAIL,0))},Z=t=>{let e=[];for(let s of t)try{let o=new Uint8Array(s.bytes),S=L.decode(o);S.endsWith(`
3
+ `)&&(S=S.slice(0,-1)),e.push({text:S,timestamp:performance.now(),sequence:s.sequence})}catch(o){console.error("[DebugWorker] Failed to decode message:",o)}e.length>0&&self.postMessage({type:"debug",messages:e})};self.addEventListener("message",t=>{let{data:e}=t;try{switch(e.type){case"init":u=e.mode||"sab",u==="sab"&&Y(e.sharedBuffer,e.ringBufferBase,e.bufferConstants),self.postMessage({type:"initialized"});break;case"start":u==="sab"&&h();break;case"stop":W();break;case"clear":u==="sab"&&V();break;case"debugRaw":e.messages&&Z(e.messages);break;default:console.warn("[DebugWorker] Unknown message type:",e.type)}}catch(s){console.error("[DebugWorker] Error:",s),self.postMessage({type:"error",error:s.message})}});w("[DebugWorker] Script loaded");})();
@@ -1 +1 @@
1
- (()=>{function m({uint8View:e,dataView:t,bufferStart:r,bufferSize:o,head:C,tail:l,messageMagic:i,paddingMagic:u,headerSize:c,maxMessages:f=1/0,onMessage:F,onCorruption:A}){let s=l,I=0;for(;s!==C&&I<f;){if(o-s<c){s=0;continue}let U=r+s,g=t.getUint32(U,!0);if(g===u){s=0;continue}if(g!==i){A&&A(s),s=(s+1)%o;continue}let p=t.getUint32(U+4,!0),L=t.getUint32(U+8,!0);if(p<c||p>o){A&&A(s),s=(s+1)%o;continue}let d=p-c,B=U+c,x=new Uint8Array(d);for(let D=0;D<d;D++)x[D]=e[B+D];F(x,L,p),s=(s+p)%o,I++}return{newTail:s,messagesRead:I}}var _=null,T=null,E=null,P=null,y=null,n=null,S={},a=null,R=!1,H=(...e)=>{},O=-1,k=(e,t,r)=>{_=e,T=t,n=r,E=new Int32Array(_),P=new DataView(_),y=new Uint8Array(_),S={OUT_HEAD:(T+n.CONTROL_START+8)/4,OUT_TAIL:(T+n.CONTROL_START+12)/4};let o=T+n.METRICS_START;a=new Uint32Array(_,o,n.METRICS_SIZE/4)},W=()=>{let e=Atomics.load(E,S.OUT_HEAD),t=Atomics.load(E,S.OUT_TAIL);if(e===t)return[];let r=[],{newTail:o,messagesRead:C}=m({uint8View:y,dataView:P,bufferStart:T+n.OUT_BUFFER_START,bufferSize:n.OUT_BUFFER_SIZE,head:e,tail:t,messageMagic:n.MESSAGE_MAGIC,paddingMagic:n.PADDING_MAGIC,headerSize:n.MESSAGE_HEADER_SIZE,maxMessages:100,onMessage:(l,i,u)=>{if(O>=0){let c=O+1&4294967295;if(i!==c){let f=i-c+4294967296&4294967295;f<1e3&&(console.warn("[OSCInWorker] Detected",f,"dropped messages (expected seq",c,"got",i,")"),a&&Atomics.add(a,18,f))}}O=i,r.push({oscData:l,sequence:i}),a&&(Atomics.add(a,17,1),Atomics.add(a,19,l.length))},onCorruption:l=>{console.error("[OSCInWorker] Corrupted message at position",l),a&&Atomics.add(a,18,1)}});return C>0&&Atomics.store(E,S.OUT_TAIL,o),r},b=()=>{for(;R;)try{let e=Atomics.load(E,S.OUT_HEAD),t=Atomics.load(E,S.OUT_TAIL);if(e===t){let o=Atomics.wait(E,S.OUT_HEAD,e,100);if(!(o==="ok"||o==="not-equal")){if(o==="timed-out")continue}}let r=W();r.length>0&&self.postMessage({type:"messages",messages:r})}catch(e){console.error("[OSCInWorker] Error in wait loop:",e),self.postMessage({type:"error",error:e.message}),Atomics.wait(E,0,E[0],10)}},h=()=>{if(!_){console.error("[OSCInWorker] Cannot start - not initialized");return}if(R){console.warn("[OSCInWorker] Already running");return}R=!0,b()},Q=()=>{R=!1};self.addEventListener("message",e=>{let{data:t}=e;try{switch(t.type){case"init":k(t.sharedBuffer,t.ringBufferBase,t.bufferConstants),self.postMessage({type:"initialized"});break;case"start":h();break;case"stop":Q();break;default:console.warn("[OSCInWorker] Unknown message type:",t.type)}}catch(r){console.error("[OSCInWorker] Error:",r),self.postMessage({type:"error",error:r.message})}});H("[OSCInWorker] Script loaded");})();
1
+ (()=>{function H({uint8View:e,dataView:t,bufferStart:r,bufferSize:o,head:A,tail:i,messageMagic:_,paddingMagic:P,headerSize:c,maxMessages:l=1/0,onMessage:N,onCorruption:D}){let s=i,O=0;for(;s!==A&&O<l;){if(o-s<c){s=0;continue}let U=r+s,u=t.getUint32(U,!0);if(u===P){s=0;continue}if(u!==_){D&&D(s),s=(s+1)%o;continue}let C=t.getUint32(U+4,!0),m=t.getUint32(U+8,!0);if(C<c||C>o){D&&D(s),s=(s+1)%o;continue}let x=C-c,B=U+c,g=new Uint8Array(x);for(let p=0;p<x;p++)g[p]=e[B+p];N(g,m,C),s=(s+C)%o,O++}return{newTail:s,messagesRead:O}}var R=null,T=null,S=null,d=null,M=null,E=null,a={},n=null,f=!1,Y=(...e)=>{},I=-1,k=(e,t,r)=>{R=e,T=t,E=r,S=new Int32Array(R),d=new DataView(R),M=new Uint8Array(R),a={OUT_HEAD:(T+E.CONTROL_START+8)/4,OUT_TAIL:(T+E.CONTROL_START+12)/4};let o=T+E.METRICS_START;n=new Uint32Array(R,o,E.METRICS_SIZE/4)},W=()=>{let e=Atomics.load(S,a.OUT_HEAD),t=Atomics.load(S,a.OUT_TAIL);if(e===t)return[];let r=[],{newTail:o,messagesRead:A}=H({uint8View:M,dataView:d,bufferStart:T+E.OUT_BUFFER_START,bufferSize:E.OUT_BUFFER_SIZE,head:e,tail:t,messageMagic:E.MESSAGE_MAGIC,paddingMagic:E.PADDING_MAGIC,headerSize:E.MESSAGE_HEADER_SIZE,maxMessages:100,onMessage:(i,_,P)=>{if(I>=0){let c=I+1&4294967295;if(_!==c){let l=_-c+4294967296&4294967295;l<1e3&&(console.warn("[OSCInWorker] Detected",l,"dropped messages (expected seq",c,"got",_,")"),n&&Atomics.add(n,27,l))}}I=_,r.push({oscData:i,sequence:_}),n&&(Atomics.add(n,25,1),Atomics.add(n,26,i.length))},onCorruption:i=>{console.error("[OSCInWorker] Corrupted message at position",i),n&&(Atomics.add(n,27,1),Atomics.add(n,28,1))}});return A>0&&Atomics.store(S,a.OUT_TAIL,o),r},b=()=>{for(;f;)try{let e=Atomics.load(S,a.OUT_HEAD),t=Atomics.load(S,a.OUT_TAIL);if(e===t){let o=Atomics.wait(S,a.OUT_HEAD,e,100);if(!(o==="ok"||o==="not-equal")){if(o==="timed-out")continue}}let r=W();r.length>0&&self.postMessage({type:"messages",messages:r})}catch(e){console.error("[OSCInWorker] Error in wait loop:",e),self.postMessage({type:"error",error:e.message}),Atomics.wait(S,0,S[0],10)}},h=()=>{if(!R){console.error("[OSCInWorker] Cannot start - not initialized");return}if(f){console.warn("[OSCInWorker] Already running");return}f=!0,b()},V=()=>{f=!1};self.addEventListener("message",e=>{let{data:t}=e;try{switch(t.type){case"init":k(t.sharedBuffer,t.ringBufferBase,t.bufferConstants),self.postMessage({type:"initialized"});break;case"start":h();break;case"stop":V();break;default:console.warn("[OSCInWorker] Unknown message type:",t.type)}}catch(r){console.error("[OSCInWorker] Error:",r),self.postMessage({type:"error",error:r.message})}});Y("[OSCInWorker] Script loaded");})();
@@ -1 +1 @@
1
- (()=>{function F(e,t,n){return(n-1-e+t)%n}function k({uint8View:e,dataView:t,bufferStart:n,bufferSize:s,head:c,payload:o,sequence:d,messageMagic:h,headerSize:S}){let U=o.length,m=S+U+3&-4,g=s-c;if(m>g){let u=new Uint8Array(S),R=new DataView(u.buffer);R.setUint32(0,h,!0),R.setUint32(4,m,!0),R.setUint32(8,d,!0),R.setUint32(12,0,!0);let I=n+c,x=n;if(g>=S){e.set(u,I);let P=g-S;P>0&&e.set(o.subarray(0,P),I+S),e.set(o.subarray(P),x)}else{e.set(u.subarray(0,g),I),e.set(u.subarray(g),x);let P=S-g;e.set(o,x+P)}}else{let u=n+c;t.setUint32(u,h,!0),t.setUint32(u+4,m,!0),t.setUint32(u+8,d,!0),t.setUint32(u+12,0,!0),e.set(o,u+S)}return(c+m)%s}function le(e,t,n=0){for(let s=0;s<=n;s++)if(Atomics.compareExchange(e,t,0,1)===0)return!0;return!1}function ie(e,t){Atomics.store(e,t,0)}function G({atomicView:e,dataView:t,uint8View:n,bufferConstants:s,ringBufferBase:c,controlIndices:o,oscMessage:d,maxSpins:h=0}){let S=d.length,U=s.MESSAGE_HEADER_SIZE+S;if(U>s.IN_BUFFER_SIZE-s.MESSAGE_HEADER_SIZE||!le(e,o.IN_WRITE_LOCK,h))return!1;try{let O=Atomics.load(e,o.IN_HEAD),m=Atomics.load(e,o.IN_TAIL),g=U+3&-4;if(F(O,m,s.IN_BUFFER_SIZE)<g)return!1;let R=Atomics.add(e,o.IN_SEQUENCE,1),I=k({uint8View:n,dataView:t,bufferStart:c+s.IN_BUFFER_START,bufferSize:s.IN_BUFFER_SIZE,head:O,payload:d,sequence:R,messageMagic:s.MESSAGE_MAGIC,headerSize:s.MESSAGE_HEADER_SIZE});return Atomics.load(e,o.IN_HEAD),Atomics.store(e,o.IN_HEAD,I),!0}finally{ie(e,o.IN_WRITE_LOCK)}}var p="sab",T=null,_=null,a=null,w=null,z=null,$=null,j={},i=null,D=null,Y=null,B=25,A=(e,t)=>{i&&(p==="sab"?Atomics.store(i,e,t):i[e]=t)},J=e=>i?p==="sab"?Atomics.load(i,e):i[e]:0,f=(e,t)=>{i&&(p==="sab"?Atomics.add(i,e,t):i[e]+=t)},Se=()=>{if(p!=="postMessage"||Y!==null)return;let e=()=>{D&&i&&self.postMessage({type:"preschedulerMetrics",metrics:new Uint32Array(D.slice(0))}),Y=setTimeout(e,B)};e(),E("[PreScheduler] Started metrics sending (every "+B+"ms)")};var r=[],ee=null,ge=0,W=!1,l=[],K=5,C=65536,pe=2208988800,te=25,de=.2,E=(...e)=>{},se=()=>(performance.timeOrigin+performance.now())/1e3+pe,Te=e=>{if(e.length>=16&&e[0]===35){let t=new DataView(e.buffer,e.byteOffset),n=t.getUint32(8,!1),s=t.getUint32(12,!1);return n+s/4294967296}return null};var _e=()=>{if(!T||!a){console.error("[PreScheduler] Cannot init - missing buffer or constants");return}w=new Int32Array(T),z=new DataView(T),$=new Uint8Array(T),j={IN_HEAD:(_+a.CONTROL_START+0)/4,IN_TAIL:(_+a.CONTROL_START+4)/4,IN_SEQUENCE:(_+a.CONTROL_START+24)/4,IN_WRITE_LOCK:(_+a.CONTROL_START+40)/4};let e=_+a.METRICS_START;i=new Uint32Array(T,e,a.METRICS_SIZE/4),E("[PreScheduler] SharedArrayBuffer initialized with direct ring buffer writing and metrics")},N=()=>{if(!i)return;A(6,r.length);let e=r.length,t=J(7);e>t&&A(7,e)},M=(e,t,n=null)=>{if(p==="postMessage")return self.postMessage({type:"dispatch",oscData:e,timestamp:n}),f(8,1),!0;if(!T||!w)return console.error("[PreScheduler] Not initialized for ring buffer writing"),!1;let s=e.length,c=a.MESSAGE_HEADER_SIZE+s;return c>a.IN_BUFFER_SIZE-a.MESSAGE_HEADER_SIZE?(console.error("[PreScheduler] Message too large:",c),!1):G({atomicView:w,dataView:z,uint8View:$,bufferConstants:a,ringBufferBase:_,controlIndices:j,oscMessage:e,maxSpins:10})?(f(8,1),!0):(t||console.warn("[PreScheduler] Ring buffer full, message will be queued for retry"),!1)},y=(e,t)=>{let n=r.length+l.length;if(n>=C){console.error("[PreScheduler] Backpressure: dropping retry ("+n+" pending)"),f(10,1);return}l.push({oscData:e,retryCount:0,context:t||"unknown",queuedAt:performance.now()}),A(15,l.length);let s=J(16);l.length>s&&A(16,l.length),E("[PreScheduler] Queued message for retry:",t,"queue size:",l.length)},he=()=>{if(l.length===0)return;let e=0;for(;e<l.length;){let t=l[e];if(M(t.oscData,!0))l.splice(e,1),f(9,1),f(14,1),A(15,l.length),E("[PreScheduler] Retry succeeded for:",t.context,"after",t.retryCount+1,"attempts");else if(t.retryCount++,f(14,1),t.retryCount>=K){let s=`Ring buffer full - dropped message after ${K} retries (${t.context})`;console.error("[PreScheduler]",s),l.splice(e,1),f(10,1),A(15,l.length),self.postMessage({type:"error",error:s})}else e++}},me=(e,t,n)=>{let s=r.length+l.length;if(s>=C)return console.warn("[PreScheduler] Backpressure: rejecting message ("+s+" pending)"),!1;let c=Te(e);if(c===null)return E("[PreScheduler] Non-bundle message, dispatching immediately"),M(e,!1)||y(e,"immediate message"),!0;let o=se(),d=c-o,h={ntpTime:c,seq:ge++,sessionId:t||0,runTag:n||"",oscData:e};return Re(h),f(11,1),N(),E("[PreScheduler] Scheduled bundle:","NTP="+c.toFixed(3),"current="+o.toFixed(3),"wait="+(d*1e3).toFixed(1)+"ms","pending="+r.length),!0},Re=e=>{r.push(e),Pe(r.length-1)},Ae=()=>r.length>0?r[0]:null,Ie=()=>{if(r.length===0)return null;let e=r[0],t=r.pop();return r.length>0&&(r[0]=t,ne(0)),e},Pe=e=>{for(;e>0;){let t=Math.floor((e-1)/2);if(b(r[e],r[t])>=0)break;re(e,t),e=t}},ne=e=>{let t=r.length;for(;;){let n=2*e+1,s=2*e+2,c=e;if(n<t&&b(r[n],r[c])<0&&(c=n),s<t&&b(r[s],r[c])<0&&(c=s),c===e)break;re(e,c),e=c}},b=(e,t)=>e.ntpTime===t.ntpTime?e.seq-t.seq:e.ntpTime-t.ntpTime,re=(e,t)=>{let n=r[e];r[e]=r[t],r[t]=n},Me=()=>{if(ee!==null){console.warn("[PreScheduler] Polling already started");return}E("[PreScheduler] Starting periodic polling (every "+te+"ms)"),ce()};var ce=()=>{W=!0,he();let e=se(),t=e+de,n=0;for(;r.length>0;){let s=Ae();if(s.ntpTime<=t){Ie(),N();let c=s.ntpTime-e;f(13,1),E("[PreScheduler] Dispatching bundle:","NTP="+s.ntpTime.toFixed(3),"current="+e.toFixed(3),"early="+(c*1e3).toFixed(1)+"ms","remaining="+r.length),M(s.oscData,!1)||y(s.oscData,"scheduled bundle NTP="+s.ntpTime.toFixed(3)),n++}else break}(n>0||r.length>0||l.length>0)&&E("[PreScheduler] Dispatch cycle complete:","dispatched="+n,"pending="+r.length,"retrying="+l.length),W=!1,ee=setTimeout(ce,te)},H=e=>{if(r.length===0)return;let t=r.length,n=[];for(let c=0;c<r.length;c++){let o=r[c];e(o)||n.push(o)}let s=t-n.length;s>0&&(r=n,Ue(),f(12,s),N(),E("[PreScheduler] Cancelled "+s+" events, "+r.length+" remaining"))},Ue=()=>{for(let e=Math.floor(r.length/2)-1;e>=0;e--)ne(e)},De=(e,t)=>{H(n=>n.sessionId===e&&n.runTag===t)},Ce=e=>{H(t=>t.sessionId===e)},ye=e=>{H(t=>t.runTag===e)},Ne=()=>{if(r.length===0)return;let e=r.length;f(12,e),r=[],N(),E("[PreScheduler] Cancelled all "+e+" events")},Oe=e=>!e||e.length<8?!1:e[0]===35&&e[1]===98&&e[2]===117&&e[3]===110&&e[4]===100&&e[5]===108&&e[6]===101&&e[7]===0,xe=e=>{let t=[],n=new DataView(e.buffer,e.byteOffset,e.byteLength),s=16;for(;s<e.length;){let c=n.getInt32(s,!1);if(s+=4,c<=0||s+c>e.length)break;let o=e.slice(s,s+c);for(t.push(o),s+=c;s%4!==0&&s<e.length;)s++}return t},Le=e=>{if(Oe(e)){let t=xe(e);for(let n=0;n<t.length;n++)M(t[n],!1)||y(t[n],"immediate bundle message "+n)}else M(e,!1)||y(e,"immediate message")};self.addEventListener("message",e=>{let{data:t}=e;try{switch(t.type){case"init":p=t.mode||"sab",t.maxPendingMessages&&(C=t.maxPendingMessages),t.snapshotIntervalMs&&(B=t.snapshotIntervalMs),p==="sab"?(T=t.sharedBuffer,_=t.ringBufferBase,a=t.bufferConstants,_e()):(D=new ArrayBuffer(128),i=new Uint32Array(D),Se()),Me(),E("[OSCPreSchedulerWorker] Initialized with NTP-based scheduling, mode="+p+", capacity="+C),self.postMessage({type:"initialized"});break;case"send":me(t.oscData,t.sessionId||0,t.runTag||"");break;case"sendImmediate":Le(t.oscData);break;case"cancelSessionTag":t.runTag!==void 0&&t.runTag!==null&&t.runTag!==""&&De(t.sessionId||0,t.runTag);break;case"cancelSession":Ce(t.sessionId||0);break;case"cancelTag":t.runTag!==void 0&&t.runTag!==null&&t.runTag!==""&&ye(t.runTag);break;case"cancelAll":Ne();break;default:console.warn("[OSCPreSchedulerWorker] Unknown message type:",t.type)}}catch(n){console.error("[OSCPreSchedulerWorker] Error:",n),self.postMessage({type:"error",error:n.message})}});E("[OSCPreSchedulerWorker] Script loaded");})();
1
+ (()=>{function k(e,t,r){return(r-1-e+t)%r}function Y({uint8View:e,dataView:t,bufferStart:r,bufferSize:s,head:o,payload:c,sequence:a,messageMagic:g,headerSize:E}){let M=c.length,P=E+M+3&-4,T=s-o;if(P>T){let _=new Uint8Array(E),D=new DataView(_.buffer);D.setUint32(0,g,!0),D.setUint32(4,P,!0),D.setUint32(8,a,!0),D.setUint32(12,0,!0);let U=r+o,H=r;if(T>=E){e.set(_,U);let C=T-E;C>0&&e.set(c.subarray(0,C),U+E),e.set(c.subarray(C),H)}else{e.set(_.subarray(0,T),U),e.set(_.subarray(T),H);let C=E-T;e.set(c,H+C)}}else{let _=r+o;t.setUint32(_,g,!0),t.setUint32(_+4,P,!0),t.setUint32(_+8,a,!0),t.setUint32(_+12,0,!0),e.set(c,_+E)}return(o+P)%s}function ae(e,t,r=0){for(let s=0;s<=r;s++)if(Atomics.compareExchange(e,t,0,1)===0)return!0;return!1}function fe(e,t){Atomics.store(e,t,0)}function v({atomicView:e,dataView:t,uint8View:r,bufferConstants:s,ringBufferBase:o,controlIndices:c,oscMessage:a,maxSpins:g=0}){let E=a.length,M=s.MESSAGE_HEADER_SIZE+E;if(M>s.IN_BUFFER_SIZE-s.MESSAGE_HEADER_SIZE||!ae(e,c.IN_WRITE_LOCK,g))return!1;try{let N=Atomics.load(e,c.IN_HEAD),P=Atomics.load(e,c.IN_TAIL),T=M+3&-4;if(k(N,P,s.IN_BUFFER_SIZE)<T)return!1;let D=Atomics.add(e,c.IN_SEQUENCE,1),U=Y({uint8View:r,dataView:t,bufferStart:o+s.IN_BUFFER_START,bufferSize:s.IN_BUFFER_SIZE,head:N,payload:a,sequence:D,messageMagic:s.MESSAGE_MAGIC,headerSize:s.MESSAGE_HEADER_SIZE});return Atomics.load(e,c.IN_HEAD),Atomics.store(e,c.IN_HEAD,U),!0}finally{fe(e,c.IN_WRITE_LOCK)}}var R="sab",B=1024,de=65536,W=3600,j=4294967295,p=null,d=null,S=null,F=null,ee=null,te=null,se={},l=null,I=null,$=null,w=50,h=(e,t)=>{l&&(R==="sab"?Atomics.store(l,e,t):l[e]=t)},re=e=>l?R==="sab"?Atomics.load(l,e):l[e]:0,f=(e,t)=>{l&&(R==="sab"?Atomics.add(l,e,t):l[e]+=t)},ne=(e,t)=>{l&&(R==="sab"?Atomics.store(l,e,t):l[e]=t)},Pe=e=>l?R==="sab"?Atomics.load(l,e):l[e]:0,De=()=>{if(R!=="postMessage"||$!==null)return;let e=()=>{I&&l&&self.postMessage({type:"preschedulerMetrics",metrics:new Uint32Array(I.slice(0))}),$=setTimeout(e,w)};e(),u("[PreScheduler] Started metrics sending (every "+w+"ms)")};var n=[],oe=null,he=0,z=!1,i=[],V=5,m=65536,Ue=2208988800,ce=25,Ce=.2,u=(...e)=>{},Ee=()=>(performance.timeOrigin+performance.now())/1e3+Ue,me=e=>{if(e.length>=16&&e[0]===35){let t=new DataView(e.buffer,e.byteOffset),r=t.getUint32(8,!1),s=t.getUint32(12,!1);return r+s/4294967296}return null};var Ae=()=>{if(!p||!S){console.error("[PreScheduler] Cannot init - missing buffer or constants");return}F=new Int32Array(p),ee=new DataView(p),te=new Uint8Array(p),se={IN_HEAD:(d+S.CONTROL_START+0)/4,IN_TAIL:(d+S.CONTROL_START+4)/4,IN_SEQUENCE:(d+S.CONTROL_START+24)/4,IN_WRITE_LOCK:(d+S.CONTROL_START+40)/4};let e=d+S.METRICS_START;l=new Uint32Array(p,e,S.METRICS_SIZE/4),u("[PreScheduler] SharedArrayBuffer initialized with direct ring buffer writing and metrics")},O=()=>{if(!l)return;h(9,n.length);let e=n.length,t=re(10);e>t&&h(10,e)},A=(e,t,r=null)=>{if(R==="postMessage")return self.postMessage({type:"dispatch",oscData:e,timestamp:r}),f(12,1),!0;if(!p||!F)return console.error("[PreScheduler] Not initialized for ring buffer writing"),!1;let s=e.length,o=S.MESSAGE_HEADER_SIZE+s;return o>S.IN_BUFFER_SIZE-S.MESSAGE_HEADER_SIZE?(console.error("[PreScheduler] Message too large:",o),!1):v({atomicView:F,dataView:ee,uint8View:te,bufferConstants:S,ringBufferBase:d,controlIndices:se,oscMessage:e,maxSpins:10})?(f(12,1),!0):(t||console.warn("[PreScheduler] Ring buffer full, message will be queued for retry"),!1)},L=(e,t)=>{let r=n.length+i.length;if(r>=m){console.error("[PreScheduler] Backpressure: dropping retry ("+r+" pending)"),f(17,1);return}i.push({oscData:e,retryCount:0,context:t||"unknown",queuedAt:performance.now()}),h(18,i.length);let s=re(19);i.length>s&&h(19,i.length),u("[PreScheduler] Queued message for retry:",t,"queue size:",i.length)},Me=()=>{if(i.length===0)return;let e=0;for(;e<i.length;){let t=i[e];if(A(t.oscData,!0))i.splice(e,1),f(16,1),f(20,1),h(18,i.length),u("[PreScheduler] Retry succeeded for:",t.context,"after",t.retryCount+1,"attempts");else if(t.retryCount++,f(20,1),t.retryCount>=V){let s=`Ring buffer full - dropped message after ${V} retries (${t.context})`;console.error("[PreScheduler]",s),i.splice(e,1),f(17,1),h(18,i.length),self.postMessage({type:"error",error:s})}else e++}},Ie=(e,t,r)=>{let s=n.length+i.length;if(s>=m){let E=`Prescheduler queue full (${s} >= ${m} max)`;return console.warn("[PreScheduler]",E),self.postMessage({type:"error",error:E,code:"PRESCHEDULER_QUEUE_FULL"}),!1}let o=me(e);if(o===null)return u("[PreScheduler] Non-bundle message, dispatching immediately"),A(e,!1)||L(e,"immediate message"),!0;let c=Ee(),a=o-c;if(e.length>B){let E=`Bundle too large for scheduler (${e.length} > ${B} bytes)`;return console.warn("[PreScheduler]",E),self.postMessage({type:"error",error:E,code:"BUNDLE_TOO_LARGE"}),!1}if(a>W){let E=`Bundle scheduled too far in future (${a.toFixed(0)}s > ${W}s max)`;return console.warn("[PreScheduler]",E),self.postMessage({type:"error",error:E,code:"BUNDLE_TOO_FAR_FUTURE"}),!1}let g={ntpTime:o,seq:he++,sessionId:t||0,runTag:r||"",oscData:e};return Le(g),f(11,1),O(),u("[PreScheduler] Scheduled bundle:","NTP="+o.toFixed(3),"current="+c.toFixed(3),"wait="+(a*1e3).toFixed(1)+"ms","pending="+n.length),!0},Le=e=>{n.push(e),He(n.length-1)},Oe=()=>n.length>0?n[0]:null,Ne=()=>{if(n.length===0)return null;let e=n[0],t=n.pop();return n.length>0&&(n[0]=t,le(0)),e},He=e=>{for(;e>0;){let t=Math.floor((e-1)/2);if(b(n[e],n[t])>=0)break;ie(e,t),e=t}},le=e=>{let t=n.length;for(;;){let r=2*e+1,s=2*e+2,o=e;if(r<t&&b(n[r],n[o])<0&&(o=r),s<t&&b(n[s],n[o])<0&&(o=s),o===e)break;ie(e,o),e=o}},b=(e,t)=>e.ntpTime===t.ntpTime?e.seq-t.seq:e.ntpTime-t.ntpTime,ie=(e,t)=>{let r=n[e];n[e]=n[t],n[t]=r},xe=()=>{if(oe!==null){console.warn("[PreScheduler] Polling already started");return}u("[PreScheduler] Starting periodic polling (every "+ce+"ms)"),Se()};var Se=()=>{z=!0,Me();let e=Ee(),t=e+Ce,r=0;for(;n.length>0;){let s=Oe();if(s.ntpTime<=t){Ne(),O();let o=s.ntpTime-e;if(f(21,1),o<0)f(15,1);else{let a=Math.round(o*1e3),g=Pe(14);(g===j||a<g)&&ne(14,a)}u("[PreScheduler] Dispatching bundle:","NTP="+s.ntpTime.toFixed(3),"current="+e.toFixed(3),"early="+(o*1e3).toFixed(1)+"ms","remaining="+n.length),A(s.oscData,!1)||L(s.oscData,"scheduled bundle NTP="+s.ntpTime.toFixed(3)),r++}else break}(r>0||n.length>0||i.length>0)&&u("[PreScheduler] Dispatch cycle complete:","dispatched="+r,"pending="+n.length,"retrying="+i.length),z=!1,oe=setTimeout(Se,ce)},G=e=>{if(n.length===0)return;let t=n.length,r=[];for(let o=0;o<n.length;o++){let c=n[o];e(c)||r.push(c)}let s=t-r.length;s>0&&(n=r,ye(),f(13,s),O(),u("[PreScheduler] Cancelled "+s+" events, "+n.length+" remaining"))},ye=()=>{for(let e=Math.floor(n.length/2)-1;e>=0;e--)le(e)},Be=(e,t)=>{G(r=>r.sessionId===e&&r.runTag===t)},Fe=e=>{G(t=>t.sessionId===e)},we=e=>{G(t=>t.runTag===e)},be=()=>{if(n.length===0)return;let e=n.length;f(13,e),n=[],O(),u("[PreScheduler] Cancelled all "+e+" events")},Ge=e=>!e||e.length<8?!1:e[0]===35&&e[1]===98&&e[2]===117&&e[3]===110&&e[4]===100&&e[5]===108&&e[6]===101&&e[7]===0,ke=e=>{let t=[],r=new DataView(e.buffer,e.byteOffset,e.byteLength),s=16;for(;s+4<=e.length;){let o=r.getInt32(s,!1);if(s+=4,o<=0||o>de||s+o>e.length)break;let c=e.slice(s,s+o);for(t.push(c),s+=o;s%4!==0&&s<e.length;)s++}return t},Ye=e=>{if(Ge(e)){let t=ke(e);for(let r=0;r<t.length;r++)A(t[r],!1)||L(t[r],"immediate bundle message "+r)}else A(e,!1)||L(e,"immediate message")};self.addEventListener("message",e=>{let{data:t}=e;try{switch(t.type){case"init":R=t.mode||"sab",t.maxPendingMessages&&(m=t.maxPendingMessages),t.snapshotIntervalMs&&(w=t.snapshotIntervalMs),R==="sab"?(p=t.sharedBuffer,d=t.ringBufferBase,S=t.bufferConstants,Ae(),S&&S.scheduler_slot_size&&(B=S.scheduler_slot_size)):(I=new ArrayBuffer(128),l=new Uint32Array(I),De()),ne(14,j),xe(),u("[OSCPreSchedulerWorker] Initialized with NTP-based scheduling, mode="+R+", capacity="+m),self.postMessage({type:"initialized"});break;case"send":Ie(t.oscData,t.sessionId||0,t.runTag||"");break;case"sendImmediate":Ye(t.oscData);break;case"cancelSessionTag":t.runTag!==void 0&&t.runTag!==null&&t.runTag!==""&&Be(t.sessionId||0,t.runTag);break;case"cancelSession":Fe(t.sessionId||0);break;case"cancelTag":t.runTag!==void 0&&t.runTag!==null&&t.runTag!==""&&we(t.runTag);break;case"cancelAll":be();break;default:console.warn("[OSCPreSchedulerWorker] Unknown message type:",t.type)}}catch(r){console.error("[OSCPreSchedulerWorker] Error:",r),self.postMessage({type:"error",error:r.message})}});u("[OSCPreSchedulerWorker] Script loaded");})();
@@ -1,2 +1,2 @@
1
- (()=>{function C(l,e,t){return(t-1-l+e)%t}function O({uint8View:l,dataView:e,bufferStart:t,bufferSize:s,head:i,payload:a,sequence:n,messageMagic:h,headerSize:r}){let u=a.length,c=r+u+3&-4,o=s-i;if(c>o){let f=new Uint8Array(r),E=new DataView(f.buffer);E.setUint32(0,h,!0),E.setUint32(4,c,!0),E.setUint32(8,n,!0),E.setUint32(12,0,!0);let S=t+i,p=t;if(o>=r){l.set(f,S);let m=o-r;m>0&&l.set(a.subarray(0,m),S+r),l.set(a.subarray(m),p)}else{l.set(f.subarray(0,o),S),l.set(f.subarray(o),p);let m=r-o;l.set(a,p+m)}}else{let f=t+i;e.setUint32(f,h,!0),e.setUint32(f+4,c,!0),e.setUint32(f+8,n,!0),e.setUint32(f+12,0,!0),l.set(a,f+r)}return(i+c)%s}function I({uint8View:l,dataView:e,bufferStart:t,bufferSize:s,head:i,tail:a,messageMagic:n,paddingMagic:h,headerSize:r,maxMessages:u=1/0,onMessage:_,onCorruption:c}){let o=a,f=0;for(;o!==i&&f<u;){if(s-o<r){o=0;continue}let S=t+o,p=e.getUint32(S,!0);if(p===h){o=0;continue}if(p!==n){c&&c(o),o=(o+1)%s;continue}let m=e.getUint32(S+4,!0),T=e.getUint32(S+8,!0);if(m<r||m>s){c&&c(o),o=(o+1)%s;continue}let d=m-r,g=S+r,R=new Uint8Array(d);for(let w=0;w<d;w++)R[w]=l[g+w];_(R,T,m),o=(o+m)%s,f++}return{newTail:o,messagesRead:f}}var A=class extends AudioWorkletProcessor{constructor(){super(),this.mode="sab",this.sharedBuffer=null,this.wasmModule=null,this.wasmInstance=null,this.isInitialized=!1,this.processCallCount=0,this.lastStatusCheck=0,this.ringBufferBase=null,this.audioView=null,this.lastAudioBufferPtr=0,this.lastWasmBufferSize=0,this.lastTreeVersion=-1,this.treeSnapshotsSent=0,this.lastTreeSendTime=-1,this.treeSnapshotMinInterval=.025,this.atomicView=null,this.uint8View=null,this.dataView=null,this.localClockOffsetView=null,this.bufferConstants=null,this.CONTROL_INDICES=null,this.metricsView=null,this.STATUS_FLAGS={OK:0,BUFFER_FULL:1,OVERRUN:2,WASM_ERROR:4,FRAGMENTED_MSG:8},this.oscQueue=[],this.port.onmessage=this.handleMessage.bind(this)}loadBufferConstants(){if(!this.wasmInstance||!this.wasmInstance.exports.get_buffer_layout)throw new Error("WASM instance does not export get_buffer_layout");let e=this.wasmInstance.exports.get_buffer_layout(),t=this.wasmMemory;if(!t)throw new Error("WASM memory not available");let s=new Uint32Array(t.buffer,e,34),i=new Uint8Array(t.buffer,e,140);if(this.bufferConstants={IN_BUFFER_START:s[0],IN_BUFFER_SIZE:s[1],OUT_BUFFER_START:s[2],OUT_BUFFER_SIZE:s[3],DEBUG_BUFFER_START:s[4],DEBUG_BUFFER_SIZE:s[5],CONTROL_START:s[6],CONTROL_SIZE:s[7],METRICS_START:s[8],METRICS_SIZE:s[9],NODE_TREE_START:s[10],NODE_TREE_SIZE:s[11],NODE_TREE_HEADER_SIZE:s[12],NODE_TREE_ENTRY_SIZE:s[13],NODE_TREE_DEF_NAME_SIZE:s[14],NODE_TREE_MIRROR_MAX_NODES:s[15],NTP_START_TIME_START:s[16],NTP_START_TIME_SIZE:s[17],DRIFT_OFFSET_START:s[18],DRIFT_OFFSET_SIZE:s[19],GLOBAL_OFFSET_START:s[20],GLOBAL_OFFSET_SIZE:s[21],AUDIO_CAPTURE_START:s[22],AUDIO_CAPTURE_SIZE:s[23],AUDIO_CAPTURE_HEADER_SIZE:s[24],AUDIO_CAPTURE_FRAMES:s[25],AUDIO_CAPTURE_CHANNELS:s[26],AUDIO_CAPTURE_SAMPLE_RATE:s[27],TOTAL_BUFFER_SIZE:s[28],MAX_MESSAGE_SIZE:s[29],MESSAGE_MAGIC:s[30],PADDING_MAGIC:s[31],scheduler_slot_size:s[32],scheduler_slot_count:s[33],DEBUG_PADDING_MARKER:i[136],MESSAGE_HEADER_SIZE:16},this.bufferConstants.MESSAGE_MAGIC!==3735928559)throw new Error("Invalid buffer constants from WASM")}calculateBufferIndices(e){if(!this.bufferConstants)throw new Error("Buffer constants not loaded. Call loadBufferConstants() first.");let t=this.bufferConstants.CONTROL_START,s=this.bufferConstants.METRICS_START;if(this.CONTROL_INDICES={IN_HEAD:(e+t+0)/4,IN_TAIL:(e+t+4)/4,OUT_HEAD:(e+t+8)/4,OUT_TAIL:(e+t+12)/4,DEBUG_HEAD:(e+t+16)/4,DEBUG_TAIL:(e+t+20)/4,IN_SEQUENCE:(e+t+24)/4,OUT_SEQUENCE:(e+t+28)/4,DEBUG_SEQUENCE:(e+t+32)/4,STATUS_FLAGS:(e+t+36)/4,IN_WRITE_LOCK:(e+t+40)/4},this.mode==="sab"){let i=e+s;this.metricsView=new Uint32Array(this.sharedBuffer,i,this.bufferConstants.METRICS_SIZE/4)}else{this.atomicView=new Int32Array(this.wasmMemory.buffer),this.uint8View=new Uint8Array(this.wasmMemory.buffer),this.dataView=new DataView(this.wasmMemory.buffer);let i=e+s;this.metricsView=new Uint32Array(this.wasmMemory.buffer,i,this.bufferConstants.METRICS_SIZE/4)}}writeWorldOptionsToMemory(){if(!this.worldOptions||!this.wasmMemory)return;let e=this.ringBufferBase+65536,t=new Uint32Array(this.wasmMemory.buffer,e,32),s=new Float32Array(this.wasmMemory.buffer,e,32);t[0]=this.worldOptions.numBuffers||1024,t[1]=this.worldOptions.maxNodes||1024,t[2]=this.worldOptions.maxGraphDefs||1024,t[3]=this.worldOptions.maxWireBufs||64,t[4]=this.worldOptions.numAudioBusChannels||128,t[5]=this.worldOptions.numInputBusChannels||0,t[6]=this.worldOptions.numOutputBusChannels||0,t[7]=this.worldOptions.numControlBusChannels||4096,t[8]=this.worldOptions.bufLength||128,t[9]=this.worldOptions.realTimeMemorySize||16384,t[10]=this.worldOptions.numRGens||64,t[11]=this.worldOptions.realTime?1:0,t[12]=this.worldOptions.memoryLocking?1:0,t[13]=this.worldOptions.loadGraphDefs||0,t[14]=this.worldOptions.preferredSampleRate||0,t[15]=this.worldOptions.verbosity||0}js_debug(e){if(!(!this.uint8View||!this.atomicView||!this.CONTROL_INDICES||!this.ringBufferBase))try{let t=this.bufferConstants.DEBUG_BUFFER_START,s=this.bufferConstants.DEBUG_BUFFER_SIZE,i=this.bufferConstants.DEBUG_PADDING_MARKER,a="[JS] "+e+`
2
- `,h=new TextEncoder().encode(a);if(h.length>s)return;let r=this.CONTROL_INDICES.DEBUG_HEAD,u=this.atomicLoad(r),_=s-u,c=u;h.length>_&&(this.uint8View[this.ringBufferBase+t+u]=i,c=0);let o=this.ringBufferBase+t;for(let E=0;E<h.length;E++)this.uint8View[o+c+E]=h[E];let f=c+h.length;this.atomicStore(r,f)}catch{}}atomicLoad(e){return this.mode==="sab"?Atomics.load(this.atomicView,e):this.atomicView[e]}atomicStore(e,t){this.mode==="sab"?Atomics.store(this.atomicView,e,t):this.atomicView[e]=t}drainOscQueue(){if(this.oscQueue.length===0)return;let e=this.bufferConstants.IN_BUFFER_SIZE,t=this.bufferConstants.MESSAGE_HEADER_SIZE,s=this.ringBufferBase+this.bufferConstants.IN_BUFFER_START;for(;this.oscQueue.length>0;){let i=this.oscQueue[0],a=i.byteLength,h=t+a+3&-4,r=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD),u=this.atomicLoad(this.CONTROL_INDICES.IN_TAIL),_=C(r,u,e);if(h>_)break;this.oscQueue.shift();let c=this.atomicLoad(this.CONTROL_INDICES.IN_SEQUENCE);this.atomicStore(this.CONTROL_INDICES.IN_SEQUENCE,c+1);let o=new Uint8Array(i),f=O({uint8View:this.uint8View,dataView:this.dataView,bufferStart:s,bufferSize:e,head:r,payload:o,sequence:c,messageMagic:this.bufferConstants.MESSAGE_MAGIC,headerSize:t});this.atomicStore(this.CONTROL_INDICES.IN_HEAD,f)}}readOscReplies(){let e=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);if(e===t)return;let s=[],{newTail:i,messagesRead:a}=I({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.OUT_BUFFER_START,bufferSize:this.bufferConstants.OUT_BUFFER_SIZE,head:e,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,onMessage:(n,h)=>{s.push({oscData:n.buffer,sequence:h})}});a>0&&this.atomicStore(this.CONTROL_INDICES.OUT_TAIL,i),s.length>0&&this.port.postMessage({type:"oscReplies",messages:s})}readNodeTree(){if(!this.bufferConstants||!this.wasmMemory||this.ringBufferBase===null)return null;let e=this.bufferConstants,t=this.ringBufferBase+e.NODE_TREE_START,s=new Uint32Array(this.wasmMemory.buffer,t,2),i=s[0],a=s[1],n=t+e.NODE_TREE_HEADER_SIZE,h=e.NODE_TREE_MIRROR_MAX_NODES,r=e.NODE_TREE_ENTRY_SIZE,u=e.NODE_TREE_DEF_NAME_SIZE,_=new DataView(this.wasmMemory.buffer,n,h*r),c=[],o=0;for(let f=0;f<h&&o<i;f++){let E=f*r,S=_.getInt32(E,!0);if(S===-1)continue;o++;let p=n+E+24,m=new Uint8Array(this.wasmMemory.buffer,p,u),T="";for(let d=0;d<u&&m[d]!==0;d++)T+=String.fromCharCode(m[d]);c.push({id:S,parentId:_.getInt32(E+4,!0),isGroup:_.getInt32(E+8,!0)===1,prevId:_.getInt32(E+12,!0),nextId:_.getInt32(E+16,!0),headId:_.getInt32(E+20,!0),defName:T})}return{nodeCount:i,version:a,nodes:c}}readMetrics(){return this.metricsView?new Uint32Array(this.metricsView):null}checkAndSendSnapshot(e){let t=this.bufferConstants;if(!t||!this.wasmMemory||this.ringBufferBase===null)return;let s=this.ringBufferBase+t.NODE_TREE_START,a=new Uint32Array(this.wasmMemory.buffer,s,2)[1];if(a!==this.lastTreeVersion)this.lastTreeVersion=a,this.lastTreeSendTime=e;else{if(this.lastTreeSendTime>=0&&e-this.lastTreeSendTime<this.treeSnapshotMinInterval)return;this.lastTreeSendTime=e}let h=this.readMetricsAndTreeBuffer();h&&(this.treeSnapshotsSent++,this.port.postMessage({type:"snapshot",buffer:h,snapshotsSent:this.treeSnapshotsSent},[h]))}readMetricsAndTreeBuffer(){if(!this.bufferConstants||!this.wasmMemory||this.ringBufferBase===null)return null;let e=this.bufferConstants,t=this.ringBufferBase+e.METRICS_START,s=e.METRICS_SIZE+e.NODE_TREE_SIZE,i=new Uint8Array(this.wasmMemory.buffer,t,s),a=new ArrayBuffer(s);return new Uint8Array(a).set(i),a}readDebugMessages(){let e=this.atomicLoad(this.CONTROL_INDICES.DEBUG_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.DEBUG_TAIL);if(e===t)return;let s=[],{newTail:i,messagesRead:a}=I({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.DEBUG_BUFFER_START,bufferSize:this.bufferConstants.DEBUG_BUFFER_SIZE,head:e,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,onMessage:(n,h)=>{s.push({bytes:n.buffer,sequence:h})}});a>0&&this.atomicStore(this.CONTROL_INDICES.DEBUG_TAIL,i),s.length>0&&this.port.postMessage({type:"debugRawBatch",messages:s},s.map(n=>n.bytes))}async handleMessage(e){let{data:t}=e;try{if(t.type==="osc"){this.mode==="postMessage"&&t.oscData&&this.oscQueue.push(t.oscData);return}if(t.type==="init"&&(this.mode=t.mode||"sab",t.snapshotIntervalMs&&(this.treeSnapshotMinInterval=t.snapshotIntervalMs/1e3),this.mode==="sab"&&t.sharedBuffer&&(this.sharedBuffer=t.sharedBuffer,this.atomicView=new Int32Array(this.sharedBuffer),this.uint8View=new Uint8Array(this.sharedBuffer),this.dataView=new DataView(this.sharedBuffer))),t.type==="loadWasm"){if(t.wasmBytes){let s;if(this.mode==="sab"){if(s=t.wasmMemory,!s){this.port.postMessage({type:"error",error:"No WASM memory provided!"});return}}else{let n=t.memoryPages||1280;s=new WebAssembly.Memory({initial:n,maximum:n,shared:!0})}this.wasmMemory=s,this.worldOptions=t.worldOptions||{},this.sampleRate=t.sampleRate||48e3;let i={env:{memory:s,emscripten_asm_const_double:()=>Date.now()*1e3,__syscall_getdents64:()=>0,__syscall_unlinkat:()=>0,_emscripten_init_main_thread_js:()=>{},_emscripten_thread_mailbox_await:()=>{},_emscripten_thread_set_strongref:()=>{},emscripten_exit_with_live_runtime:()=>{},_emscripten_receive_on_main_thread_js:()=>{},emscripten_check_blocking_allowed:()=>{},_emscripten_thread_cleanup:()=>{},emscripten_num_logical_cores:()=>1,_emscripten_notify_mailbox_postmessage:()=>{}},wasi_snapshot_preview1:{clock_time_get:(n,h,r)=>{let u=new DataView(s.buffer),_=BigInt(Math.floor(Date.now()*1e6));return u.setBigUint64(r,_,!0),0},environ_sizes_get:()=>0,environ_get:()=>0,fd_close:()=>0,fd_write:()=>0,fd_seek:()=>0,fd_read:()=>0,proc_exit:n=>{console.error("[AudioWorklet] WASM tried to exit with code:",n)}}},a=await WebAssembly.compile(t.wasmBytes);if(this.wasmInstance=await WebAssembly.instantiate(a,i),this.wasmInstance.exports.get_ring_buffer_base&&(this.ringBufferBase=this.wasmInstance.exports.get_ring_buffer_base(),this.loadBufferConstants(),this.calculateBufferIndices(this.ringBufferBase),this.writeWorldOptionsToMemory(),this.wasmInstance.exports.init_memory)){this.wasmInstance.exports.init_memory(this.sampleRate),this.isInitialized=!0;let n=this.mode==="postMessage"?this.readMetricsAndTreeBuffer():void 0,h={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:n};this.port.postMessage(h,n?[n]:[])}}else if(t.wasmInstance&&(this.wasmInstance=t.wasmInstance,this.wasmInstance.exports.get_ring_buffer_base&&(this.ringBufferBase=this.wasmInstance.exports.get_ring_buffer_base(),this.loadBufferConstants(),this.calculateBufferIndices(this.ringBufferBase),this.writeWorldOptionsToMemory(),this.wasmInstance.exports.init_memory))){this.wasmInstance.exports.init_memory(this.sampleRate),this.isInitialized=!0;let s=this.mode==="postMessage"?this.readMetricsAndTreeBuffer():void 0,i={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:s};this.port.postMessage(i,s?[s]:[])}}if(t.type==="getVersion")if(this.wasmInstance&&this.wasmInstance.exports.get_supersonic_version_string){let s=this.wasmInstance.exports.get_supersonic_version_string(),i=new Uint8Array(this.wasmMemory.buffer),a="";for(let n=s;i[n]!==0;n++)a+=String.fromCharCode(i[n]);this.port.postMessage({type:"version",version:a})}else this.port.postMessage({type:"version",version:"unknown"});if(t.type==="getTimeOffset")if(this.wasmInstance&&this.wasmInstance.exports.get_time_offset){let s=this.wasmInstance.exports.get_time_offset();this.port.postMessage({type:"timeOffset",offset:s})}else console.error("[AudioWorklet] get_time_offset not available! wasmInstance:",!!this.wasmInstance),this.port.postMessage({type:"error",error:"get_time_offset function not available in WASM exports"});if(t.type==="setNTPStartTime"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.NTP_START_TIME_START,i=new Float64Array(this.wasmMemory.buffer,s,1);i[0]=t.ntpStartTime}if(t.type==="setDriftOffset"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.DRIFT_OFFSET_START,i=new Int32Array(this.wasmMemory.buffer,s,1);i[0]=t.driftOffsetMs}if(t.type==="setGlobalOffset"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.GLOBAL_OFFSET_START,i=new Int32Array(this.wasmMemory.buffer,s,1);i[0]=t.globalOffsetMs}if(t.type==="getMetrics"){let s=this.metricsView?new Uint32Array(this.metricsView):null;this.port.postMessage({type:"metricsSnapshot",requestId:t.requestId,metrics:s})}if(t.type==="copyBufferData")try{let{copyId:s,ptr:i,data:a}=t;if(!this.wasmMemory||!this.wasmMemory.buffer)throw new Error("WASM memory not initialized");let n=new Float32Array(a);new Float32Array(this.wasmMemory.buffer,i,n.length).set(n),this.port.postMessage({type:"bufferCopied",copyId:s,success:!0})}catch(s){console.error("[AudioWorklet] Buffer copy failed:",s),this.port.postMessage({type:"bufferCopied",copyId:t.copyId,success:!1,error:s.message})}}catch(s){console.error("[AudioWorklet] Error handling message:",s),this.port.postMessage({type:"error",error:s.message,stack:s.stack})}}process(e,t,s){if(this.processCallCount++,!this.isInitialized)return!0;try{if(this.wasmInstance&&this.wasmInstance.exports.process_audio){this.mode==="postMessage"&&this.drainOscQueue();let i=currentTime,a=e[0]?.length||0,n=t[0]?.length||0;if(a>0&&this.wasmInstance?.exports?.get_audio_input_bus)try{let r=this.wasmInstance.exports.get_audio_input_bus(),u=this.wasmInstance.exports.get_audio_buffer_samples();if(r&&r>0){let _=this.sharedBuffer||this.wasmMemory?.buffer;if(_){let c=this.worldOptions?.numInputBusChannels||2,o=Math.min(a,c);(!this.inputView||this.lastInputBusPtr!==r||this.lastInputChannels!==c)&&(this.inputView=new Float32Array(_,r,u*c),this.lastInputBusPtr=r,this.lastInputChannels=c);for(let f=0;f<o;f++)e[0]?.[f]&&this.inputView.set(e[0][f],f*u)}}}catch{}let h=this.wasmInstance.exports.process_audio(i,n,a);if(this.wasmInstance.exports.get_audio_output_bus&&t[0]&&t[0].length>=2)try{let r=this.wasmInstance.exports.get_audio_output_bus(),u=this.wasmInstance.exports.get_audio_buffer_samples();if(r&&r>0){let _=this.wasmInstance.exports.memory||this.wasmMemory;if(!_||!_.buffer)return!0;let c=_.buffer,o=c.byteLength,f=r+u*2*4;if(r<0||r>o||f>o)return!0;(!this.audioView||this.lastAudioBufferPtr!==r||this.lastWasmBufferSize!==o||c!==this.audioView.buffer)&&(this.audioView=new Float32Array(c,r,u*2),this.lastAudioBufferPtr=r,this.lastWasmBufferSize=o),t[0][0].set(this.audioView.subarray(0,u)),t[0][1].set(this.audioView.subarray(u,u*2))}}catch{}if(this.mode==="postMessage")this.readOscReplies(),this.readDebugMessages(),this.checkAndSendSnapshot(i);else if(this.atomicView){let r=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),u=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);r!==u&&Atomics.notify(this.atomicView,this.CONTROL_INDICES.OUT_HEAD,1)}return this.processCallCount%3750===0&&this.checkStatus(),h!==0}}catch(i){console.error("[AudioWorklet] process() error:",i),console.error("[AudioWorklet] Stack:",i.stack),this.atomicView&&this.mode==="sab"&&Atomics.or(this.atomicView,this.CONTROL_INDICES.STATUS_FLAGS,this.STATUS_FLAGS.WASM_ERROR)}return!0}checkStatus(){if(!this.atomicView)return;let e=this.atomicLoad(this.CONTROL_INDICES.STATUS_FLAGS);if(e!==this.STATUS_FLAGS.OK){let t={bufferFull:!!(e&this.STATUS_FLAGS.BUFFER_FULL),overrun:!!(e&this.STATUS_FLAGS.OVERRUN),wasmError:!!(e&this.STATUS_FLAGS.WASM_ERROR),fragmented:!!(e&this.STATUS_FLAGS.FRAGMENTED_MSG)},s={processCount:this.metricsView[0],messagesProcessed:this.metricsView[1],messagesDropped:this.metricsView[2],schedulerQueueDepth:this.metricsView[3],schedulerQueueMax:this.metricsView[4],schedulerQueueDropped:this.metricsView[5]};this.port.postMessage({type:"status",flags:e,status:t,metrics:s});let i=e&this.STATUS_FLAGS.BUFFER_FULL;this.atomicStore(this.CONTROL_INDICES.STATUS_FLAGS,i)}}};registerProcessor("scsynth-processor",A);})();
1
+ (()=>{function C(m,e,t){return(t-1-m+e)%t}function D({uint8View:m,dataView:e,bufferStart:t,bufferSize:s,head:i,payload:a,sequence:n,messageMagic:c,headerSize:r}){let _=a.length,h=r+_+3&-4,o=s-i;if(h>o){let f=new Uint8Array(r),u=new DataView(f.buffer);u.setUint32(0,c,!0),u.setUint32(4,h,!0),u.setUint32(8,n,!0),u.setUint32(12,0,!0);let l=t+i,T=t;if(o>=r){m.set(f,l);let S=o-r;S>0&&m.set(a.subarray(0,S),l+r),m.set(a.subarray(S),T)}else{m.set(f.subarray(0,o),l),m.set(f.subarray(o),T);let S=r-o;m.set(a,T+S)}}else{let f=t+i;e.setUint32(f,c,!0),e.setUint32(f+4,h,!0),e.setUint32(f+8,n,!0),e.setUint32(f+12,0,!0),m.set(a,f+r)}return(i+h)%s}function R({uint8View:m,dataView:e,bufferStart:t,bufferSize:s,head:i,tail:a,messageMagic:n,paddingMagic:c,headerSize:r,maxMessages:_=1/0,onMessage:E,onCorruption:h}){let o=a,f=0;for(;o!==i&&f<_;){if(s-o<r){o=0;continue}let l=t+o,T=e.getUint32(l,!0);if(T===c){o=0;continue}if(T!==n){h&&h(o),o=(o+1)%s;continue}let S=e.getUint32(l+4,!0),d=e.getUint32(l+8,!0);if(S<r||S>s){h&&h(o),o=(o+1)%s;continue}let p=S-r,M=l+r,A=new Uint8Array(p);for(let w=0;w<p;w++)A[w]=m[M+w];E(A,d,S),o=(o+S)%s,f++}return{newTail:o,messagesRead:f}}var I=class extends AudioWorkletProcessor{constructor(){super(),this.mode="sab",this.sharedBuffer=null,this.wasmModule=null,this.wasmInstance=null,this.isInitialized=!1,this.processCallCount=0,this.lastStatusCheck=0,this.ringBufferBase=null,this.audioView=null,this.lastAudioBufferPtr=0,this.lastWasmBufferSize=0,this.lastTreeVersion=-1,this.treeSnapshotsSent=0,this.lastTreeSendTime=-1,this.treeSnapshotMinInterval=.05,this.atomicView=null,this.uint8View=null,this.dataView=null,this.localClockOffsetView=null,this.bufferConstants=null,this.CONTROL_INDICES=null,this.metricsView=null,this.STATUS_FLAGS={OK:0,BUFFER_FULL:1,OVERRUN:2,WASM_ERROR:4,FRAGMENTED_MSG:8},this.oscQueue=[],this.port.onmessage=this.handleMessage.bind(this)}loadBufferConstants(){if(!this.wasmInstance||!this.wasmInstance.exports.get_buffer_layout)throw new Error("WASM instance does not export get_buffer_layout");let e=this.wasmInstance.exports.get_buffer_layout(),t=this.wasmMemory;if(!t)throw new Error("WASM memory not available");let s=new Uint32Array(t.buffer,e,34),i=new Uint8Array(t.buffer,e,140);if(this.bufferConstants={IN_BUFFER_START:s[0],IN_BUFFER_SIZE:s[1],OUT_BUFFER_START:s[2],OUT_BUFFER_SIZE:s[3],DEBUG_BUFFER_START:s[4],DEBUG_BUFFER_SIZE:s[5],CONTROL_START:s[6],CONTROL_SIZE:s[7],METRICS_START:s[8],METRICS_SIZE:s[9],NODE_TREE_START:s[10],NODE_TREE_SIZE:s[11],NODE_TREE_HEADER_SIZE:s[12],NODE_TREE_ENTRY_SIZE:s[13],NODE_TREE_DEF_NAME_SIZE:s[14],NODE_TREE_MIRROR_MAX_NODES:s[15],NTP_START_TIME_START:s[16],NTP_START_TIME_SIZE:s[17],DRIFT_OFFSET_START:s[18],DRIFT_OFFSET_SIZE:s[19],GLOBAL_OFFSET_START:s[20],GLOBAL_OFFSET_SIZE:s[21],AUDIO_CAPTURE_START:s[22],AUDIO_CAPTURE_SIZE:s[23],AUDIO_CAPTURE_HEADER_SIZE:s[24],AUDIO_CAPTURE_FRAMES:s[25],AUDIO_CAPTURE_CHANNELS:s[26],AUDIO_CAPTURE_SAMPLE_RATE:s[27],TOTAL_BUFFER_SIZE:s[28],MAX_MESSAGE_SIZE:s[29],MESSAGE_MAGIC:s[30],PADDING_MAGIC:s[31],scheduler_slot_size:s[32],scheduler_slot_count:s[33],DEBUG_PADDING_MARKER:i[136],MESSAGE_HEADER_SIZE:16},this.bufferConstants.MESSAGE_MAGIC!==3735928559)throw new Error("Invalid buffer constants from WASM")}calculateBufferIndices(e){if(!this.bufferConstants)throw new Error("Buffer constants not loaded. Call loadBufferConstants() first.");let t=this.bufferConstants.CONTROL_START,s=this.bufferConstants.METRICS_START;if(this.CONTROL_INDICES={IN_HEAD:(e+t+0)/4,IN_TAIL:(e+t+4)/4,OUT_HEAD:(e+t+8)/4,OUT_TAIL:(e+t+12)/4,DEBUG_HEAD:(e+t+16)/4,DEBUG_TAIL:(e+t+20)/4,IN_SEQUENCE:(e+t+24)/4,OUT_SEQUENCE:(e+t+28)/4,DEBUG_SEQUENCE:(e+t+32)/4,STATUS_FLAGS:(e+t+36)/4,IN_WRITE_LOCK:(e+t+40)/4},this.mode==="sab"){let i=e+s;this.metricsView=new Uint32Array(this.sharedBuffer,i,this.bufferConstants.METRICS_SIZE/4)}else{this.atomicView=new Int32Array(this.wasmMemory.buffer),this.uint8View=new Uint8Array(this.wasmMemory.buffer),this.dataView=new DataView(this.wasmMemory.buffer);let i=e+s;this.metricsView=new Uint32Array(this.wasmMemory.buffer,i,this.bufferConstants.METRICS_SIZE/4)}}writeWorldOptionsToMemory(){if(!this.worldOptions||!this.wasmMemory)return;let e=this.ringBufferBase+65536,t=new Uint32Array(this.wasmMemory.buffer,e,32),s=new Float32Array(this.wasmMemory.buffer,e,32);t[0]=this.worldOptions.numBuffers||1024,t[1]=this.worldOptions.maxNodes||1024,t[2]=this.worldOptions.maxGraphDefs||1024,t[3]=this.worldOptions.maxWireBufs||64,t[4]=this.worldOptions.numAudioBusChannels||128,t[5]=this.worldOptions.numInputBusChannels||0,t[6]=this.worldOptions.numOutputBusChannels||0,t[7]=this.worldOptions.numControlBusChannels||4096,t[8]=this.worldOptions.bufLength||128,t[9]=this.worldOptions.realTimeMemorySize||16384,t[10]=this.worldOptions.numRGens||64,t[11]=this.worldOptions.realTime?1:0,t[12]=this.worldOptions.memoryLocking?1:0,t[13]=this.worldOptions.loadGraphDefs||0,t[14]=this.worldOptions.preferredSampleRate||0,t[15]=this.worldOptions.verbosity||0}js_debug(e){if(!(!this.uint8View||!this.atomicView||!this.CONTROL_INDICES||!this.ringBufferBase))try{let t=this.bufferConstants.DEBUG_BUFFER_START,s=this.bufferConstants.DEBUG_BUFFER_SIZE,i=this.bufferConstants.DEBUG_PADDING_MARKER,a="[JS] "+e+`
2
+ `,c=new TextEncoder().encode(a);if(c.length>s)return;let r=this.CONTROL_INDICES.DEBUG_HEAD,_=this.atomicLoad(r),E=s-_,h=_;c.length>E&&(this.uint8View[this.ringBufferBase+t+_]=i,h=0);let o=this.ringBufferBase+t;for(let u=0;u<c.length;u++)this.uint8View[o+h+u]=c[u];let f=h+c.length;this.atomicStore(r,f)}catch{}}atomicLoad(e){return this.mode==="sab"?Atomics.load(this.atomicView,e):this.atomicView[e]}atomicStore(e,t){this.mode==="sab"?Atomics.store(this.atomicView,e,t):this.atomicView[e]=t}drainOscQueue(){if(this.oscQueue.length===0)return;let e=this.bufferConstants.IN_BUFFER_SIZE,t=this.bufferConstants.MESSAGE_HEADER_SIZE,s=this.ringBufferBase+this.bufferConstants.IN_BUFFER_START;for(;this.oscQueue.length>0;){let i=this.oscQueue[0],a=i.byteLength,c=t+a+3&-4,r=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD),_=this.atomicLoad(this.CONTROL_INDICES.IN_TAIL),E=C(r,_,e);if(c>E)break;this.oscQueue.shift();let h=this.atomicLoad(this.CONTROL_INDICES.IN_SEQUENCE);this.atomicStore(this.CONTROL_INDICES.IN_SEQUENCE,h+1);let o=new Uint8Array(i),f=D({uint8View:this.uint8View,dataView:this.dataView,bufferStart:s,bufferSize:e,head:r,payload:o,sequence:h,messageMagic:this.bufferConstants.MESSAGE_MAGIC,headerSize:t});this.atomicStore(this.CONTROL_INDICES.IN_HEAD,f)}}readOscReplies(){let e=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);if(e===t)return;let s=[],{newTail:i,messagesRead:a}=R({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.OUT_BUFFER_START,bufferSize:this.bufferConstants.OUT_BUFFER_SIZE,head:e,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,onMessage:(n,c)=>{s.push({oscData:n.buffer,sequence:c})}});a>0&&this.atomicStore(this.CONTROL_INDICES.OUT_TAIL,i),s.length>0&&this.port.postMessage({type:"oscReplies",messages:s})}readNodeTree(){if(!this.bufferConstants||!this.wasmMemory||this.ringBufferBase===null)return null;let e=this.bufferConstants,t=this.ringBufferBase+e.NODE_TREE_START,s=new Uint32Array(this.wasmMemory.buffer,t,2),i=s[0],a=s[1],n=t+e.NODE_TREE_HEADER_SIZE,c=e.NODE_TREE_MIRROR_MAX_NODES,r=e.NODE_TREE_ENTRY_SIZE,_=e.NODE_TREE_DEF_NAME_SIZE,E=new DataView(this.wasmMemory.buffer,n,c*r),h=[],o=0;for(let f=0;f<c&&o<i;f++){let u=f*r,l=E.getInt32(u,!0);if(l===-1)continue;o++;let T=n+u+24,S=new Uint8Array(this.wasmMemory.buffer,T,_),d="";for(let p=0;p<_&&S[p]!==0;p++)d+=String.fromCharCode(S[p]);h.push({id:l,parentId:E.getInt32(u+4,!0),isGroup:E.getInt32(u+8,!0)===1,prevId:E.getInt32(u+12,!0),nextId:E.getInt32(u+16,!0),headId:E.getInt32(u+20,!0),defName:d})}return{nodeCount:i,version:a,nodes:h}}readMetrics(){return this.metricsView?new Uint32Array(this.metricsView):null}checkAndSendSnapshot(e){let t=this.bufferConstants;if(!t||!this.wasmMemory||this.ringBufferBase===null)return;let s=this.ringBufferBase+t.NODE_TREE_START,a=new Uint32Array(this.wasmMemory.buffer,s,2)[1];if(a!==this.lastTreeVersion)this.lastTreeVersion=a,this.lastTreeSendTime=e;else{if(this.lastTreeSendTime>=0&&e-this.lastTreeSendTime<this.treeSnapshotMinInterval)return;this.lastTreeSendTime=e}let c=this.readMetricsAndTreeBuffer();c&&(this.treeSnapshotsSent++,this.port.postMessage({type:"snapshot",buffer:c,snapshotsSent:this.treeSnapshotsSent},[c]))}readMetricsAndTreeBuffer(){if(!this.bufferConstants||!this.wasmMemory||this.ringBufferBase===null)return null;let e=this.bufferConstants,t=this.ringBufferBase+e.METRICS_START,s=e.METRICS_SIZE+e.NODE_TREE_SIZE,i=new Uint8Array(this.wasmMemory.buffer,t,s),a=new ArrayBuffer(s);return new Uint8Array(a).set(i),a}readDebugMessages(){let e=this.atomicLoad(this.CONTROL_INDICES.DEBUG_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.DEBUG_TAIL);if(e===t)return;let s=[],{newTail:i,messagesRead:a}=R({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.DEBUG_BUFFER_START,bufferSize:this.bufferConstants.DEBUG_BUFFER_SIZE,head:e,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,onMessage:(n,c)=>{s.push({bytes:n.buffer,sequence:c})}});a>0&&this.atomicStore(this.CONTROL_INDICES.DEBUG_TAIL,i),s.length>0&&this.port.postMessage({type:"debugRawBatch",messages:s},s.map(n=>n.bytes))}async handleMessage(e){let{data:t}=e;try{if(t.type==="osc"){this.mode==="postMessage"&&t.oscData&&this.oscQueue.push(t.oscData);return}if(t.type==="init"&&(this.mode=t.mode||"sab",t.snapshotIntervalMs&&(this.treeSnapshotMinInterval=t.snapshotIntervalMs/1e3),this.mode==="sab"&&t.sharedBuffer&&(this.sharedBuffer=t.sharedBuffer,this.atomicView=new Int32Array(this.sharedBuffer),this.uint8View=new Uint8Array(this.sharedBuffer),this.dataView=new DataView(this.sharedBuffer))),t.type==="loadWasm"){if(t.wasmBytes){let s;if(this.mode==="sab"){if(s=t.wasmMemory,!s){this.port.postMessage({type:"error",error:"No WASM memory provided!"});return}}else{let n=t.memoryPages||1280;s=new WebAssembly.Memory({initial:n,maximum:n,shared:!0})}this.wasmMemory=s,this.worldOptions=t.worldOptions||{},this.sampleRate=t.sampleRate||48e3;let i={env:{memory:s,emscripten_asm_const_double:()=>Date.now()*1e3,__syscall_getdents64:()=>0,__syscall_unlinkat:()=>0,_emscripten_init_main_thread_js:()=>{},_emscripten_thread_mailbox_await:()=>{},_emscripten_thread_set_strongref:()=>{},emscripten_exit_with_live_runtime:()=>{},_emscripten_receive_on_main_thread_js:()=>{},emscripten_check_blocking_allowed:()=>{},_emscripten_thread_cleanup:()=>{},emscripten_num_logical_cores:()=>1,_emscripten_notify_mailbox_postmessage:()=>{}},wasi_snapshot_preview1:{clock_time_get:(n,c,r)=>{let _=new DataView(s.buffer),E=BigInt(Math.floor(Date.now()*1e6));return _.setBigUint64(r,E,!0),0},environ_sizes_get:()=>0,environ_get:()=>0,fd_close:()=>0,fd_write:()=>0,fd_seek:()=>0,fd_read:()=>0,proc_exit:n=>{console.error("[AudioWorklet] WASM tried to exit with code:",n)}}},a=await WebAssembly.compile(t.wasmBytes);if(this.wasmInstance=await WebAssembly.instantiate(a,i),this.wasmInstance.exports.get_ring_buffer_base&&(this.ringBufferBase=this.wasmInstance.exports.get_ring_buffer_base(),this.loadBufferConstants(),this.calculateBufferIndices(this.ringBufferBase),this.writeWorldOptionsToMemory(),this.wasmInstance.exports.init_memory)){this.wasmInstance.exports.init_memory(this.sampleRate),this.isInitialized=!0;let n=this.mode==="postMessage"?this.readMetricsAndTreeBuffer():void 0,c={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:n};this.port.postMessage(c,n?[n]:[])}}else if(t.wasmInstance&&(this.wasmInstance=t.wasmInstance,this.wasmInstance.exports.get_ring_buffer_base&&(this.ringBufferBase=this.wasmInstance.exports.get_ring_buffer_base(),this.loadBufferConstants(),this.calculateBufferIndices(this.ringBufferBase),this.writeWorldOptionsToMemory(),this.wasmInstance.exports.init_memory))){this.wasmInstance.exports.init_memory(this.sampleRate),this.isInitialized=!0;let s=this.mode==="postMessage"?this.readMetricsAndTreeBuffer():void 0,i={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:s};this.port.postMessage(i,s?[s]:[])}}if(t.type==="getVersion")if(this.wasmInstance&&this.wasmInstance.exports.get_supersonic_version_string){let s=this.wasmInstance.exports.get_supersonic_version_string(),i=new Uint8Array(this.wasmMemory.buffer),a="";for(let n=s;i[n]!==0;n++)a+=String.fromCharCode(i[n]);this.port.postMessage({type:"version",version:a})}else this.port.postMessage({type:"version",version:"unknown"});if(t.type==="getTimeOffset")if(this.wasmInstance&&this.wasmInstance.exports.get_time_offset){let s=this.wasmInstance.exports.get_time_offset();this.port.postMessage({type:"timeOffset",offset:s})}else console.error("[AudioWorklet] get_time_offset not available! wasmInstance:",!!this.wasmInstance),this.port.postMessage({type:"error",error:"get_time_offset function not available in WASM exports"});if(t.type==="setNTPStartTime"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.NTP_START_TIME_START,i=new Float64Array(this.wasmMemory.buffer,s,1);i[0]=t.ntpStartTime}if(t.type==="setDriftOffset"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.DRIFT_OFFSET_START,i=new Int32Array(this.wasmMemory.buffer,s,1);i[0]=t.driftOffsetMs}if(t.type==="setGlobalOffset"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.GLOBAL_OFFSET_START,i=new Int32Array(this.wasmMemory.buffer,s,1);i[0]=t.globalOffsetMs}if(t.type==="getMetrics"){let s=this.metricsView?new Uint32Array(this.metricsView):null;this.port.postMessage({type:"metricsSnapshot",requestId:t.requestId,metrics:s})}if(t.type==="copyBufferData")try{let{copyId:s,ptr:i,data:a}=t;if(!this.wasmMemory||!this.wasmMemory.buffer)throw new Error("WASM memory not initialized");let n=new Float32Array(a);new Float32Array(this.wasmMemory.buffer,i,n.length).set(n),this.port.postMessage({type:"bufferCopied",copyId:s,success:!0})}catch(s){console.error("[AudioWorklet] Buffer copy failed:",s),this.port.postMessage({type:"bufferCopied",copyId:t.copyId,success:!1,error:s.message})}}catch(s){console.error("[AudioWorklet] Error handling message:",s),this.port.postMessage({type:"error",error:s.message,stack:s.stack})}}process(e,t,s){if(this.processCallCount++,!this.isInitialized)return!0;try{if(this.wasmInstance&&this.wasmInstance.exports.process_audio){this.mode==="postMessage"&&this.drainOscQueue();let i=currentTime,a=e[0]?.length||0,n=t[0]?.length||0;if(a>0&&this.wasmInstance?.exports?.get_audio_input_bus)try{let r=this.wasmInstance.exports.get_audio_input_bus(),_=this.wasmInstance.exports.get_audio_buffer_samples();if(r&&r>0){let E=this.sharedBuffer||this.wasmMemory?.buffer;if(E){let h=this.worldOptions?.numInputBusChannels||2,o=Math.min(a,h);(!this.inputView||this.lastInputBusPtr!==r||this.lastInputChannels!==h)&&(this.inputView=new Float32Array(E,r,_*h),this.lastInputBusPtr=r,this.lastInputChannels=h);for(let f=0;f<o;f++)e[0]?.[f]&&this.inputView.set(e[0][f],f*_)}}}catch{}let c=this.wasmInstance.exports.process_audio(i,n,a);if(this.wasmInstance.exports.get_audio_output_bus&&t[0]&&t[0].length>=2)try{let r=this.wasmInstance.exports.get_audio_output_bus(),_=this.wasmInstance.exports.get_audio_buffer_samples();if(r&&r>0){let E=this.wasmInstance.exports.memory||this.wasmMemory;if(!E||!E.buffer)return!0;let h=E.buffer,o=h.byteLength,f=r+_*2*4;if(r<0||r>o||f>o)return!0;(!this.audioView||this.lastAudioBufferPtr!==r||this.lastWasmBufferSize!==o||h!==this.audioView.buffer)&&(this.audioView=new Float32Array(h,r,_*2),this.lastAudioBufferPtr=r,this.lastWasmBufferSize=o),t[0][0].set(this.audioView.subarray(0,_)),t[0][1].set(this.audioView.subarray(_,_*2))}}catch{}if(this.mode==="postMessage")this.readOscReplies(),this.readDebugMessages(),this.checkAndSendSnapshot(i);else if(this.atomicView){let r=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),_=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);r!==_&&Atomics.notify(this.atomicView,this.CONTROL_INDICES.OUT_HEAD,1)}return this.processCallCount%3750===0&&this.checkStatus(),c!==0}}catch(i){console.error("[AudioWorklet] process() error:",i),console.error("[AudioWorklet] Stack:",i.stack),this.atomicView&&this.mode==="sab"&&Atomics.or(this.atomicView,this.CONTROL_INDICES.STATUS_FLAGS,this.STATUS_FLAGS.WASM_ERROR),this.metricsView&&(this.mode==="sab"?Atomics.add(this.metricsView,7,1):this.metricsView[7]++)}return!0}checkStatus(){if(!this.atomicView)return;let e=this.atomicLoad(this.CONTROL_INDICES.STATUS_FLAGS);if(e!==this.STATUS_FLAGS.OK){let t={bufferFull:!!(e&this.STATUS_FLAGS.BUFFER_FULL),overrun:!!(e&this.STATUS_FLAGS.OVERRUN),wasmError:!!(e&this.STATUS_FLAGS.WASM_ERROR),fragmented:!!(e&this.STATUS_FLAGS.FRAGMENTED_MSG)},s={processCount:this.metricsView[0],messagesProcessed:this.metricsView[1],messagesDropped:this.metricsView[2],schedulerQueueDepth:this.metricsView[3],schedulerQueueMax:this.metricsView[4],schedulerQueueDropped:this.metricsView[5]};this.port.postMessage({type:"status",flags:e,status:t,metrics:s});let i=e&this.STATUS_FLAGS.BUFFER_FULL;this.atomicStore(this.CONTROL_INDICES.STATUS_FLAGS,i)}}};registerProcessor("scsynth-processor",I);})();