supersonic-scsynth-core 0.32.0 → 0.33.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
package/wasm/scsynth-nrt.wasm
CHANGED
|
Binary file
|
package/workers/debug_worker.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(()=>{function
|
|
2
|
-
`)&&(c=c.slice(0,-1)),s.push({text:c,timestamp:performance.now(),sequence:
|
|
3
|
-
`)&&(
|
|
1
|
+
(()=>{function m({uint8View:e,dataView:t,bufferStart:s,bufferSize:o,head:a,tail:i,messageMagic:f,paddingMagic:g,headerSize:c,maxMessages:L=1/0,onMessage:N,onCorruption:R}){let r=i,C=0;for(;r!==a&&C<L;){if(o-r<c){r=0;continue}let U=s+r,B=t.getUint32(U,!0);if(B===g){r=0;continue}if(B!==f){R&&R(r),r=(r+1)%o;continue}let D=t.getUint32(U+4,!0),M=t.getUint32(U+8,!0);if(D<c||D>o){R&&R(r),r=(r+1)%o;continue}let x=D-c,G=U+c,P=new Uint8Array(x);for(let p=0;p<x;p++)P[p]=e[G+p];N(P,M,D),r=(r+D)%o,C++}return{newTail:r,messagesRead:C}}var T="sab",S=null,l=null,E=null,d=null,H=null,n=null,_={},A=null,u=!1,I=new TextDecoder("utf-8"),w=(...e)=>{},Y=(e,t,s)=>{S=e,l=t,n=s,E=new Int32Array(S),d=new DataView(S),H=new Uint8Array(S),_={DEBUG_HEAD:(l+n.CONTROL_START+16)/4,DEBUG_TAIL:(l+n.CONTROL_START+20)/4};let o=l+n.METRICS_START;A=new Uint32Array(S,o,n.METRICS_SIZE/4)},F=()=>{let e=Atomics.load(E,_.DEBUG_HEAD),t=Atomics.load(E,_.DEBUG_TAIL);if(e===t)return null;let s=[],{newTail:o,messagesRead:a}=m({uint8View:H,dataView:d,bufferStart:l+n.DEBUG_BUFFER_START,bufferSize:n.DEBUG_BUFFER_SIZE,head:e,tail:t,messageMagic:n.MESSAGE_MAGIC,paddingMagic:n.PADDING_MAGIC,headerSize:n.MESSAGE_HEADER_SIZE,maxMessages:1e3,onMessage:(i,f,g)=>{let c=I.decode(i);c.endsWith(`
|
|
2
|
+
`)&&(c=c.slice(0,-1)),s.push({text:c,timestamp:performance.now(),sequence:f}),A&&(Atomics.add(A,29,1),Atomics.add(A,30,i.length))},onCorruption:i=>{console.error("[DebugWorker] Corrupted message at position",i)}});return a>0&&Atomics.store(E,_.DEBUG_TAIL,o),s.length>0?s:null},k=()=>{for(;u;)try{let e=Atomics.load(E,_.DEBUG_HEAD),t=Atomics.load(E,_.DEBUG_TAIL);if(e===t){let o=Atomics.wait(E,_.DEBUG_HEAD,e,100);if(!(o==="ok"||o==="not-equal")){if(o==="timed-out")continue}}let s=F();s&&s.length>0&&self.postMessage({type:"debug",messages:s})}catch(e){console.error("[DebugWorker] Error in wait loop:",e),self.postMessage({type:"error",error:e.message}),Atomics.wait(E,0,E[0],10)}},h=()=>{if(!S){console.error("[DebugWorker] Cannot start - not initialized");return}if(u){console.warn("[DebugWorker] Already running");return}u=!0,k()},W=()=>{u=!1},K=()=>{S&&(Atomics.store(E,_.DEBUG_HEAD,0),Atomics.store(E,_.DEBUG_TAIL,0))},V=e=>{let t=[];for(let s of e)try{let o=new Uint8Array(s.bytes),a=I.decode(o);a.endsWith(`
|
|
3
|
+
`)&&(a=a.slice(0,-1)),t.push({text:a,timestamp:performance.now(),sequence:s.sequence})}catch(o){console.error("[DebugWorker] Failed to decode message:",o)}t.length>0&&self.postMessage({type:"debug",messages:t})};self.addEventListener("message",e=>{let{data:t}=e;try{switch(t.type){case"init":T=t.mode||"sab",T==="sab"&&Y(t.sharedBuffer,t.ringBufferBase,t.bufferConstants),self.postMessage({type:"initialized"});break;case"start":T==="sab"&&h();break;case"stop":W();break;case"clear":T==="sab"&&K();break;case"debugRaw":t.messages&&V(t.messages);break;default:console.warn("[DebugWorker] Unknown message type:",t.type)}}catch(s){console.error("[DebugWorker] Error:",s),self.postMessage({type:"error",error:s.message})}});w("[DebugWorker] Script loaded");})();
|
package/workers/osc_in_worker.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function
|
|
1
|
+
(()=>{function B({uint8View:e,dataView:t,bufferStart:E,bufferSize:o,head:f,tail:i,messageMagic:_,paddingMagic:P,headerSize:c,maxMessages:T=1/0,onMessage:M,onCorruption:C}){let s=i,O=0;for(;s!==f&&O<T;){if(o-s<c){s=0;continue}let D=E+s,x=t.getUint32(D,!0);if(x===P){s=0;continue}if(x!==_){C&&C(s),s=(s+1)%o;continue}let U=t.getUint32(D+4,!0),d=t.getUint32(D+8,!0);if(U<c||U>o){C&&C(s),s=(s+1)%o;continue}let u=U-c,F=D+c,g=new Uint8Array(u);for(let p=0;p<u;p++)g[p]=e[F+p];M(g,d,U),s=(s+U)%o,O++}return{newTail:s,messagesRead:O}}var R=null,l=null,S=null,H=null,L=null,r=null,a={},n=null,A=!1,w=(...e)=>{},I=-1,k=(e,t,E)=>{R=e,l=t,r=E,S=new Int32Array(R),H=new DataView(R),L=new Uint8Array(R),a={OUT_HEAD:(l+r.CONTROL_START+8)/4,OUT_TAIL:(l+r.CONTROL_START+12)/4};let o=l+r.METRICS_START;n=new Uint32Array(R,o,r.METRICS_SIZE/4)},W=()=>{let e=Atomics.load(S,a.OUT_HEAD),t=Atomics.load(S,a.OUT_TAIL);if(e===t)return[];let E=[],{newTail:o,messagesRead:f}=B({uint8View:L,dataView:H,bufferStart:l+r.OUT_BUFFER_START,bufferSize:r.OUT_BUFFER_SIZE,head:e,tail:t,messageMagic:r.MESSAGE_MAGIC,paddingMagic:r.PADDING_MAGIC,headerSize:r.MESSAGE_HEADER_SIZE,maxMessages:100,onMessage:(i,_,P)=>{if(I>=0){let c=I+1&4294967295;if(_!==c){let T=_-c+4294967296&4294967295;T<1e3&&(console.warn("[OSCInWorker] Detected",T,"dropped messages (expected seq",c,"got",_,")"),n&&Atomics.add(n,27,T))}}I=_,E.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 f>0&&Atomics.store(S,a.OUT_TAIL,o),E},b=()=>{for(;A;)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 E=W();E.length>0&&self.postMessage({type:"messages",messages:E})}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(A){console.warn("[OSCInWorker] Already running");return}A=!0,b()},K=()=>{A=!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":K();break;default:console.warn("[OSCInWorker] Unknown message type:",t.type)}}catch(E){console.error("[OSCInWorker] Error:",E),self.postMessage({type:"error",error:E.message})}});w("[OSCInWorker] Script loaded");})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function
|
|
1
|
+
(()=>{function k(e,t,r){return(r-1-e+t)%r}function v({uint8View:e,dataView:t,bufferStart:r,bufferSize:s,head:o,payload:c,sequence:u,messageMagic:g,headerSize:E}){let M=c.length,P=E+M+3&-4,p=s-o;if(P>p){let f=new Uint8Array(E),U=new DataView(f.buffer);U.setUint32(0,g,!0),U.setUint32(4,P,!0),U.setUint32(8,u,!0),U.setUint32(12,0,!0);let h=r+o,H=r;if(p>=E){e.set(f,h);let A=p-E;A>0&&e.set(c.subarray(0,A),h+E),e.set(c.subarray(A),H)}else{e.set(f.subarray(0,p),h),e.set(f.subarray(p),H);let A=E-p;e.set(c,H+A)}}else{let f=r+o;t.setUint32(f,g,!0),t.setUint32(f+4,P,!0),t.setUint32(f+8,u,!0),t.setUint32(f+12,0,!0),e.set(c,f+E)}return(o+P)%s}function fe(e,t,r=0){for(let s=0;s<=r;s++)if(Atomics.compareExchange(e,t,0,1)===0)return!0;return!1}function Re(e,t){Atomics.store(e,t,0)}function Z({atomicView:e,dataView:t,uint8View:r,bufferConstants:s,ringBufferBase:o,controlIndices:c,oscMessage:u,maxSpins:g=0}){let E=u.length,M=s.MESSAGE_HEADER_SIZE+E;if(M>s.IN_BUFFER_SIZE-s.MESSAGE_HEADER_SIZE||!fe(e,c.IN_WRITE_LOCK,g))return!1;try{let N=Atomics.load(e,c.IN_HEAD),P=Atomics.load(e,c.IN_TAIL),p=M+3&-4;if(k(N,P,s.IN_BUFFER_SIZE)<p)return!1;let U=Atomics.add(e,c.IN_SEQUENCE,1),h=v({uint8View:r,dataView:t,bufferStart:o+s.IN_BUFFER_START,bufferSize:s.IN_BUFFER_SIZE,head:N,payload:u,sequence:U,messageMagic:s.MESSAGE_MAGIC,headerSize:s.MESSAGE_HEADER_SIZE});return Atomics.load(e,c.IN_HEAD),Atomics.store(e,c.IN_HEAD,h),!0}finally{Re(e,c.IN_WRITE_LOCK)}}var R="sab",B=null,F=1024,Ue=65536,$=3600,te=4294967295,T=null,d=null,S=null,w=null,se=null,re=null,ne={},l=null,I=null,z=null,b=50,D=(e,t)=>{l&&(R==="sab"?Atomics.store(l,e,t):l[e]=t)},oe=e=>l?R==="sab"?Atomics.load(l,e):l[e]:0,_=(e,t)=>{l&&(R==="sab"?Atomics.add(l,e,t):l[e]+=t)},ce=(e,t)=>{l&&(R==="sab"?Atomics.store(l,e,t):l[e]=t)},De=e=>l?R==="sab"?Atomics.load(l,e):l[e]:0,he=()=>{if(R!=="postMessage"||z!==null)return;let e=()=>{I&&l&&self.postMessage({type:"preschedulerMetrics",metrics:new Uint32Array(I.slice(0))}),z=setTimeout(e,b)};e(),a("[PreScheduler] Started metrics sending (every "+b+"ms)")};var n=[],Ee=null,Ae=0,V=!1,i=[],X=5,C=65536,Ce=2208988800,le=25,me=.2,a=(...e)=>{},ie=()=>(performance.timeOrigin+performance.now())/1e3+Ce,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},Ie=()=>{if(!T||!S){console.error("[PreScheduler] Cannot init - missing buffer or constants");return}w=new Int32Array(T),se=new DataView(T),re=new Uint8Array(T),ne={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(T,e,S.METRICS_SIZE/4),a("[PreScheduler] SharedArrayBuffer initialized with direct ring buffer writing and metrics")},O=()=>{if(!l)return;D(9,n.length);let e=n.length,t=oe(10);e>t&&D(10,e)},m=(e,t,r=null)=>{if(R==="postMessage")return B?(B.postMessage({type:"osc",oscData:e}),_(12,1),!0):(console.error("[PreScheduler] No worklet port available"),!1);if(!T||!w)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):Z({atomicView:w,dataView:se,uint8View:re,bufferConstants:S,ringBufferBase:d,controlIndices:ne,oscMessage:e,maxSpins:10})?(_(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>=C){console.error("[PreScheduler] Backpressure: dropping retry ("+r+" pending)"),_(17,1);return}i.push({oscData:e,retryCount:0,context:t||"unknown",queuedAt:performance.now()}),D(18,i.length);let s=oe(19);i.length>s&&D(19,i.length),a("[PreScheduler] Queued message for retry:",t,"queue size:",i.length)},Le=()=>{if(i.length===0)return;let e=0;for(;e<i.length;){let t=i[e];if(m(t.oscData,!0))i.splice(e,1),_(16,1),_(20,1),D(18,i.length),a("[PreScheduler] Retry succeeded for:",t.context,"after",t.retryCount+1,"attempts");else if(t.retryCount++,_(20,1),t.retryCount>=X){let s=`Ring buffer full - dropped message after ${X} retries (${t.context})`;console.error("[PreScheduler]",s),i.splice(e,1),_(17,1),D(18,i.length),self.postMessage({type:"error",error:s})}else e++}},J=(e,t,r)=>{let s=n.length+i.length;if(s>=C){let E=`Prescheduler queue full (${s} >= ${C} 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 a("[PreScheduler] Non-bundle message, dispatching immediately"),m(e,!1)||L(e,"immediate message"),!0;let c=ie(),u=o-c;if(e.length>F){let E=`Bundle too large for scheduler (${e.length} > ${F} bytes)`;return console.warn("[PreScheduler]",E),self.postMessage({type:"error",error:E,code:"BUNDLE_TOO_LARGE"}),!1}if(u>$){let E=`Bundle scheduled too far in future (${u.toFixed(0)}s > ${$}s max)`;return console.warn("[PreScheduler]",E),self.postMessage({type:"error",error:E,code:"BUNDLE_TOO_FAR_FUTURE"}),!1}let g={ntpTime:o,seq:Ae++,sessionId:t||0,runTag:r||"",oscData:e};return Oe(g),_(11,1),O(),a("[PreScheduler] Scheduled bundle:","NTP="+o.toFixed(3),"current="+c.toFixed(3),"wait="+(u*1e3).toFixed(1)+"ms","pending="+n.length),!0},Oe=e=>{n.push(e),xe(n.length-1)},Ne=()=>n.length>0?n[0]:null,He=()=>{if(n.length===0)return null;let e=n[0],t=n.pop();return n.length>0&&(n[0]=t,Se(0)),e},xe=e=>{for(;e>0;){let t=Math.floor((e-1)/2);if(G(n[e],n[t])>=0)break;ae(e,t),e=t}},Se=e=>{let t=n.length;for(;;){let r=2*e+1,s=2*e+2,o=e;if(r<t&&G(n[r],n[o])<0&&(o=r),s<t&&G(n[s],n[o])<0&&(o=s),o===e)break;ae(e,o),e=o}},G=(e,t)=>e.ntpTime===t.ntpTime?e.seq-t.seq:e.ntpTime-t.ntpTime,ae=(e,t)=>{let r=n[e];n[e]=n[t],n[t]=r},ye=()=>{if(Ee!==null){console.warn("[PreScheduler] Polling already started");return}a("[PreScheduler] Starting periodic polling (every "+le+"ms)"),ue()};var ue=()=>{V=!0,Le();let e=ie(),t=e+me,r=0;for(;n.length>0;){let s=Ne();if(s.ntpTime<=t){He(),O();let o=s.ntpTime-e;if(_(21,1),o<0)_(15,1);else{let u=Math.round(o*1e3),g=De(14);(g===te||u<g)&&ce(14,u)}a("[PreScheduler] Dispatching bundle:","NTP="+s.ntpTime.toFixed(3),"current="+e.toFixed(3),"early="+(o*1e3).toFixed(1)+"ms","remaining="+n.length),m(s.oscData,!1)||L(s.oscData,"scheduled bundle NTP="+s.ntpTime.toFixed(3)),r++}else break}(r>0||n.length>0||i.length>0)&&a("[PreScheduler] Dispatch cycle complete:","dispatched="+r,"pending="+n.length,"retrying="+i.length),V=!1,Ee=setTimeout(ue,le)},Y=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,Be(),_(13,s),O(),a("[PreScheduler] Cancelled "+s+" events, "+n.length+" remaining"))},Be=()=>{for(let e=Math.floor(n.length/2)-1;e>=0;e--)Se(e)},Fe=(e,t)=>{Y(r=>r.sessionId===e&&r.runTag===t)},we=e=>{Y(t=>t.sessionId===e)},be=e=>{Y(t=>t.runTag===e)},Ge=()=>{if(n.length===0)return;let e=n.length;_(13,e),n=[],O(),a("[PreScheduler] Cancelled all "+e+" events")},Ye=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>Ue||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},ve=e=>{if(Ye(e)){let t=ke(e);for(let r=0;r<t.length;r++)m(t[r],!1)||L(t[r],"immediate bundle message "+r)}else m(e,!1)||L(e,"immediate message")};self.addEventListener("message",e=>{let{data:t}=e;try{switch(t.type){case"init":if(R=t.mode||"sab",t.maxPendingMessages&&(C=t.maxPendingMessages),t.snapshotIntervalMs&&(b=t.snapshotIntervalMs),R==="sab")T=t.sharedBuffer,d=t.ringBufferBase,S=t.bufferConstants,Ie(),S&&S.scheduler_slot_size&&(F=S.scheduler_slot_size);else{B=t.workletPort;let s=128;I=new ArrayBuffer(s),l=new Uint32Array(I),he()}ce(14,te),ye(),a("[OSCPreSchedulerWorker] Initialized with NTP-based scheduling, mode="+R+", capacity="+C),self.postMessage({type:"initialized"});break;case"addOscSource":let r=e.ports[0];r&&(r.onmessage=s=>{s.data.type==="osc"&&s.data.oscData&&J(s.data.oscData,0,"")},a("[OSCPreSchedulerWorker] Added external OSC source"));break;case"send":J(t.oscData,t.sessionId||0,t.runTag||"");break;case"sendImmediate":ve(t.oscData);break;case"cancelSessionTag":t.runTag!==void 0&&t.runTag!==null&&t.runTag!==""&&Fe(t.sessionId||0,t.runTag);break;case"cancelSession":we(t.sessionId||0);break;case"cancelTag":t.runTag!==void 0&&t.runTag!==null&&t.runTag!==""&&be(t.runTag);break;case"cancelAll":Ge();break;default:console.warn("[OSCPreSchedulerWorker] Unknown message type:",t.type)}}catch(r){console.error("[OSCPreSchedulerWorker] Error:",r),self.postMessage({type:"error",error:r.message})}});a("[OSCPreSchedulerWorker] Script loaded");})();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(()=>{function C(m,e,t){return(t-1-m+e)%t}function
|
|
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}=w({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}=w({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,maxMessages:10,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);})();
|
|
1
|
+
(()=>{function C(m,e,t){return(t-1-m+e)%t}function O({uint8View:m,dataView:e,bufferStart:t,bufferSize:s,head:i,payload:a,sequence:o,messageMagic:f,headerSize:r}){let _=a.length,h=r+_+3&-4,n=s-i;if(h>n){let c=new Uint8Array(r),u=new DataView(c.buffer);u.setUint32(0,f,!0),u.setUint32(4,h,!0),u.setUint32(8,o,!0),u.setUint32(12,0,!0);let l=t+i,T=t;if(n>=r){m.set(c,l);let S=n-r;S>0&&m.set(a.subarray(0,S),l+r),m.set(a.subarray(S),T)}else{m.set(c.subarray(0,n),l),m.set(c.subarray(n),T);let S=r-n;m.set(a,T+S)}}else{let c=t+i;e.setUint32(c,f,!0),e.setUint32(c+4,h,!0),e.setUint32(c+8,o,!0),e.setUint32(c+12,0,!0),m.set(a,c+r)}return(i+h)%s}function R({uint8View:m,dataView:e,bufferStart:t,bufferSize:s,head:i,tail:a,messageMagic:o,paddingMagic:f,headerSize:r,maxMessages:_=1/0,onMessage:E,onCorruption:h}){let n=a,c=0;for(;n!==i&&c<_;){if(s-n<r){n=0;continue}let l=t+n,T=e.getUint32(l,!0);if(T===f){n=0;continue}if(T!==o){h&&h(n),n=(n+1)%s;continue}let S=e.getUint32(l+4,!0),d=e.getUint32(l+8,!0);if(S<r||S>s){h&&h(n),n=(n+1)%s;continue}let p=S-r,g=l+r,I=new Uint8Array(p);for(let A=0;A<p;A++)I[A]=m[g+A];E(I,d,S),n=(n+S)%s,c++}return{newTail:n,messagesRead:c}}var w=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.oscPorts=[],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,t[16]=this.mode==="postMessage"?1: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
|
+
`,f=new TextEncoder().encode(a);if(f.length>s)return;let r=this.CONTROL_INDICES.DEBUG_HEAD,_=this.atomicLoad(r),E=s-_,h=_;f.length>E&&(this.uint8View[this.ringBufferBase+t+_]=i,h=0);let n=this.ringBufferBase+t;for(let u=0;u<f.length;u++)this.uint8View[n+h+u]=f[u];let c=h+f.length;this.atomicStore(r,c)}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,f=t+a+3&-4,r=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD),_=this.atomicLoad(this.CONTROL_INDICES.IN_TAIL),E=C(r,_,e);if(f>E)break;this.oscQueue.shift();let h=this.atomicLoad(this.CONTROL_INDICES.IN_SEQUENCE);this.atomicStore(this.CONTROL_INDICES.IN_SEQUENCE,h+1);let n=new Uint8Array(i),c=O({uint8View:this.uint8View,dataView:this.dataView,bufferStart:s,bufferSize:e,head:r,payload:n,sequence:h,messageMagic:this.bufferConstants.MESSAGE_MAGIC,headerSize:t});this.atomicStore(this.CONTROL_INDICES.IN_HEAD,c)}}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:(o,f)=>{s.push({oscData:o.buffer,sequence:f})}});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],o=t+e.NODE_TREE_HEADER_SIZE,f=e.NODE_TREE_MIRROR_MAX_NODES,r=e.NODE_TREE_ENTRY_SIZE,_=e.NODE_TREE_DEF_NAME_SIZE,E=new DataView(this.wasmMemory.buffer,o,f*r),h=[],n=0;for(let c=0;c<f&&n<i;c++){let u=c*r,l=E.getInt32(u,!0);if(l===-1)continue;n++;let T=o+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}recordOscReceived(e){this.metricsView&&(this.mode==="sab"?(Atomics.add(this.metricsView,23,1),Atomics.add(this.metricsView,24,e)):(this.metricsView[23]++,this.metricsView[24]+=e))}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 f=this.readMetricsAndTreeBuffer();f&&(this.treeSnapshotsSent++,this.port.postMessage({type:"snapshot",buffer:f,snapshotsSent:this.treeSnapshotsSent},[f]))}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,maxMessages:10,onMessage:(o,f)=>{s.push({bytes:o.buffer,sequence:f})}});a>0&&this.atomicStore(this.CONTROL_INDICES.DEBUG_TAIL,i),s.length>0&&this.port.postMessage({type:"debugRawBatch",messages:s},s.map(o=>o.bytes))}async handleMessage(e){let{data:t}=e;try{if(t.type==="osc"){this.mode==="postMessage"&&t.oscData&&(this.oscQueue.push(t.oscData),this.recordOscReceived(t.oscData.byteLength));return}if(t.type==="addOscPort"){let s=e.ports[0];s&&(s.onmessage=i=>{i.data.type==="osc"&&i.data.oscData&&(this.oscQueue.push(i.data.oscData),this.recordOscReceived(i.data.oscData.byteLength))},this.oscPorts.push(s));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 o=t.memoryPages||1280;s=new WebAssembly.Memory({initial:o,maximum:o,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:(o,f,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:o=>{console.error("[AudioWorklet] WASM tried to exit with code:",o)}}},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 o=this.mode==="postMessage"?this.readMetricsAndTreeBuffer():void 0,f={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:o};this.port.postMessage(f,o?[o]:[])}}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 o=s;i[o]!==0;o++)a+=String.fromCharCode(i[o]);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 o=new Float32Array(a);new Float32Array(this.wasmMemory.buffer,i,o.length).set(o),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,o=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,n=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 c=0;c<n;c++)e[0]?.[c]&&this.inputView.set(e[0][c],c*_)}}}catch{}let f=this.wasmInstance.exports.process_audio(i,o,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,n=h.byteLength,c=r+_*2*4;if(r<0||r>n||c>n)return!0;(!this.audioView||this.lastAudioBufferPtr!==r||this.lastWasmBufferSize!==n||h!==this.audioView.buffer)&&(this.audioView=new Float32Array(h,r,_*2),this.lastAudioBufferPtr=r,this.lastWasmBufferSize=n),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(),f!==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",w);})();
|