supersonic-scsynth-core 0.53.0 → 0.56.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.53.0",
3
+ "version": "0.56.0",
4
4
  "description": "SuperCollider scsynth WebAssembly engine and AudioWorklet for SuperSonic",
5
5
  "type": "module",
6
6
  "main": "index.js",
Binary file
@@ -1,2 +1,2 @@
1
- (()=>{function O(T,e,t){return(t-1-T+e)%t}function w({uint8View:T,dataView:e,bufferStart:t,bufferSize:s,head:i,payload:r,sequence:n,messageMagic:E,headerSize:a,sourceId:c=0,headerScratch:f=null,headerScratchView:u=null}){let _=r.length,o=a+_+3&-4,l=s-i;if(o>l){let S=f||new Uint8Array(a),m=u||new DataView(S.buffer);m.setUint32(0,E,!0),m.setUint32(4,o,!0),m.setUint32(8,n,!0),m.setUint32(12,c,!0);let I=t+i,A=t;if(l>=a){T.set(S,I);let p=l-a;p>0&&T.set(r.subarray(0,p),I+a),T.set(r.subarray(p),A)}else{T.set(S.subarray(0,l),I),T.set(S.subarray(l),A);let p=a-l;T.set(r,A+p)}}else{let S=t+i;e.setUint32(S,E,!0),e.setUint32(S+4,o,!0),e.setUint32(S+8,n,!0),e.setUint32(S+12,c,!0),T.set(r,S+a)}return(i+o)%s}function C({uint8View:T,dataView:e,bufferStart:t,bufferSize:s,head:i,tail:r,messageMagic:n,paddingMagic:E,headerSize:a,maxMessages:c=1/0,onMessage:f,onCorruption:u}){let _=r,h=0,o=l=>{let S=l;if(S+4<=s)return e.getUint32(t+S,!0);let m=0;for(let I=0;I<4;I++)m|=T[t+(S+I)%s]<<I*8;return m};for(;_!==i&&h<c;){let l=s-_,S;if(l>=4?S=e.getUint32(t+_,!0):S=o(_),S===E){_=0;continue}if(S!==n){u&&u(_),_=(_+1)%s;continue}let m=o((_+4)%s),I=o((_+8)%s),A=o((_+12)%s);if(m<a||m>s){u&&u(_),_=(_+1)%s;continue}let p=m-a,N=t+(_+a)%s;f(N,p,I,A),_=(_+m)%s,h++}return{newTail:_,messagesRead:h}}function D(T,e){let t=T+e;return{IN_HEAD:(t+0)/4,IN_TAIL:(t+4)/4,OUT_HEAD:(t+8)/4,OUT_TAIL:(t+12)/4,DEBUG_HEAD:(t+16)/4,DEBUG_TAIL:(t+20)/4,IN_SEQUENCE:(t+24)/4,OUT_SEQUENCE:(t+28)/4,DEBUG_SEQUENCE:(t+32)/4,STATUS_FLAGS:(t+36)/4,IN_WRITE_LOCK:(t+40)/4,IN_LOG_TAIL:(t+44)/4}}var d={MAX_REPLY_MESSAGES:64,MAX_DEBUG_MESSAGES:32,MAX_LOG_ENTRIES:100,REPLY_BUFFER_SIZE:128*1024,DEBUG_BUFFER_SIZE:64*1024,LOG_BUFFER_SIZE:256*1024,LOG_MAX_MESSAGE_SIZE:16*1024,MAX_OSC_MESSAGE_SIZE:8192},R=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.pendingClearSched=!1,this.audioView=null,this.lastAudioBufferPtr=0,this.lastWasmBufferSize=0,this.lastTreeVersion=-1,this.treeSnapshotsSent=0,this.lastTreeSendTime=-1,this.treeSnapshotMinInterval=.15,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.oscPorts=[],this.portSourceIds=new Map,this.channelViews=null,this.lastNumSamples=0,this.lastNumChannels=0,this.pmPools=null,this._statusObj={bufferFull:!1,overrun:!1,wasmError:!1,fragmented:!1},this._metricsObj={processCount:0,messagesProcessed:0,messagesDropped:0,schedulerQueueDepth:0,schedulerQueueMax:0,schedulerQueueDropped:0},this._statusMessage={type:"status",flags:0,status:this._statusObj,metrics:this._metricsObj},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=D(e,t),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);let r=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD);this.atomicStore(this.CONTROL_INDICES.IN_LOG_TAIL,r)}}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,r="[JS] "+e+`
2
- `,E=new TextEncoder().encode(r);if(E.length>s)return;let a=this.CONTROL_INDICES.DEBUG_HEAD,c=this.atomicLoad(a),f=s-c,u=c;E.length>f&&(this.uint8View[this.ringBufferBase+t+c]=i,u=0);let _=this.ringBufferBase+t;for(let o=0;o<E.length;o++)this.uint8View[_+u+o]=E[o];let h=u+E.length;this.atomicStore(a,h),this.mode==="sab"&&Atomics.notify(this.atomicView,a,1)}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}initPMPools(){if(this.mode!=="postMessage")return;let e=d;this.pmPools={replies:{message:{type:"oscReplies",messages:null,count:0},buffer:new ArrayBuffer(e.REPLY_BUFFER_SIZE),bufferView:null,entries:new Array(e.MAX_REPLY_MESSAGES).fill(null).map(()=>({offset:0,length:0,sequence:0}))},debug:{message:{type:"debugRawBatch",messages:null,count:0},buffer:new ArrayBuffer(e.DEBUG_BUFFER_SIZE),bufferView:null,entries:new Array(e.MAX_DEBUG_MESSAGES).fill(null).map(()=>({offset:0,length:0,sequence:0}))},snapshot:{message:{type:"snapshot",buffer:null,snapshotsSent:0},buffer:null,bufferView:null,size:0},log:{message:{type:"oscLog",entries:null,count:0,buffer:null},buffer:new ArrayBuffer(e.LOG_BUFFER_SIZE),bufferView:null,entries:new Array(e.MAX_LOG_ENTRIES).fill(null).map(()=>({offset:0,length:0,originalLength:0,sourceId:0,sequence:0}))},incoming:{headerBytes:new Uint8Array(16),headerView:null}};let t=this.pmPools;if(t.replies.bufferView=new Uint8Array(t.replies.buffer),t.debug.bufferView=new Uint8Array(t.debug.buffer),t.log.bufferView=new Uint8Array(t.log.buffer),t.replies.message.messages=t.replies.entries,t.debug.message.messages=t.debug.entries,t.log.message.entries=t.log.entries,t.incoming.headerView=new DataView(t.incoming.headerBytes.buffer),this.bufferConstants&&this.wasmMemory){let s=this.bufferConstants,i=s.METRICS_SIZE+s.NODE_TREE_SIZE;t.snapshot.buffer=new ArrayBuffer(i),t.snapshot.bufferView=new Uint8Array(t.snapshot.buffer),t.snapshot.size=i,t.snapshot.message.buffer=t.snapshot.buffer;let r=this.ringBufferBase+s.METRICS_START;t.snapshot.sourceView=new Uint8Array(this.wasmMemory.buffer,r,i)}}writeOscToRingBuffer(e,t=0){if(!this.bufferConstants||!this.uint8View||!this.pmPools)return!1;let s=this.bufferConstants.IN_BUFFER_SIZE,i=this.bufferConstants.MESSAGE_HEADER_SIZE,r=this.ringBufferBase+this.bufferConstants.IN_BUFFER_START,n=e.byteLength,a=i+n+3&-4,c=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD),f=this.atomicLoad(this.CONTROL_INDICES.IN_TAIL),u=O(c,f,s);if(a>u)return console.error("[AudioWorklet] Ring buffer full, dropping OSC message"),!1;let _=this.atomicLoad(this.CONTROL_INDICES.IN_SEQUENCE);this.atomicStore(this.CONTROL_INDICES.IN_SEQUENCE,_+1);let h=new Uint8Array(e),o=w({uint8View:this.uint8View,dataView:this.dataView,bufferStart:r,bufferSize:s,head:c,payload:h,sequence:_,messageMagic:this.bufferConstants.MESSAGE_MAGIC,headerSize:i,sourceId:t,headerScratch:this.pmPools.incoming.headerBytes,headerScratchView:this.pmPools.incoming.headerView});return this.atomicStore(this.CONTROL_INDICES.IN_HEAD,o),!0}readOscReplies(){if(!this.pmPools)return;let e=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);if(e===t)return;let s=this.pmPools.replies,i=d,r=0,n=0,{newTail:E,messagesRead:a}=C({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,maxMessages:i.MAX_REPLY_MESSAGES,onMessage:(c,f,u,_)=>{if(r>=i.MAX_REPLY_MESSAGES||n+f>i.REPLY_BUFFER_SIZE)return;for(let o=0;o<f;o++)s.bufferView[n+o]=this.uint8View[c+o];let h=s.entries[r];h.offset=n,h.length=f,h.sequence=u,n+=f,r++}});a>0&&this.atomicStore(this.CONTROL_INDICES.OUT_TAIL,E),r>0&&(s.message.count=r,s.message.buffer=s.buffer,this.port.postMessage(s.message))}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],r=s[1],n=t+e.NODE_TREE_HEADER_SIZE,E=e.NODE_TREE_MIRROR_MAX_NODES,a=e.NODE_TREE_ENTRY_SIZE,c=e.NODE_TREE_DEF_NAME_SIZE,f=new DataView(this.wasmMemory.buffer,n,E*a),u=[],_=0;for(let h=0;h<E&&_<i;h++){let o=h*a,l=f.getInt32(o,!0);if(l===-1)continue;_++;let S=n+o+24,m=new Uint8Array(this.wasmMemory.buffer,S,c),I="";for(let A=0;A<c&&m[A]!==0;A++)I+=String.fromCharCode(m[A]);u.push({id:l,parentId:f.getInt32(o+4,!0),isGroup:f.getInt32(o+8,!0)===1,prevId:f.getInt32(o+12,!0),nextId:f.getInt32(o+16,!0),headId:f.getInt32(o+20,!0),defName:I})}return{nodeCount:i,version:r,nodes:u}}readMetrics(){return this.metricsView?new Uint32Array(this.metricsView):null}recordOscReceived(e,t=null){if(this.metricsView){if(this.mode==="sab")Atomics.add(this.metricsView,24,1),Atomics.add(this.metricsView,25,e);else if(this.metricsView[24]++,this.metricsView[25]+=e,t){this.metricsView[22]++;let i={nonBundle:38,immediate:39,nearFuture:40,late:41}[t];i!==void 0&&this.metricsView[i]++}}}checkAndSendSnapshot(e){let t=this.bufferConstants;if(!t||!this.wasmMemory||this.ringBufferBase===null||!this.pmPools)return!1;let i=(this.ringBufferBase+t.NODE_TREE_START+4)/4,r=this.atomicView[i];if(r!==this.lastTreeVersion)this.lastTreeVersion=r,this.lastTreeSendTime=e;else{if(this.lastTreeSendTime>=0&&e-this.lastTreeSendTime<this.treeSnapshotMinInterval)return!1;this.lastTreeSendTime=e}let E=this.pmPools.snapshot;return!E.buffer||!E.sourceView?!1:(E.bufferView.set(E.sourceView),this.treeSnapshotsSent++,E.message.snapshotsSent=this.treeSnapshotsSent,this.port.postMessage(E.message),!0)}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),r=new ArrayBuffer(s);return new Uint8Array(r).set(i),r}sendLogEntries(){if(!this.CONTROL_INDICES||!this.bufferConstants||!this.pmPools)return;let e=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.IN_LOG_TAIL);if(e===t)return;let s=this.pmPools.log,i=d,r=0,n=0,{newTail:E,messagesRead:a}=C({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.IN_BUFFER_START,bufferSize:this.bufferConstants.IN_BUFFER_SIZE,head:e,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,maxMessages:i.MAX_LOG_ENTRIES,onMessage:(c,f,u,_)=>{if(r>=i.MAX_LOG_ENTRIES)return;let h=Math.min(f,i.LOG_MAX_MESSAGE_SIZE);if(n+h>i.LOG_BUFFER_SIZE)return;for(let l=0;l<h;l++)s.bufferView[n+l]=this.uint8View[c+l];let o=s.entries[r];o.offset=n,o.length=h,o.originalLength=f,o.sourceId=_??0,o.sequence=u,n+=h,r++}});a>0&&this.atomicStore(this.CONTROL_INDICES.IN_LOG_TAIL,E),r>0&&(s.message.count=r,s.message.buffer=s.buffer,this.port.postMessage(s.message))}readDebugMessages(){if(!this.pmPools)return;let e=this.atomicLoad(this.CONTROL_INDICES.DEBUG_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.DEBUG_TAIL);if(e===t)return;let s=this.pmPools.debug,i=d,r=0,n=0,{newTail:E,messagesRead:a}=C({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:i.MAX_DEBUG_MESSAGES,onMessage:(c,f,u,_)=>{if(r>=i.MAX_DEBUG_MESSAGES||n+f>i.DEBUG_BUFFER_SIZE)return;for(let o=0;o<f;o++)s.bufferView[n+o]=this.uint8View[c+o];let h=s.entries[r];h.offset=n,h.length=f,h.sequence=u,n+=f,r++}});a>0&&this.atomicStore(this.CONTROL_INDICES.DEBUG_TAIL,E),r>0&&(s.message.count=r,s.message.buffer=s.buffer,this.port.postMessage(s.message))}async handleMessage(e){let{data:t}=e;try{if(t.type==="osc"){this.mode==="postMessage"&&t.oscData&&(this.writeOscToRingBuffer(t.oscData,t.sourceId??0),this.recordOscReceived(t.oscData.byteLength,t.bypassCategory));return}if(t.type==="addOscPort"){let s=e.ports[0];if(s){let i=t.sourceId??0;this.portSourceIds.set(s,i),s.onmessage=r=>{if(r.data.type==="osc"&&r.data.oscData){let n=r.data.sourceId??this.portSourceIds.get(s)??0;this.writeOscToRingBuffer(r.data.oscData,n),this.recordOscReceived(r.data.oscData.byteLength,r.data.bypassCategory)}},this.oscPorts.push(s)}return}if(t.type==="clearSched"){if(this.CONTROL_INDICES){let s=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD);this.atomicStore(this.CONTROL_INDICES.IN_TAIL,s)}this.pendingClearSched=!0,t.ack&&this.port.postMessage({type:"clearSchedAck"});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,E,a)=>{let c=new DataView(s.buffer),f=BigInt(Math.floor(Date.now()*1e6));return c.setBigUint64(a,f,!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)}}},r=await WebAssembly.compile(t.wasmBytes);if(this.wasmInstance=await WebAssembly.instantiate(r,i),this.wasmInstance.exports.get_ring_buffer_base&&(this.ringBufferBase=this.wasmInstance.exports.get_ring_buffer_base(),this.loadBufferConstants(),this.calculateBufferIndices(this.ringBufferBase),this.initPMPools(),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,E={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:n};this.port.postMessage(E,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.initPMPools(),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),r="";for(let n=s;i[n]!==0;n++)r+=String.fromCharCode(i[n]);this.port.postMessage({type:"version",version:r})}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==="setClockOffset"&&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.clockOffsetMs}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:r}=t;if(!this.wasmMemory||!this.wasmMemory.buffer)throw new Error("WASM memory not initialized");let n=new Float32Array(r);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.pendingClearSched&&(this.pendingClearSched=!1,this.wasmInstance.exports.clear_scheduler&&this.wasmInstance.exports.clear_scheduler());let i=currentTime,r=e[0]?.length||0,n=t[0]?.length||0;if(r>0&&this.wasmInstance?.exports?.get_audio_input_bus)try{let a=this.wasmInstance.exports.get_audio_input_bus(),c=this.wasmInstance.exports.get_audio_buffer_samples();if(a&&a>0){let f=this.sharedBuffer||this.wasmMemory?.buffer;if(f){let u=this.worldOptions?.numInputBusChannels||2,_=Math.min(r,u);(!this.inputView||this.lastInputBusPtr!==a||this.lastInputChannels!==u)&&(this.inputView=new Float32Array(f,a,c*u),this.lastInputBusPtr=a,this.lastInputChannels=u);for(let h=0;h<_;h++)e[0]?.[h]&&this.inputView.set(e[0][h],h*c)}}}catch{}let E=this.wasmInstance.exports.process_audio(i,n,r);if(this.wasmInstance.exports.get_audio_output_bus&&t[0]&&t[0].length>=1)try{let a=this.wasmInstance.exports.get_audio_output_bus(),c=this.wasmInstance.exports.get_audio_buffer_samples();if(a&&a>0){let f=this.wasmInstance.exports.memory||this.wasmMemory;if(!f||!f.buffer)return!0;let u=f.buffer,_=u.byteLength,h=this.worldOptions?.numOutputBusChannels||2,o=Math.min(t[0].length,h),l=a+c*o*4;if(a<0||a>_||l>_)return!0;if((!this.audioView||this.lastAudioBufferPtr!==a||this.lastWasmBufferSize!==_||this.lastNumChannels!==o||u!==this.audioView.buffer)&&(this.audioView=new Float32Array(u,a,c*o),this.lastAudioBufferPtr=a,this.lastWasmBufferSize=_),!this.channelViews||this.lastNumSamples!==c||this.lastNumChannels!==o||this.channelViews[0].buffer!==this.audioView.buffer){this.channelViews=new Array(o);for(let S=0;S<o;S++)this.channelViews[S]=this.audioView.subarray(S*c,(S+1)*c);this.lastNumSamples=c,this.lastNumChannels=o}for(let S=0;S<o;S++)t[0][S].set(this.channelViews[S])}}catch{}if(this.mode==="postMessage")this.readOscReplies(),this.readDebugMessages(),this.checkAndSendSnapshot(i)&&this.sendLogEntries();else if(this.atomicView){let a=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),c=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);a!==c&&Atomics.notify(this.atomicView,this.CONTROL_INDICES.OUT_HEAD,1);let f=this.atomicLoad(this.CONTROL_INDICES.DEBUG_HEAD),u=this.atomicLoad(this.CONTROL_INDICES.DEBUG_TAIL);f!==u&&Atomics.notify(this.atomicView,this.CONTROL_INDICES.DEBUG_HEAD,1),Atomics.notify(this.atomicView,this.CONTROL_INDICES.IN_TAIL,1)}return this.processCallCount%3750===0&&this.checkStatus(),E!==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){this._statusObj.bufferFull=!!(e&this.STATUS_FLAGS.BUFFER_FULL),this._statusObj.overrun=!!(e&this.STATUS_FLAGS.OVERRUN),this._statusObj.wasmError=!!(e&this.STATUS_FLAGS.WASM_ERROR),this._statusObj.fragmented=!!(e&this.STATUS_FLAGS.FRAGMENTED_MSG),this._metricsObj.processCount=this.metricsView[0],this._metricsObj.messagesProcessed=this.metricsView[1],this._metricsObj.messagesDropped=this.metricsView[2],this._metricsObj.schedulerQueueDepth=this.metricsView[3],this._metricsObj.schedulerQueueMax=this.metricsView[4],this._metricsObj.schedulerQueueDropped=this.metricsView[5],this._statusMessage.flags=e,this.port.postMessage(this._statusMessage);let t=e&this.STATUS_FLAGS.BUFFER_FULL;this.atomicStore(this.CONTROL_INDICES.STATUS_FLAGS,t)}}};registerProcessor("scsynth-processor",R);})();
1
+ (()=>{function O(d,s,t){return(t-1-d+s)%t}function w({uint8View:d,dataView:s,bufferStart:t,bufferSize:e,head:i,payload:o,sequence:a,messageMagic:E,headerSize:n,sourceId:f=0,headerScratch:_=null,headerScratchView:u=null}){let c=o.length,r=n+c+3&-4,l=e-i;if(r>l){let S=_||new Uint8Array(n),m=u||new DataView(S.buffer);m.setUint32(0,E,!0),m.setUint32(4,r,!0),m.setUint32(8,a,!0),m.setUint32(12,f,!0);let I=t+i,T=t;if(l>=n){d.set(S,I);let p=l-n;p>0&&d.set(o.subarray(0,p),I+n),d.set(o.subarray(p),T)}else{d.set(S.subarray(0,l),I),d.set(S.subarray(l),T);let p=n-l;d.set(o,T+p)}}else{let S=t+i;s.setUint32(S,E,!0),s.setUint32(S+4,r,!0),s.setUint32(S+8,a,!0),s.setUint32(S+12,f,!0),d.set(o,S+n)}return(i+r)%e}function A({uint8View:d,dataView:s,bufferStart:t,bufferSize:e,head:i,tail:o,messageMagic:a,paddingMagic:E,headerSize:n,maxMessages:f=1/0,onMessage:_,onCorruption:u}){let c=o,h=0,r=l=>{let S=l;if(S+4<=e)return s.getUint32(t+S,!0);let m=0;for(let I=0;I<4;I++)m|=d[t+(S+I)%e]<<I*8;return m};for(;c!==i&&h<f;){let l=e-c,S;if(l>=4?S=s.getUint32(t+c,!0):S=r(c),S===E){c=0;continue}if(S!==a){u&&u(c),c=(c+1)%e;continue}let m=r((c+4)%e),I=r((c+8)%e),T=r((c+12)%e);if(m<n||m>e){u&&u(c),c=(c+1)%e;continue}let p=m-n,U=t+(c+n)%e;_(U,p,I,T),c=(c+m)%e,h++}return{newTail:c,messagesRead:h}}function g(d,s){let t=d+s;return{IN_HEAD:(t+0)/4,IN_TAIL:(t+4)/4,OUT_HEAD:(t+8)/4,OUT_TAIL:(t+12)/4,DEBUG_HEAD:(t+16)/4,DEBUG_TAIL:(t+20)/4,IN_SEQUENCE:(t+24)/4,OUT_SEQUENCE:(t+28)/4,DEBUG_SEQUENCE:(t+32)/4,STATUS_FLAGS:(t+36)/4,IN_WRITE_LOCK:(t+40)/4,IN_LOG_TAIL:(t+44)/4}}var C={MAX_REPLY_MESSAGES:64,MAX_DEBUG_MESSAGES:32,MAX_LOG_ENTRIES:100,REPLY_BUFFER_SIZE:128*1024,DEBUG_BUFFER_SIZE:64*1024,LOG_BUFFER_SIZE:256*1024,LOG_MAX_MESSAGE_SIZE:16*1024,MAX_OSC_MESSAGE_SIZE:8192},R=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.pendingClearSched=!1,this.audioView=null,this.lastAudioBufferPtr=0,this.lastWasmBufferSize=0,this.lastTreeVersion=-1,this.treeSnapshotsSent=0,this.lastTreeSendTime=-1,this.treeSnapshotMinInterval=.15,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.oscPorts=[],this.portSourceIds=new Map,this.channelViews=null,this.lastNumSamples=0,this.lastNumChannels=0,this.pmPools=null,this.nodeIdRanges=[{from:0,to:0},{from:0,to:0}],this.nodeIdRangeCount=0,this.nodeIdRefillRequested=!1,this.nodeIdPort=null,this.nodeIdCounterView=null,this._statusObj={bufferFull:!1,overrun:!1,wasmError:!1,fragmented:!1},this._metricsObj={processCount:0,messagesProcessed:0,messagesDropped:0,schedulerQueueDepth:0,schedulerQueueMax:0,schedulerQueueDropped:0},this._statusMessage={type:"status",flags:0,status:this._statusObj,metrics:this._metricsObj},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 s=this.wasmInstance.exports.get_buffer_layout(),t=this.wasmMemory;if(!t)throw new Error("WASM memory not available");let e=new Uint32Array(t.buffer,s,36),i=new Uint8Array(t.buffer,s,148);if(this.bufferConstants={IN_BUFFER_START:e[0],IN_BUFFER_SIZE:e[1],OUT_BUFFER_START:e[2],OUT_BUFFER_SIZE:e[3],DEBUG_BUFFER_START:e[4],DEBUG_BUFFER_SIZE:e[5],CONTROL_START:e[6],CONTROL_SIZE:e[7],METRICS_START:e[8],METRICS_SIZE:e[9],NODE_TREE_START:e[10],NODE_TREE_SIZE:e[11],NODE_TREE_HEADER_SIZE:e[12],NODE_TREE_ENTRY_SIZE:e[13],NODE_TREE_DEF_NAME_SIZE:e[14],NODE_TREE_MIRROR_MAX_NODES:e[15],NTP_START_TIME_START:e[16],NTP_START_TIME_SIZE:e[17],DRIFT_OFFSET_START:e[18],DRIFT_OFFSET_SIZE:e[19],GLOBAL_OFFSET_START:e[20],GLOBAL_OFFSET_SIZE:e[21],AUDIO_CAPTURE_START:e[22],AUDIO_CAPTURE_SIZE:e[23],AUDIO_CAPTURE_HEADER_SIZE:e[24],AUDIO_CAPTURE_FRAMES:e[25],AUDIO_CAPTURE_CHANNELS:e[26],AUDIO_CAPTURE_SAMPLE_RATE:e[27],NODE_ID_COUNTER_START:e[28],NODE_ID_COUNTER_SIZE:e[29],TOTAL_BUFFER_SIZE:e[30],MAX_MESSAGE_SIZE:e[31],MESSAGE_MAGIC:e[32],PADDING_MAGIC:e[33],scheduler_slot_size:e[34],scheduler_slot_count:e[35],DEBUG_PADDING_MARKER:i[144],MESSAGE_HEADER_SIZE:16},this.bufferConstants.MESSAGE_MAGIC!==3735928559)throw new Error("Invalid buffer constants from WASM")}calculateBufferIndices(s){if(!this.bufferConstants)throw new Error("Buffer constants not loaded. Call loadBufferConstants() first.");let t=this.bufferConstants.CONTROL_START,e=this.bufferConstants.METRICS_START;if(this.CONTROL_INDICES=g(s,t),this.mode==="sab"){let i=s+e;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=s+e;this.metricsView=new Uint32Array(this.wasmMemory.buffer,i,this.bufferConstants.METRICS_SIZE/4);let o=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD);this.atomicStore(this.CONTROL_INDICES.IN_LOG_TAIL,o)}}initNodeIdCounter(){if(!this.wasmMemory||!this.bufferConstants||!this.ringBufferBase||this.mode!=="postMessage")return;let s=this.ringBufferBase+this.bufferConstants.NODE_ID_COUNTER_START;this.nodeIdCounterView=new Int32Array(this.wasmMemory.buffer,s,1),this.nodeIdRangeCount>0&&Atomics.store(this.nodeIdCounterView,0,this.nodeIdRanges[0].from)}pushNodeIdRange(s,t){if(this.nodeIdRangeCount<2){let e=this.nodeIdRanges[this.nodeIdRangeCount];e.from=s,e.to=t,this.nodeIdRangeCount++,this.nodeIdRefillRequested=!1,this.nodeIdRangeCount===1&&this.nodeIdCounterView&&Atomics.store(this.nodeIdCounterView,0,s)}}writeWorldOptionsToMemory(){if(!this.worldOptions||!this.wasmMemory)return;let s=this.ringBufferBase+65536,t=new Uint32Array(this.wasmMemory.buffer,s,32),e=new Float32Array(this.wasmMemory.buffer,s,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(s){if(!(!this.uint8View||!this.atomicView||!this.CONTROL_INDICES||!this.ringBufferBase))try{let t=this.bufferConstants.DEBUG_BUFFER_START,e=this.bufferConstants.DEBUG_BUFFER_SIZE,i=this.bufferConstants.DEBUG_PADDING_MARKER,o="[JS] "+s+`
2
+ `,E=new TextEncoder().encode(o);if(E.length>e)return;let n=this.CONTROL_INDICES.DEBUG_HEAD,f=this.atomicLoad(n),_=e-f,u=f;E.length>_&&(this.uint8View[this.ringBufferBase+t+f]=i,u=0);let c=this.ringBufferBase+t;for(let r=0;r<E.length;r++)this.uint8View[c+u+r]=E[r];let h=u+E.length;this.atomicStore(n,h),this.mode==="sab"&&Atomics.notify(this.atomicView,n,1)}catch{}}atomicLoad(s){return this.mode==="sab"?Atomics.load(this.atomicView,s):this.atomicView[s]}atomicStore(s,t){this.mode==="sab"?Atomics.store(this.atomicView,s,t):this.atomicView[s]=t}initPMPools(){if(this.mode!=="postMessage")return;let s=C;this.pmPools={replies:{message:{type:"oscReplies",messages:null,count:0},buffer:new ArrayBuffer(s.REPLY_BUFFER_SIZE),bufferView:null,entries:new Array(s.MAX_REPLY_MESSAGES).fill(null).map(()=>({offset:0,length:0,sequence:0}))},debug:{message:{type:"debugRawBatch",messages:null,count:0},buffer:new ArrayBuffer(s.DEBUG_BUFFER_SIZE),bufferView:null,entries:new Array(s.MAX_DEBUG_MESSAGES).fill(null).map(()=>({offset:0,length:0,sequence:0}))},snapshot:{message:{type:"snapshot",buffer:null,snapshotsSent:0},buffer:null,bufferView:null,size:0},log:{message:{type:"oscLog",entries:null,count:0,buffer:null},buffer:new ArrayBuffer(s.LOG_BUFFER_SIZE),bufferView:null,entries:new Array(s.MAX_LOG_ENTRIES).fill(null).map(()=>({offset:0,length:0,originalLength:0,sourceId:0,sequence:0}))},incoming:{headerBytes:new Uint8Array(16),headerView:null}};let t=this.pmPools;if(t.replies.bufferView=new Uint8Array(t.replies.buffer),t.debug.bufferView=new Uint8Array(t.debug.buffer),t.log.bufferView=new Uint8Array(t.log.buffer),t.replies.message.messages=t.replies.entries,t.debug.message.messages=t.debug.entries,t.log.message.entries=t.log.entries,t.incoming.headerView=new DataView(t.incoming.headerBytes.buffer),this.bufferConstants&&this.wasmMemory){let e=this.bufferConstants,i=e.METRICS_SIZE+e.NODE_TREE_SIZE;t.snapshot.buffer=new ArrayBuffer(i),t.snapshot.bufferView=new Uint8Array(t.snapshot.buffer),t.snapshot.size=i,t.snapshot.message.buffer=t.snapshot.buffer;let o=this.ringBufferBase+e.METRICS_START;t.snapshot.sourceView=new Uint8Array(this.wasmMemory.buffer,o,i)}}writeOscToRingBuffer(s,t=0){if(!this.bufferConstants||!this.uint8View||!this.pmPools)return!1;let e=this.bufferConstants.IN_BUFFER_SIZE,i=this.bufferConstants.MESSAGE_HEADER_SIZE,o=this.ringBufferBase+this.bufferConstants.IN_BUFFER_START,a=s.byteLength,n=i+a+3&-4,f=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD),_=this.atomicLoad(this.CONTROL_INDICES.IN_TAIL),u=O(f,_,e);if(n>u)return console.error("[AudioWorklet] Ring buffer full, dropping OSC message"),!1;let c=this.atomicLoad(this.CONTROL_INDICES.IN_SEQUENCE);this.atomicStore(this.CONTROL_INDICES.IN_SEQUENCE,c+1);let h=new Uint8Array(s),r=w({uint8View:this.uint8View,dataView:this.dataView,bufferStart:o,bufferSize:e,head:f,payload:h,sequence:c,messageMagic:this.bufferConstants.MESSAGE_MAGIC,headerSize:i,sourceId:t,headerScratch:this.pmPools.incoming.headerBytes,headerScratchView:this.pmPools.incoming.headerView});return this.atomicStore(this.CONTROL_INDICES.IN_HEAD,r),!0}readOscReplies(){if(!this.pmPools)return;let s=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);if(s===t)return;let e=this.pmPools.replies,i=C,o=0,a=0,{newTail:E,messagesRead:n}=A({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.OUT_BUFFER_START,bufferSize:this.bufferConstants.OUT_BUFFER_SIZE,head:s,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,maxMessages:i.MAX_REPLY_MESSAGES,onMessage:(f,_,u,c)=>{if(o>=i.MAX_REPLY_MESSAGES||a+_>i.REPLY_BUFFER_SIZE)return;for(let r=0;r<_;r++)e.bufferView[a+r]=this.uint8View[f+r];let h=e.entries[o];h.offset=a,h.length=_,h.sequence=u,a+=_,o++}});n>0&&this.atomicStore(this.CONTROL_INDICES.OUT_TAIL,E),o>0&&(e.message.count=o,e.message.buffer=e.buffer,this.port.postMessage(e.message))}readNodeTree(){if(!this.bufferConstants||!this.wasmMemory||this.ringBufferBase===null)return null;let s=this.bufferConstants,t=this.ringBufferBase+s.NODE_TREE_START,e=new Uint32Array(this.wasmMemory.buffer,t,2),i=e[0],o=e[1],a=t+s.NODE_TREE_HEADER_SIZE,E=s.NODE_TREE_MIRROR_MAX_NODES,n=s.NODE_TREE_ENTRY_SIZE,f=s.NODE_TREE_DEF_NAME_SIZE,_=new DataView(this.wasmMemory.buffer,a,E*n),u=[],c=0;for(let h=0;h<E&&c<i;h++){let r=h*n,l=_.getInt32(r,!0);if(l===-1)continue;c++;let S=a+r+24,m=new Uint8Array(this.wasmMemory.buffer,S,f),I="";for(let T=0;T<f&&m[T]!==0;T++)I+=String.fromCharCode(m[T]);u.push({id:l,parentId:_.getInt32(r+4,!0),isGroup:_.getInt32(r+8,!0)===1,prevId:_.getInt32(r+12,!0),nextId:_.getInt32(r+16,!0),headId:_.getInt32(r+20,!0),defName:I})}return{nodeCount:i,version:o,nodes:u}}readMetrics(){return this.metricsView?new Uint32Array(this.metricsView):null}recordOscReceived(s,t=null){if(this.metricsView){if(this.mode==="sab")Atomics.add(this.metricsView,24,1),Atomics.add(this.metricsView,25,s);else if(this.metricsView[24]++,this.metricsView[25]+=s,t){this.metricsView[22]++;let i={nonBundle:38,immediate:39,nearFuture:40,late:41}[t];i!==void 0&&this.metricsView[i]++}}}checkAndSendSnapshot(s){let t=this.bufferConstants;if(!t||!this.wasmMemory||this.ringBufferBase===null||!this.pmPools)return!1;let i=(this.ringBufferBase+t.NODE_TREE_START+4)/4,o=this.atomicView[i];if(o!==this.lastTreeVersion)this.lastTreeVersion=o,this.lastTreeSendTime=s;else{if(this.lastTreeSendTime>=0&&s-this.lastTreeSendTime<this.treeSnapshotMinInterval)return!1;this.lastTreeSendTime=s}let E=this.pmPools.snapshot;return!E.buffer||!E.sourceView?!1:(E.bufferView.set(E.sourceView),this.treeSnapshotsSent++,E.message.snapshotsSent=this.treeSnapshotsSent,this.port.postMessage(E.message),!0)}readMetricsAndTreeBuffer(){if(!this.bufferConstants||!this.wasmMemory||this.ringBufferBase===null)return null;let s=this.bufferConstants,t=this.ringBufferBase+s.METRICS_START,e=s.METRICS_SIZE+s.NODE_TREE_SIZE,i=new Uint8Array(this.wasmMemory.buffer,t,e),o=new ArrayBuffer(e);return new Uint8Array(o).set(i),o}sendLogEntries(){if(!this.CONTROL_INDICES||!this.bufferConstants||!this.pmPools)return;let s=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.IN_LOG_TAIL);if(s===t)return;let e=this.pmPools.log,i=C,o=0,a=0,{newTail:E,messagesRead:n}=A({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.IN_BUFFER_START,bufferSize:this.bufferConstants.IN_BUFFER_SIZE,head:s,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,maxMessages:i.MAX_LOG_ENTRIES,onMessage:(f,_,u,c)=>{if(o>=i.MAX_LOG_ENTRIES)return;let h=Math.min(_,i.LOG_MAX_MESSAGE_SIZE);if(a+h>i.LOG_BUFFER_SIZE)return;for(let l=0;l<h;l++)e.bufferView[a+l]=this.uint8View[f+l];let r=e.entries[o];r.offset=a,r.length=h,r.originalLength=_,r.sourceId=c??0,r.sequence=u,a+=h,o++}});n>0&&this.atomicStore(this.CONTROL_INDICES.IN_LOG_TAIL,E),o>0&&(e.message.count=o,e.message.buffer=e.buffer,this.port.postMessage(e.message))}readDebugMessages(){if(!this.pmPools)return;let s=this.atomicLoad(this.CONTROL_INDICES.DEBUG_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.DEBUG_TAIL);if(s===t)return;let e=this.pmPools.debug,i=C,o=0,a=0,{newTail:E,messagesRead:n}=A({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.DEBUG_BUFFER_START,bufferSize:this.bufferConstants.DEBUG_BUFFER_SIZE,head:s,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,maxMessages:i.MAX_DEBUG_MESSAGES,onMessage:(f,_,u,c)=>{if(o>=i.MAX_DEBUG_MESSAGES||a+_>i.DEBUG_BUFFER_SIZE)return;for(let r=0;r<_;r++)e.bufferView[a+r]=this.uint8View[f+r];let h=e.entries[o];h.offset=a,h.length=_,h.sequence=u,a+=_,o++}});n>0&&this.atomicStore(this.CONTROL_INDICES.DEBUG_TAIL,E),o>0&&(e.message.count=o,e.message.buffer=e.buffer,this.port.postMessage(e.message))}async handleMessage(s){let{data:t}=s;try{if(t.type==="osc"){this.mode==="postMessage"&&t.oscData&&(this.writeOscToRingBuffer(t.oscData,t.sourceId??0),this.recordOscReceived(t.oscData.byteLength,t.bypassCategory));return}if(t.type==="addOscPort"){let e=s.ports[0];if(e){let i=t.sourceId??0;this.portSourceIds.set(e,i),e.onmessage=o=>{if(o.data.type==="osc"&&o.data.oscData){let a=o.data.sourceId??this.portSourceIds.get(e)??0;this.writeOscToRingBuffer(o.data.oscData,a),this.recordOscReceived(o.data.oscData.byteLength,o.data.bypassCategory)}},this.oscPorts.push(e)}return}if(t.type==="clearSched"){if(this.CONTROL_INDICES){let e=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD);this.atomicStore(this.CONTROL_INDICES.IN_TAIL,e)}this.pendingClearSched=!0,t.ack&&this.port.postMessage({type:"clearSchedAck"});return}if(t.type==="nodeIdRange"){t.from!==void 0&&t.to!==void 0&&this.pushNodeIdRange(t.from,t.to);let e=s.ports[0];e&&(this.nodeIdPort=e,this.nodeIdPort.onmessage=i=>{i.data.type==="nodeIdRange"&&this.pushNodeIdRange(i.data.from,i.data.to)});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 e;if(this.mode==="sab"){if(e=t.wasmMemory,!e){this.port.postMessage({type:"error",error:"No WASM memory provided!"});return}}else{let a=t.memoryPages||1280;e=new WebAssembly.Memory({initial:a,maximum:a,shared:!0})}this.wasmMemory=e,this.worldOptions=t.worldOptions||{},this.sampleRate=t.sampleRate||48e3;let i={env:{memory:e,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:(a,E,n)=>{let f=new DataView(e.buffer),_=BigInt(Math.floor(Date.now()*1e6));return f.setBigUint64(n,_,!0),0},environ_sizes_get:()=>0,environ_get:()=>0,fd_close:()=>0,fd_write:()=>0,fd_seek:()=>0,fd_read:()=>0,proc_exit:a=>{console.error("[AudioWorklet] WASM tried to exit with code:",a)}}},o=await WebAssembly.compile(t.wasmBytes);if(this.wasmInstance=await WebAssembly.instantiate(o,i),this.wasmInstance.exports.get_ring_buffer_base&&(this.ringBufferBase=this.wasmInstance.exports.get_ring_buffer_base(),this.loadBufferConstants(),this.calculateBufferIndices(this.ringBufferBase),this.initPMPools(),this.writeWorldOptionsToMemory(),this.wasmInstance.exports.init_memory)){this.wasmInstance.exports.init_memory(this.sampleRate),this.initNodeIdCounter(),this.isInitialized=!0;let a=this.mode==="postMessage"?this.readMetricsAndTreeBuffer():void 0,E={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:a};this.port.postMessage(E,a?[a]:[])}}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.initPMPools(),this.writeWorldOptionsToMemory(),this.wasmInstance.exports.init_memory))){this.wasmInstance.exports.init_memory(this.sampleRate),this.initNodeIdCounter(),this.isInitialized=!0;let e=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:e};this.port.postMessage(i,e?[e]:[])}}if(t.type==="getVersion")if(this.wasmInstance&&this.wasmInstance.exports.get_supersonic_version_string){let e=this.wasmInstance.exports.get_supersonic_version_string(),i=new Uint8Array(this.wasmMemory.buffer),o="";for(let a=e;i[a]!==0;a++)o+=String.fromCharCode(i[a]);this.port.postMessage({type:"version",version:o})}else this.port.postMessage({type:"version",version:"unknown"});if(t.type==="getTimeOffset")if(this.wasmInstance&&this.wasmInstance.exports.get_time_offset){let e=this.wasmInstance.exports.get_time_offset();this.port.postMessage({type:"timeOffset",offset:e})}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 e=this.ringBufferBase+this.bufferConstants.NTP_START_TIME_START,i=new Float64Array(this.wasmMemory.buffer,e,1);i[0]=t.ntpStartTime}if(t.type==="setDriftOffset"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let e=this.ringBufferBase+this.bufferConstants.DRIFT_OFFSET_START,i=new Int32Array(this.wasmMemory.buffer,e,1);i[0]=t.driftOffsetMs}if(t.type==="setClockOffset"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let e=this.ringBufferBase+this.bufferConstants.GLOBAL_OFFSET_START,i=new Int32Array(this.wasmMemory.buffer,e,1);i[0]=t.clockOffsetMs}if(t.type==="getMetrics"){let e=this.metricsView?new Uint32Array(this.metricsView):null;this.port.postMessage({type:"metricsSnapshot",requestId:t.requestId,metrics:e})}if(t.type==="copyBufferData")try{let{copyId:e,ptr:i,data:o}=t;if(!this.wasmMemory||!this.wasmMemory.buffer)throw new Error("WASM memory not initialized");let a=new Float32Array(o);new Float32Array(this.wasmMemory.buffer,i,a.length).set(a),this.port.postMessage({type:"bufferCopied",copyId:e,success:!0})}catch(e){console.error("[AudioWorklet] Buffer copy failed:",e),this.port.postMessage({type:"bufferCopied",copyId:t.copyId,success:!1,error:e.message})}}catch(e){console.error("[AudioWorklet] Error handling message:",e),this.port.postMessage({type:"error",error:e.message,stack:e.stack})}}process(s,t,e){if(this.processCallCount++,!this.isInitialized)return!0;try{if(this.wasmInstance&&this.wasmInstance.exports.process_audio){this.pendingClearSched&&(this.pendingClearSched=!1,this.wasmInstance.exports.clear_scheduler&&this.wasmInstance.exports.clear_scheduler());let i=currentTime,o=s[0]?.length||0,a=t[0]?.length||0;if(o>0&&this.wasmInstance?.exports?.get_audio_input_bus)try{let n=this.wasmInstance.exports.get_audio_input_bus(),f=this.wasmInstance.exports.get_audio_buffer_samples();if(n&&n>0){let _=this.sharedBuffer||this.wasmMemory?.buffer;if(_){let u=this.worldOptions?.numInputBusChannels||2,c=Math.min(o,u);(!this.inputView||this.lastInputBusPtr!==n||this.lastInputChannels!==u)&&(this.inputView=new Float32Array(_,n,f*u),this.lastInputBusPtr=n,this.lastInputChannels=u);for(let h=0;h<c;h++)s[0]?.[h]&&this.inputView.set(s[0][h],h*f)}}}catch{}let E=this.wasmInstance.exports.process_audio(i,a,o);if(this.nodeIdCounterView&&this.nodeIdRangeCount>0){let n=Atomics.load(this.nodeIdCounterView,0);if(n>=this.nodeIdRanges[0].to){if(this.nodeIdRangeCount>1){let f=this.nodeIdRanges[1];this.nodeIdRanges[0].from=f.from,this.nodeIdRanges[0].to=f.to,f.from=0,f.to=0,this.nodeIdRangeCount=1,Atomics.store(this.nodeIdCounterView,0,this.nodeIdRanges[0].from)}!this.nodeIdRefillRequested&&this.nodeIdPort&&(this.nodeIdRefillRequested=!0,this.nodeIdPort.postMessage({type:"requestNodeIdRange"}))}else if(!this.nodeIdRefillRequested&&this.nodeIdRangeCount<2&&this.nodeIdPort){let f=this.nodeIdRanges[0].to-n,_=this.nodeIdRanges[0].to-this.nodeIdRanges[0].from;f<=_>>>1&&(this.nodeIdRefillRequested=!0,this.nodeIdPort.postMessage({type:"requestNodeIdRange"}))}}if(this.wasmInstance.exports.get_audio_output_bus&&t[0]&&t[0].length>=1)try{let n=this.wasmInstance.exports.get_audio_output_bus(),f=this.wasmInstance.exports.get_audio_buffer_samples();if(n&&n>0){let _=this.wasmInstance.exports.memory||this.wasmMemory;if(!_||!_.buffer)return!0;let u=_.buffer,c=u.byteLength,h=this.worldOptions?.numOutputBusChannels||2,r=Math.min(t[0].length,h),l=n+f*r*4;if(n<0||n>c||l>c)return!0;if((!this.audioView||this.lastAudioBufferPtr!==n||this.lastWasmBufferSize!==c||this.lastNumChannels!==r||u!==this.audioView.buffer)&&(this.audioView=new Float32Array(u,n,f*r),this.lastAudioBufferPtr=n,this.lastWasmBufferSize=c),!this.channelViews||this.lastNumSamples!==f||this.lastNumChannels!==r||this.channelViews[0].buffer!==this.audioView.buffer){this.channelViews=new Array(r);for(let S=0;S<r;S++)this.channelViews[S]=this.audioView.subarray(S*f,(S+1)*f);this.lastNumSamples=f,this.lastNumChannels=r}for(let S=0;S<r;S++)t[0][S].set(this.channelViews[S])}}catch{}if(this.mode==="postMessage")this.readOscReplies(),this.readDebugMessages(),this.checkAndSendSnapshot(i)&&this.sendLogEntries();else if(this.atomicView){let n=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),f=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);n!==f&&Atomics.notify(this.atomicView,this.CONTROL_INDICES.OUT_HEAD,1);let _=this.atomicLoad(this.CONTROL_INDICES.DEBUG_HEAD),u=this.atomicLoad(this.CONTROL_INDICES.DEBUG_TAIL);_!==u&&Atomics.notify(this.atomicView,this.CONTROL_INDICES.DEBUG_HEAD,1),Atomics.notify(this.atomicView,this.CONTROL_INDICES.IN_TAIL,1)}return this.processCallCount%3750===0&&this.checkStatus(),E!==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 s=this.atomicLoad(this.CONTROL_INDICES.STATUS_FLAGS);if(s!==this.STATUS_FLAGS.OK){this._statusObj.bufferFull=!!(s&this.STATUS_FLAGS.BUFFER_FULL),this._statusObj.overrun=!!(s&this.STATUS_FLAGS.OVERRUN),this._statusObj.wasmError=!!(s&this.STATUS_FLAGS.WASM_ERROR),this._statusObj.fragmented=!!(s&this.STATUS_FLAGS.FRAGMENTED_MSG),this._metricsObj.processCount=this.metricsView[0],this._metricsObj.messagesProcessed=this.metricsView[1],this._metricsObj.messagesDropped=this.metricsView[2],this._metricsObj.schedulerQueueDepth=this.metricsView[3],this._metricsObj.schedulerQueueMax=this.metricsView[4],this._metricsObj.schedulerQueueDropped=this.metricsView[5],this._statusMessage.flags=s,this.port.postMessage(this._statusMessage);let t=s&this.STATUS_FLAGS.BUFFER_FULL;this.atomicStore(this.CONTROL_INDICES.STATUS_FLAGS,t)}}};registerProcessor("scsynth-processor",R);})();