supersonic-scsynth-core 0.25.5 → 0.27.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.25.5",
3
+ "version": "0.27.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 C(l,e,t){return(t-1-l+e)%t}function g({uint8View:l,dataView:e,bufferStart:t,bufferSize:s,head:i,payload:a,sequence:n,messageMagic:h,headerSize:r}){let u=a.length,c=r+u+3&-4,o=s-i;if(c>o){let f=new Uint8Array(r),E=new DataView(f.buffer);E.setUint32(0,h,!0),E.setUint32(4,c,!0),E.setUint32(8,n,!0),E.setUint32(12,0,!0);let S=t+i,p=t;if(o>=r){l.set(f,S);let m=o-r;m>0&&l.set(a.subarray(0,m),S+r),l.set(a.subarray(m),p)}else{l.set(f.subarray(0,o),S),l.set(f.subarray(o),p);let m=r-o;l.set(a,p+m)}}else{let f=t+i;e.setUint32(f,h,!0),e.setUint32(f+4,c,!0),e.setUint32(f+8,n,!0),e.setUint32(f+12,0,!0),l.set(a,f+r)}return(i+c)%s}function I({uint8View:l,dataView:e,bufferStart:t,bufferSize:s,head:i,tail:a,messageMagic:n,paddingMagic:h,headerSize:r,maxMessages:u=1/0,onMessage:_,onCorruption:c}){let o=a,f=0;for(;o!==i&&f<u;){if(s-o<r){o=0;continue}let S=t+o,p=e.getUint32(S,!0);if(p===h){o=0;continue}if(p!==n){c&&c(o),o=(o+1)%s;continue}let m=e.getUint32(S+4,!0),T=e.getUint32(S+8,!0);if(m<r||m>s){c&&c(o),o=(o+1)%s;continue}let d=m-r,O=S+r,R=new Uint8Array(d);for(let w=0;w<d;w++)R[w]=l[O+w];_(R,T,m),o=(o+m)%s,f++}return{newTail:o,messagesRead:f}}var A=class extends AudioWorkletProcessor{constructor(){super(),this.mode="sab",this.sharedBuffer=null,this.wasmModule=null,this.wasmInstance=null,this.isInitialized=!1,this.processCallCount=0,this.lastStatusCheck=0,this.ringBufferBase=null,this.audioView=null,this.lastAudioBufferPtr=0,this.lastWasmBufferSize=0,this.lastTreeVersion=-1,this.treeSnapshotsSent=0,this.lastTreeSendTime=-1,this.treeSnapshotMinInterval=.025,this.atomicView=null,this.uint8View=null,this.dataView=null,this.localClockOffsetView=null,this.bufferConstants=null,this.CONTROL_INDICES=null,this.metricsView=null,this.STATUS_FLAGS={OK:0,BUFFER_FULL:1,OVERRUN:2,WASM_ERROR:4,FRAGMENTED_MSG:8},this.oscQueue=[],this.port.onmessage=this.handleMessage.bind(this)}loadBufferConstants(){if(!this.wasmInstance||!this.wasmInstance.exports.get_buffer_layout)throw new Error("WASM instance does not export get_buffer_layout");let e=this.wasmInstance.exports.get_buffer_layout(),t=this.wasmMemory;if(!t)throw new Error("WASM memory not available");let s=new Uint32Array(t.buffer,e,34),i=new Uint8Array(t.buffer,e,140);if(this.bufferConstants={IN_BUFFER_START:s[0],IN_BUFFER_SIZE:s[1],OUT_BUFFER_START:s[2],OUT_BUFFER_SIZE:s[3],DEBUG_BUFFER_START:s[4],DEBUG_BUFFER_SIZE:s[5],CONTROL_START:s[6],CONTROL_SIZE:s[7],METRICS_START:s[8],METRICS_SIZE:s[9],NODE_TREE_START:s[10],NODE_TREE_SIZE:s[11],NODE_TREE_HEADER_SIZE:s[12],NODE_TREE_ENTRY_SIZE:s[13],NODE_TREE_DEF_NAME_SIZE:s[14],NODE_TREE_MAX_NODES:s[15],NTP_START_TIME_START:s[16],NTP_START_TIME_SIZE:s[17],DRIFT_OFFSET_START:s[18],DRIFT_OFFSET_SIZE:s[19],GLOBAL_OFFSET_START:s[20],GLOBAL_OFFSET_SIZE:s[21],AUDIO_CAPTURE_START:s[22],AUDIO_CAPTURE_SIZE:s[23],AUDIO_CAPTURE_HEADER_SIZE:s[24],AUDIO_CAPTURE_FRAMES:s[25],AUDIO_CAPTURE_CHANNELS:s[26],AUDIO_CAPTURE_SAMPLE_RATE:s[27],TOTAL_BUFFER_SIZE:s[28],MAX_MESSAGE_SIZE:s[29],MESSAGE_MAGIC:s[30],PADDING_MAGIC:s[31],scheduler_slot_size:s[32],scheduler_slot_count:s[33],DEBUG_PADDING_MARKER:i[136],MESSAGE_HEADER_SIZE:16},this.bufferConstants.MESSAGE_MAGIC!==3735928559)throw new Error("Invalid buffer constants from WASM")}calculateBufferIndices(e){if(!this.bufferConstants)throw new Error("Buffer constants not loaded. Call loadBufferConstants() first.");let t=this.bufferConstants.CONTROL_START,s=this.bufferConstants.METRICS_START;if(this.CONTROL_INDICES={IN_HEAD:(e+t+0)/4,IN_TAIL:(e+t+4)/4,OUT_HEAD:(e+t+8)/4,OUT_TAIL:(e+t+12)/4,DEBUG_HEAD:(e+t+16)/4,DEBUG_TAIL:(e+t+20)/4,IN_SEQUENCE:(e+t+24)/4,OUT_SEQUENCE:(e+t+28)/4,DEBUG_SEQUENCE:(e+t+32)/4,STATUS_FLAGS:(e+t+36)/4,IN_WRITE_LOCK:(e+t+40)/4},this.mode==="sab"){let i=e+s;this.metricsView=new Uint32Array(this.sharedBuffer,i,this.bufferConstants.METRICS_SIZE/4)}else{this.atomicView=new Int32Array(this.wasmMemory.buffer),this.uint8View=new Uint8Array(this.wasmMemory.buffer),this.dataView=new DataView(this.wasmMemory.buffer);let i=e+s;this.metricsView=new Uint32Array(this.wasmMemory.buffer,i,this.bufferConstants.METRICS_SIZE/4)}}writeWorldOptionsToMemory(){if(!this.worldOptions||!this.wasmMemory)return;let e=this.ringBufferBase+65536,t=new Uint32Array(this.wasmMemory.buffer,e,32),s=new Float32Array(this.wasmMemory.buffer,e,32);t[0]=this.worldOptions.numBuffers||1024,t[1]=this.worldOptions.maxNodes||1024,t[2]=this.worldOptions.maxGraphDefs||1024,t[3]=this.worldOptions.maxWireBufs||64,t[4]=this.worldOptions.numAudioBusChannels||128,t[5]=this.worldOptions.numInputBusChannels||0,t[6]=this.worldOptions.numOutputBusChannels||0,t[7]=this.worldOptions.numControlBusChannels||4096,t[8]=this.worldOptions.bufLength||128,t[9]=this.worldOptions.realTimeMemorySize||16384,t[10]=this.worldOptions.numRGens||64,t[11]=this.worldOptions.realTime?1:0,t[12]=this.worldOptions.memoryLocking?1:0,t[13]=this.worldOptions.loadGraphDefs||0,t[14]=this.worldOptions.preferredSampleRate||0,t[15]=this.worldOptions.verbosity||0}js_debug(e){if(!(!this.uint8View||!this.atomicView||!this.CONTROL_INDICES||!this.ringBufferBase))try{let t=this.bufferConstants.DEBUG_BUFFER_START,s=this.bufferConstants.DEBUG_BUFFER_SIZE,i=this.bufferConstants.DEBUG_PADDING_MARKER,a="[JS] "+e+`
2
- `,h=new TextEncoder().encode(a);if(h.length>s)return;let r=this.CONTROL_INDICES.DEBUG_HEAD,u=this.atomicLoad(r),_=s-u,c=u;h.length>_&&(this.uint8View[this.ringBufferBase+t+u]=i,c=0);let o=this.ringBufferBase+t;for(let E=0;E<h.length;E++)this.uint8View[o+c+E]=h[E];let f=c+h.length;this.atomicStore(r,f)}catch{}}atomicLoad(e){return this.mode==="sab"?Atomics.load(this.atomicView,e):this.atomicView[e]}atomicStore(e,t){this.mode==="sab"?Atomics.store(this.atomicView,e,t):this.atomicView[e]=t}drainOscQueue(){if(this.oscQueue.length===0)return;let e=this.bufferConstants.IN_BUFFER_SIZE,t=this.bufferConstants.MESSAGE_HEADER_SIZE,s=this.ringBufferBase+this.bufferConstants.IN_BUFFER_START;for(;this.oscQueue.length>0;){let i=this.oscQueue[0],a=i.byteLength,h=t+a+3&-4,r=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD),u=this.atomicLoad(this.CONTROL_INDICES.IN_TAIL),_=C(r,u,e);if(h>_)break;this.oscQueue.shift();let c=this.atomicLoad(this.CONTROL_INDICES.IN_SEQUENCE);this.atomicStore(this.CONTROL_INDICES.IN_SEQUENCE,c+1);let o=new Uint8Array(i),f=g({uint8View:this.uint8View,dataView:this.dataView,bufferStart:s,bufferSize:e,head:r,payload:o,sequence:c,messageMagic:this.bufferConstants.MESSAGE_MAGIC,headerSize:t});this.atomicStore(this.CONTROL_INDICES.IN_HEAD,f)}}readOscReplies(){let e=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);if(e===t)return;let s=[],{newTail:i,messagesRead:a}=I({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.OUT_BUFFER_START,bufferSize:this.bufferConstants.OUT_BUFFER_SIZE,head:e,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,onMessage:(n,h)=>{s.push({oscData:n.buffer,sequence:h})}});a>0&&this.atomicStore(this.CONTROL_INDICES.OUT_TAIL,i),s.length>0&&this.port.postMessage({type:"oscReplies",messages:s})}readNodeTree(){if(!this.bufferConstants||!this.wasmMemory||this.ringBufferBase===null)return null;let e=this.bufferConstants,t=this.ringBufferBase+e.NODE_TREE_START,s=new Uint32Array(this.wasmMemory.buffer,t,2),i=s[0],a=s[1],n=t+e.NODE_TREE_HEADER_SIZE,h=e.NODE_TREE_MAX_NODES,r=e.NODE_TREE_ENTRY_SIZE,u=e.NODE_TREE_DEF_NAME_SIZE,_=new DataView(this.wasmMemory.buffer,n,h*r),c=[],o=0;for(let f=0;f<h&&o<i;f++){let E=f*r,S=_.getInt32(E,!0);if(S===-1)continue;o++;let p=n+E+24,m=new Uint8Array(this.wasmMemory.buffer,p,u),T="";for(let d=0;d<u&&m[d]!==0;d++)T+=String.fromCharCode(m[d]);c.push({id:S,parentId:_.getInt32(E+4,!0),isGroup:_.getInt32(E+8,!0)===1,prevId:_.getInt32(E+12,!0),nextId:_.getInt32(E+16,!0),headId:_.getInt32(E+20,!0),defName:T})}return{nodeCount:i,version:a,nodes:c}}readMetrics(){return this.metricsView?new Uint32Array(this.metricsView):null}checkAndSendSnapshot(e){let t=this.bufferConstants;if(!t||!this.wasmMemory||this.ringBufferBase===null)return;let s=this.ringBufferBase+t.NODE_TREE_START,a=new Uint32Array(this.wasmMemory.buffer,s,2)[1];if(a!==this.lastTreeVersion)this.lastTreeVersion=a,this.lastTreeSendTime=e;else{if(this.lastTreeSendTime>=0&&e-this.lastTreeSendTime<this.treeSnapshotMinInterval)return;this.lastTreeSendTime=e}let h=this.readMetricsAndTreeBuffer();h&&(this.treeSnapshotsSent++,this.port.postMessage({type:"snapshot",buffer:h,snapshotsSent:this.treeSnapshotsSent},[h]))}readMetricsAndTreeBuffer(){if(!this.bufferConstants||!this.wasmMemory||this.ringBufferBase===null)return null;let e=this.bufferConstants,t=this.ringBufferBase+e.METRICS_START,s=e.METRICS_SIZE+e.NODE_TREE_SIZE,i=new Uint8Array(this.wasmMemory.buffer,t,s),a=new ArrayBuffer(s);return new Uint8Array(a).set(i),a}readDebugMessages(){let e=this.atomicLoad(this.CONTROL_INDICES.DEBUG_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.DEBUG_TAIL);if(e===t)return;let s=[],{newTail:i,messagesRead:a}=I({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.DEBUG_BUFFER_START,bufferSize:this.bufferConstants.DEBUG_BUFFER_SIZE,head:e,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,onMessage:(n,h)=>{s.push({bytes:n.buffer,sequence:h})}});a>0&&this.atomicStore(this.CONTROL_INDICES.DEBUG_TAIL,i),s.length>0&&this.port.postMessage({type:"debugRawBatch",messages:s},s.map(n=>n.bytes))}async handleMessage(e){let{data:t}=e;try{if(t.type==="osc"){this.mode==="postMessage"&&t.oscData&&this.oscQueue.push(t.oscData);return}if(t.type==="init"&&(this.mode=t.mode||"sab",t.snapshotIntervalMs&&(this.treeSnapshotMinInterval=t.snapshotIntervalMs/1e3),this.mode==="sab"&&t.sharedBuffer&&(this.sharedBuffer=t.sharedBuffer,this.atomicView=new Int32Array(this.sharedBuffer),this.uint8View=new Uint8Array(this.sharedBuffer),this.dataView=new DataView(this.sharedBuffer))),t.type==="loadWasm"){if(t.wasmBytes){let s;if(this.mode==="sab"){if(s=t.wasmMemory,!s){this.port.postMessage({type:"error",error:"No WASM memory provided!"});return}}else{let n=t.memoryPages||1280;s=new WebAssembly.Memory({initial:n,maximum:n,shared:!0})}this.wasmMemory=s,this.worldOptions=t.worldOptions||{},this.sampleRate=t.sampleRate||48e3;let i={env:{memory:s,emscripten_asm_const_double:()=>Date.now()*1e3,__syscall_getdents64:()=>0,__syscall_unlinkat:()=>0,_emscripten_init_main_thread_js:()=>{},_emscripten_thread_mailbox_await:()=>{},_emscripten_thread_set_strongref:()=>{},emscripten_exit_with_live_runtime:()=>{},_emscripten_receive_on_main_thread_js:()=>{},emscripten_check_blocking_allowed:()=>{},_emscripten_thread_cleanup:()=>{},emscripten_num_logical_cores:()=>1,_emscripten_notify_mailbox_postmessage:()=>{}},wasi_snapshot_preview1:{clock_time_get:(n,h,r)=>{let u=new DataView(s.buffer),_=BigInt(Math.floor(Date.now()*1e6));return u.setBigUint64(r,_,!0),0},environ_sizes_get:()=>0,environ_get:()=>0,fd_close:()=>0,fd_write:()=>0,fd_seek:()=>0,fd_read:()=>0,proc_exit:n=>{console.error("[AudioWorklet] WASM tried to exit with code:",n)}}},a=await WebAssembly.compile(t.wasmBytes);if(this.wasmInstance=await WebAssembly.instantiate(a,i),this.wasmInstance.exports.get_ring_buffer_base&&(this.ringBufferBase=this.wasmInstance.exports.get_ring_buffer_base(),this.loadBufferConstants(),this.calculateBufferIndices(this.ringBufferBase),this.writeWorldOptionsToMemory(),this.wasmInstance.exports.init_memory)){this.wasmInstance.exports.init_memory(this.sampleRate),this.isInitialized=!0;let n=this.mode==="postMessage"?this.readMetricsAndTreeBuffer():void 0,h={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:n};this.port.postMessage(h,n?[n]:[])}}else if(t.wasmInstance&&(this.wasmInstance=t.wasmInstance,this.wasmInstance.exports.get_ring_buffer_base&&(this.ringBufferBase=this.wasmInstance.exports.get_ring_buffer_base(),this.loadBufferConstants(),this.calculateBufferIndices(this.ringBufferBase),this.writeWorldOptionsToMemory(),this.wasmInstance.exports.init_memory))){this.wasmInstance.exports.init_memory(this.sampleRate),this.isInitialized=!0;let s=this.mode==="postMessage"?this.readMetricsAndTreeBuffer():void 0,i={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:s};this.port.postMessage(i,s?[s]:[])}}if(t.type==="getVersion")if(this.wasmInstance&&this.wasmInstance.exports.get_supersonic_version_string){let s=this.wasmInstance.exports.get_supersonic_version_string(),i=new Uint8Array(this.wasmMemory.buffer),a="";for(let n=s;i[n]!==0;n++)a+=String.fromCharCode(i[n]);this.port.postMessage({type:"version",version:a})}else this.port.postMessage({type:"version",version:"unknown"});if(t.type==="getTimeOffset")if(this.wasmInstance&&this.wasmInstance.exports.get_time_offset){let s=this.wasmInstance.exports.get_time_offset();this.port.postMessage({type:"timeOffset",offset:s})}else console.error("[AudioWorklet] get_time_offset not available! wasmInstance:",!!this.wasmInstance),this.port.postMessage({type:"error",error:"get_time_offset function not available in WASM exports"});if(t.type==="setNTPStartTime"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.NTP_START_TIME_START,i=new Float64Array(this.wasmMemory.buffer,s,1);i[0]=t.ntpStartTime}if(t.type==="setGlobalOffset"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.GLOBAL_OFFSET_START,i=new Int32Array(this.wasmMemory.buffer,s,1);i[0]=t.globalOffsetMs}if(t.type==="getMetrics"){let s=this.metricsView?new Uint32Array(this.metricsView):null;this.port.postMessage({type:"metricsSnapshot",requestId:t.requestId,metrics:s})}if(t.type==="copyBufferData")try{let{copyId:s,ptr:i,data:a}=t;if(!this.wasmMemory||!this.wasmMemory.buffer)throw new Error("WASM memory not initialized");let n=new Float32Array(a);new Float32Array(this.wasmMemory.buffer,i,n.length).set(n),this.port.postMessage({type:"bufferCopied",copyId:s,success:!0})}catch(s){console.error("[AudioWorklet] Buffer copy failed:",s),this.port.postMessage({type:"bufferCopied",copyId:t.copyId,success:!1,error:s.message})}}catch(s){console.error("[AudioWorklet] Error handling message:",s),this.port.postMessage({type:"error",error:s.message,stack:s.stack})}}process(e,t,s){if(this.processCallCount++,!this.isInitialized)return!0;try{if(this.wasmInstance&&this.wasmInstance.exports.process_audio){this.mode==="postMessage"&&this.drainOscQueue();let i=currentTime,a=e[0]?.length||0,n=t[0]?.length||0;if(a>0&&this.wasmInstance?.exports?.get_audio_input_bus)try{let r=this.wasmInstance.exports.get_audio_input_bus(),u=this.wasmInstance.exports.get_audio_buffer_samples();if(r&&r>0){let _=this.sharedBuffer||this.wasmMemory?.buffer;if(_){let c=this.worldOptions?.numInputBusChannels||2,o=Math.min(a,c);(!this.inputView||this.lastInputBusPtr!==r||this.lastInputChannels!==c)&&(this.inputView=new Float32Array(_,r,u*c),this.lastInputBusPtr=r,this.lastInputChannels=c);for(let f=0;f<o;f++)e[0]?.[f]&&this.inputView.set(e[0][f],f*u)}}}catch{}let h=this.wasmInstance.exports.process_audio(i,n,a);if(this.wasmInstance.exports.get_audio_output_bus&&t[0]&&t[0].length>=2)try{let r=this.wasmInstance.exports.get_audio_output_bus(),u=this.wasmInstance.exports.get_audio_buffer_samples();if(r&&r>0){let _=this.wasmInstance.exports.memory||this.wasmMemory;if(!_||!_.buffer)return!0;let c=_.buffer,o=c.byteLength,f=r+u*2*4;if(r<0||r>o||f>o)return!0;(!this.audioView||this.lastAudioBufferPtr!==r||this.lastWasmBufferSize!==o||c!==this.audioView.buffer)&&(this.audioView=new Float32Array(c,r,u*2),this.lastAudioBufferPtr=r,this.lastWasmBufferSize=o),t[0][0].set(this.audioView.subarray(0,u)),t[0][1].set(this.audioView.subarray(u,u*2))}}catch{}if(this.mode==="postMessage")this.readOscReplies(),this.readDebugMessages(),this.checkAndSendSnapshot(i);else if(this.atomicView){let r=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),u=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);r!==u&&Atomics.notify(this.atomicView,this.CONTROL_INDICES.OUT_HEAD,1)}return this.processCallCount%3750===0&&this.checkStatus(),h!==0}}catch(i){console.error("[AudioWorklet] process() error:",i),console.error("[AudioWorklet] Stack:",i.stack),this.atomicView&&this.mode==="sab"&&Atomics.or(this.atomicView,this.CONTROL_INDICES.STATUS_FLAGS,this.STATUS_FLAGS.WASM_ERROR)}return!0}checkStatus(){if(!this.atomicView)return;let e=this.atomicLoad(this.CONTROL_INDICES.STATUS_FLAGS);if(e!==this.STATUS_FLAGS.OK){let t={bufferFull:!!(e&this.STATUS_FLAGS.BUFFER_FULL),overrun:!!(e&this.STATUS_FLAGS.OVERRUN),wasmError:!!(e&this.STATUS_FLAGS.WASM_ERROR),fragmented:!!(e&this.STATUS_FLAGS.FRAGMENTED_MSG)},s={processCount:this.metricsView[0],messagesProcessed:this.metricsView[1],messagesDropped:this.metricsView[2],schedulerQueueDepth:this.metricsView[3],schedulerQueueMax:this.metricsView[4],schedulerQueueDropped:this.metricsView[5]};this.port.postMessage({type:"status",flags:e,status:t,metrics:s});let i=e&this.STATUS_FLAGS.BUFFER_FULL;this.atomicStore(this.CONTROL_INDICES.STATUS_FLAGS,i)}}};registerProcessor("scsynth-processor",A);})();
1
+ (()=>{function C(l,e,t){return(t-1-l+e)%t}function O({uint8View:l,dataView:e,bufferStart:t,bufferSize:s,head:i,payload:a,sequence:n,messageMagic:h,headerSize:r}){let u=a.length,c=r+u+3&-4,o=s-i;if(c>o){let f=new Uint8Array(r),E=new DataView(f.buffer);E.setUint32(0,h,!0),E.setUint32(4,c,!0),E.setUint32(8,n,!0),E.setUint32(12,0,!0);let S=t+i,p=t;if(o>=r){l.set(f,S);let m=o-r;m>0&&l.set(a.subarray(0,m),S+r),l.set(a.subarray(m),p)}else{l.set(f.subarray(0,o),S),l.set(f.subarray(o),p);let m=r-o;l.set(a,p+m)}}else{let f=t+i;e.setUint32(f,h,!0),e.setUint32(f+4,c,!0),e.setUint32(f+8,n,!0),e.setUint32(f+12,0,!0),l.set(a,f+r)}return(i+c)%s}function I({uint8View:l,dataView:e,bufferStart:t,bufferSize:s,head:i,tail:a,messageMagic:n,paddingMagic:h,headerSize:r,maxMessages:u=1/0,onMessage:_,onCorruption:c}){let o=a,f=0;for(;o!==i&&f<u;){if(s-o<r){o=0;continue}let S=t+o,p=e.getUint32(S,!0);if(p===h){o=0;continue}if(p!==n){c&&c(o),o=(o+1)%s;continue}let m=e.getUint32(S+4,!0),T=e.getUint32(S+8,!0);if(m<r||m>s){c&&c(o),o=(o+1)%s;continue}let d=m-r,g=S+r,R=new Uint8Array(d);for(let w=0;w<d;w++)R[w]=l[g+w];_(R,T,m),o=(o+m)%s,f++}return{newTail:o,messagesRead:f}}var A=class extends AudioWorkletProcessor{constructor(){super(),this.mode="sab",this.sharedBuffer=null,this.wasmModule=null,this.wasmInstance=null,this.isInitialized=!1,this.processCallCount=0,this.lastStatusCheck=0,this.ringBufferBase=null,this.audioView=null,this.lastAudioBufferPtr=0,this.lastWasmBufferSize=0,this.lastTreeVersion=-1,this.treeSnapshotsSent=0,this.lastTreeSendTime=-1,this.treeSnapshotMinInterval=.025,this.atomicView=null,this.uint8View=null,this.dataView=null,this.localClockOffsetView=null,this.bufferConstants=null,this.CONTROL_INDICES=null,this.metricsView=null,this.STATUS_FLAGS={OK:0,BUFFER_FULL:1,OVERRUN:2,WASM_ERROR:4,FRAGMENTED_MSG:8},this.oscQueue=[],this.port.onmessage=this.handleMessage.bind(this)}loadBufferConstants(){if(!this.wasmInstance||!this.wasmInstance.exports.get_buffer_layout)throw new Error("WASM instance does not export get_buffer_layout");let e=this.wasmInstance.exports.get_buffer_layout(),t=this.wasmMemory;if(!t)throw new Error("WASM memory not available");let s=new Uint32Array(t.buffer,e,34),i=new Uint8Array(t.buffer,e,140);if(this.bufferConstants={IN_BUFFER_START:s[0],IN_BUFFER_SIZE:s[1],OUT_BUFFER_START:s[2],OUT_BUFFER_SIZE:s[3],DEBUG_BUFFER_START:s[4],DEBUG_BUFFER_SIZE:s[5],CONTROL_START:s[6],CONTROL_SIZE:s[7],METRICS_START:s[8],METRICS_SIZE:s[9],NODE_TREE_START:s[10],NODE_TREE_SIZE:s[11],NODE_TREE_HEADER_SIZE:s[12],NODE_TREE_ENTRY_SIZE:s[13],NODE_TREE_DEF_NAME_SIZE:s[14],NODE_TREE_MIRROR_MAX_NODES:s[15],NTP_START_TIME_START:s[16],NTP_START_TIME_SIZE:s[17],DRIFT_OFFSET_START:s[18],DRIFT_OFFSET_SIZE:s[19],GLOBAL_OFFSET_START:s[20],GLOBAL_OFFSET_SIZE:s[21],AUDIO_CAPTURE_START:s[22],AUDIO_CAPTURE_SIZE:s[23],AUDIO_CAPTURE_HEADER_SIZE:s[24],AUDIO_CAPTURE_FRAMES:s[25],AUDIO_CAPTURE_CHANNELS:s[26],AUDIO_CAPTURE_SAMPLE_RATE:s[27],TOTAL_BUFFER_SIZE:s[28],MAX_MESSAGE_SIZE:s[29],MESSAGE_MAGIC:s[30],PADDING_MAGIC:s[31],scheduler_slot_size:s[32],scheduler_slot_count:s[33],DEBUG_PADDING_MARKER:i[136],MESSAGE_HEADER_SIZE:16},this.bufferConstants.MESSAGE_MAGIC!==3735928559)throw new Error("Invalid buffer constants from WASM")}calculateBufferIndices(e){if(!this.bufferConstants)throw new Error("Buffer constants not loaded. Call loadBufferConstants() first.");let t=this.bufferConstants.CONTROL_START,s=this.bufferConstants.METRICS_START;if(this.CONTROL_INDICES={IN_HEAD:(e+t+0)/4,IN_TAIL:(e+t+4)/4,OUT_HEAD:(e+t+8)/4,OUT_TAIL:(e+t+12)/4,DEBUG_HEAD:(e+t+16)/4,DEBUG_TAIL:(e+t+20)/4,IN_SEQUENCE:(e+t+24)/4,OUT_SEQUENCE:(e+t+28)/4,DEBUG_SEQUENCE:(e+t+32)/4,STATUS_FLAGS:(e+t+36)/4,IN_WRITE_LOCK:(e+t+40)/4},this.mode==="sab"){let i=e+s;this.metricsView=new Uint32Array(this.sharedBuffer,i,this.bufferConstants.METRICS_SIZE/4)}else{this.atomicView=new Int32Array(this.wasmMemory.buffer),this.uint8View=new Uint8Array(this.wasmMemory.buffer),this.dataView=new DataView(this.wasmMemory.buffer);let i=e+s;this.metricsView=new Uint32Array(this.wasmMemory.buffer,i,this.bufferConstants.METRICS_SIZE/4)}}writeWorldOptionsToMemory(){if(!this.worldOptions||!this.wasmMemory)return;let e=this.ringBufferBase+65536,t=new Uint32Array(this.wasmMemory.buffer,e,32),s=new Float32Array(this.wasmMemory.buffer,e,32);t[0]=this.worldOptions.numBuffers||1024,t[1]=this.worldOptions.maxNodes||1024,t[2]=this.worldOptions.maxGraphDefs||1024,t[3]=this.worldOptions.maxWireBufs||64,t[4]=this.worldOptions.numAudioBusChannels||128,t[5]=this.worldOptions.numInputBusChannels||0,t[6]=this.worldOptions.numOutputBusChannels||0,t[7]=this.worldOptions.numControlBusChannels||4096,t[8]=this.worldOptions.bufLength||128,t[9]=this.worldOptions.realTimeMemorySize||16384,t[10]=this.worldOptions.numRGens||64,t[11]=this.worldOptions.realTime?1:0,t[12]=this.worldOptions.memoryLocking?1:0,t[13]=this.worldOptions.loadGraphDefs||0,t[14]=this.worldOptions.preferredSampleRate||0,t[15]=this.worldOptions.verbosity||0}js_debug(e){if(!(!this.uint8View||!this.atomicView||!this.CONTROL_INDICES||!this.ringBufferBase))try{let t=this.bufferConstants.DEBUG_BUFFER_START,s=this.bufferConstants.DEBUG_BUFFER_SIZE,i=this.bufferConstants.DEBUG_PADDING_MARKER,a="[JS] "+e+`
2
+ `,h=new TextEncoder().encode(a);if(h.length>s)return;let r=this.CONTROL_INDICES.DEBUG_HEAD,u=this.atomicLoad(r),_=s-u,c=u;h.length>_&&(this.uint8View[this.ringBufferBase+t+u]=i,c=0);let o=this.ringBufferBase+t;for(let E=0;E<h.length;E++)this.uint8View[o+c+E]=h[E];let f=c+h.length;this.atomicStore(r,f)}catch{}}atomicLoad(e){return this.mode==="sab"?Atomics.load(this.atomicView,e):this.atomicView[e]}atomicStore(e,t){this.mode==="sab"?Atomics.store(this.atomicView,e,t):this.atomicView[e]=t}drainOscQueue(){if(this.oscQueue.length===0)return;let e=this.bufferConstants.IN_BUFFER_SIZE,t=this.bufferConstants.MESSAGE_HEADER_SIZE,s=this.ringBufferBase+this.bufferConstants.IN_BUFFER_START;for(;this.oscQueue.length>0;){let i=this.oscQueue[0],a=i.byteLength,h=t+a+3&-4,r=this.atomicLoad(this.CONTROL_INDICES.IN_HEAD),u=this.atomicLoad(this.CONTROL_INDICES.IN_TAIL),_=C(r,u,e);if(h>_)break;this.oscQueue.shift();let c=this.atomicLoad(this.CONTROL_INDICES.IN_SEQUENCE);this.atomicStore(this.CONTROL_INDICES.IN_SEQUENCE,c+1);let o=new Uint8Array(i),f=O({uint8View:this.uint8View,dataView:this.dataView,bufferStart:s,bufferSize:e,head:r,payload:o,sequence:c,messageMagic:this.bufferConstants.MESSAGE_MAGIC,headerSize:t});this.atomicStore(this.CONTROL_INDICES.IN_HEAD,f)}}readOscReplies(){let e=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);if(e===t)return;let s=[],{newTail:i,messagesRead:a}=I({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.OUT_BUFFER_START,bufferSize:this.bufferConstants.OUT_BUFFER_SIZE,head:e,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,onMessage:(n,h)=>{s.push({oscData:n.buffer,sequence:h})}});a>0&&this.atomicStore(this.CONTROL_INDICES.OUT_TAIL,i),s.length>0&&this.port.postMessage({type:"oscReplies",messages:s})}readNodeTree(){if(!this.bufferConstants||!this.wasmMemory||this.ringBufferBase===null)return null;let e=this.bufferConstants,t=this.ringBufferBase+e.NODE_TREE_START,s=new Uint32Array(this.wasmMemory.buffer,t,2),i=s[0],a=s[1],n=t+e.NODE_TREE_HEADER_SIZE,h=e.NODE_TREE_MIRROR_MAX_NODES,r=e.NODE_TREE_ENTRY_SIZE,u=e.NODE_TREE_DEF_NAME_SIZE,_=new DataView(this.wasmMemory.buffer,n,h*r),c=[],o=0;for(let f=0;f<h&&o<i;f++){let E=f*r,S=_.getInt32(E,!0);if(S===-1)continue;o++;let p=n+E+24,m=new Uint8Array(this.wasmMemory.buffer,p,u),T="";for(let d=0;d<u&&m[d]!==0;d++)T+=String.fromCharCode(m[d]);c.push({id:S,parentId:_.getInt32(E+4,!0),isGroup:_.getInt32(E+8,!0)===1,prevId:_.getInt32(E+12,!0),nextId:_.getInt32(E+16,!0),headId:_.getInt32(E+20,!0),defName:T})}return{nodeCount:i,version:a,nodes:c}}readMetrics(){return this.metricsView?new Uint32Array(this.metricsView):null}checkAndSendSnapshot(e){let t=this.bufferConstants;if(!t||!this.wasmMemory||this.ringBufferBase===null)return;let s=this.ringBufferBase+t.NODE_TREE_START,a=new Uint32Array(this.wasmMemory.buffer,s,2)[1];if(a!==this.lastTreeVersion)this.lastTreeVersion=a,this.lastTreeSendTime=e;else{if(this.lastTreeSendTime>=0&&e-this.lastTreeSendTime<this.treeSnapshotMinInterval)return;this.lastTreeSendTime=e}let h=this.readMetricsAndTreeBuffer();h&&(this.treeSnapshotsSent++,this.port.postMessage({type:"snapshot",buffer:h,snapshotsSent:this.treeSnapshotsSent},[h]))}readMetricsAndTreeBuffer(){if(!this.bufferConstants||!this.wasmMemory||this.ringBufferBase===null)return null;let e=this.bufferConstants,t=this.ringBufferBase+e.METRICS_START,s=e.METRICS_SIZE+e.NODE_TREE_SIZE,i=new Uint8Array(this.wasmMemory.buffer,t,s),a=new ArrayBuffer(s);return new Uint8Array(a).set(i),a}readDebugMessages(){let e=this.atomicLoad(this.CONTROL_INDICES.DEBUG_HEAD),t=this.atomicLoad(this.CONTROL_INDICES.DEBUG_TAIL);if(e===t)return;let s=[],{newTail:i,messagesRead:a}=I({uint8View:this.uint8View,dataView:this.dataView,bufferStart:this.ringBufferBase+this.bufferConstants.DEBUG_BUFFER_START,bufferSize:this.bufferConstants.DEBUG_BUFFER_SIZE,head:e,tail:t,messageMagic:this.bufferConstants.MESSAGE_MAGIC,paddingMagic:this.bufferConstants.PADDING_MAGIC,headerSize:this.bufferConstants.MESSAGE_HEADER_SIZE,onMessage:(n,h)=>{s.push({bytes:n.buffer,sequence:h})}});a>0&&this.atomicStore(this.CONTROL_INDICES.DEBUG_TAIL,i),s.length>0&&this.port.postMessage({type:"debugRawBatch",messages:s},s.map(n=>n.bytes))}async handleMessage(e){let{data:t}=e;try{if(t.type==="osc"){this.mode==="postMessage"&&t.oscData&&this.oscQueue.push(t.oscData);return}if(t.type==="init"&&(this.mode=t.mode||"sab",t.snapshotIntervalMs&&(this.treeSnapshotMinInterval=t.snapshotIntervalMs/1e3),this.mode==="sab"&&t.sharedBuffer&&(this.sharedBuffer=t.sharedBuffer,this.atomicView=new Int32Array(this.sharedBuffer),this.uint8View=new Uint8Array(this.sharedBuffer),this.dataView=new DataView(this.sharedBuffer))),t.type==="loadWasm"){if(t.wasmBytes){let s;if(this.mode==="sab"){if(s=t.wasmMemory,!s){this.port.postMessage({type:"error",error:"No WASM memory provided!"});return}}else{let n=t.memoryPages||1280;s=new WebAssembly.Memory({initial:n,maximum:n,shared:!0})}this.wasmMemory=s,this.worldOptions=t.worldOptions||{},this.sampleRate=t.sampleRate||48e3;let i={env:{memory:s,emscripten_asm_const_double:()=>Date.now()*1e3,__syscall_getdents64:()=>0,__syscall_unlinkat:()=>0,_emscripten_init_main_thread_js:()=>{},_emscripten_thread_mailbox_await:()=>{},_emscripten_thread_set_strongref:()=>{},emscripten_exit_with_live_runtime:()=>{},_emscripten_receive_on_main_thread_js:()=>{},emscripten_check_blocking_allowed:()=>{},_emscripten_thread_cleanup:()=>{},emscripten_num_logical_cores:()=>1,_emscripten_notify_mailbox_postmessage:()=>{}},wasi_snapshot_preview1:{clock_time_get:(n,h,r)=>{let u=new DataView(s.buffer),_=BigInt(Math.floor(Date.now()*1e6));return u.setBigUint64(r,_,!0),0},environ_sizes_get:()=>0,environ_get:()=>0,fd_close:()=>0,fd_write:()=>0,fd_seek:()=>0,fd_read:()=>0,proc_exit:n=>{console.error("[AudioWorklet] WASM tried to exit with code:",n)}}},a=await WebAssembly.compile(t.wasmBytes);if(this.wasmInstance=await WebAssembly.instantiate(a,i),this.wasmInstance.exports.get_ring_buffer_base&&(this.ringBufferBase=this.wasmInstance.exports.get_ring_buffer_base(),this.loadBufferConstants(),this.calculateBufferIndices(this.ringBufferBase),this.writeWorldOptionsToMemory(),this.wasmInstance.exports.init_memory)){this.wasmInstance.exports.init_memory(this.sampleRate),this.isInitialized=!0;let n=this.mode==="postMessage"?this.readMetricsAndTreeBuffer():void 0,h={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:n};this.port.postMessage(h,n?[n]:[])}}else if(t.wasmInstance&&(this.wasmInstance=t.wasmInstance,this.wasmInstance.exports.get_ring_buffer_base&&(this.ringBufferBase=this.wasmInstance.exports.get_ring_buffer_base(),this.loadBufferConstants(),this.calculateBufferIndices(this.ringBufferBase),this.writeWorldOptionsToMemory(),this.wasmInstance.exports.init_memory))){this.wasmInstance.exports.init_memory(this.sampleRate),this.isInitialized=!0;let s=this.mode==="postMessage"?this.readMetricsAndTreeBuffer():void 0,i={type:"initialized",success:!0,ringBufferBase:this.ringBufferBase,bufferConstants:this.bufferConstants,exports:Object.keys(this.wasmInstance.exports),initialSnapshot:s};this.port.postMessage(i,s?[s]:[])}}if(t.type==="getVersion")if(this.wasmInstance&&this.wasmInstance.exports.get_supersonic_version_string){let s=this.wasmInstance.exports.get_supersonic_version_string(),i=new Uint8Array(this.wasmMemory.buffer),a="";for(let n=s;i[n]!==0;n++)a+=String.fromCharCode(i[n]);this.port.postMessage({type:"version",version:a})}else this.port.postMessage({type:"version",version:"unknown"});if(t.type==="getTimeOffset")if(this.wasmInstance&&this.wasmInstance.exports.get_time_offset){let s=this.wasmInstance.exports.get_time_offset();this.port.postMessage({type:"timeOffset",offset:s})}else console.error("[AudioWorklet] get_time_offset not available! wasmInstance:",!!this.wasmInstance),this.port.postMessage({type:"error",error:"get_time_offset function not available in WASM exports"});if(t.type==="setNTPStartTime"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.NTP_START_TIME_START,i=new Float64Array(this.wasmMemory.buffer,s,1);i[0]=t.ntpStartTime}if(t.type==="setDriftOffset"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.DRIFT_OFFSET_START,i=new Int32Array(this.wasmMemory.buffer,s,1);i[0]=t.driftOffsetMs}if(t.type==="setGlobalOffset"&&this.wasmMemory&&this.ringBufferBase!==null&&this.bufferConstants){let s=this.ringBufferBase+this.bufferConstants.GLOBAL_OFFSET_START,i=new Int32Array(this.wasmMemory.buffer,s,1);i[0]=t.globalOffsetMs}if(t.type==="getMetrics"){let s=this.metricsView?new Uint32Array(this.metricsView):null;this.port.postMessage({type:"metricsSnapshot",requestId:t.requestId,metrics:s})}if(t.type==="copyBufferData")try{let{copyId:s,ptr:i,data:a}=t;if(!this.wasmMemory||!this.wasmMemory.buffer)throw new Error("WASM memory not initialized");let n=new Float32Array(a);new Float32Array(this.wasmMemory.buffer,i,n.length).set(n),this.port.postMessage({type:"bufferCopied",copyId:s,success:!0})}catch(s){console.error("[AudioWorklet] Buffer copy failed:",s),this.port.postMessage({type:"bufferCopied",copyId:t.copyId,success:!1,error:s.message})}}catch(s){console.error("[AudioWorklet] Error handling message:",s),this.port.postMessage({type:"error",error:s.message,stack:s.stack})}}process(e,t,s){if(this.processCallCount++,!this.isInitialized)return!0;try{if(this.wasmInstance&&this.wasmInstance.exports.process_audio){this.mode==="postMessage"&&this.drainOscQueue();let i=currentTime,a=e[0]?.length||0,n=t[0]?.length||0;if(a>0&&this.wasmInstance?.exports?.get_audio_input_bus)try{let r=this.wasmInstance.exports.get_audio_input_bus(),u=this.wasmInstance.exports.get_audio_buffer_samples();if(r&&r>0){let _=this.sharedBuffer||this.wasmMemory?.buffer;if(_){let c=this.worldOptions?.numInputBusChannels||2,o=Math.min(a,c);(!this.inputView||this.lastInputBusPtr!==r||this.lastInputChannels!==c)&&(this.inputView=new Float32Array(_,r,u*c),this.lastInputBusPtr=r,this.lastInputChannels=c);for(let f=0;f<o;f++)e[0]?.[f]&&this.inputView.set(e[0][f],f*u)}}}catch{}let h=this.wasmInstance.exports.process_audio(i,n,a);if(this.wasmInstance.exports.get_audio_output_bus&&t[0]&&t[0].length>=2)try{let r=this.wasmInstance.exports.get_audio_output_bus(),u=this.wasmInstance.exports.get_audio_buffer_samples();if(r&&r>0){let _=this.wasmInstance.exports.memory||this.wasmMemory;if(!_||!_.buffer)return!0;let c=_.buffer,o=c.byteLength,f=r+u*2*4;if(r<0||r>o||f>o)return!0;(!this.audioView||this.lastAudioBufferPtr!==r||this.lastWasmBufferSize!==o||c!==this.audioView.buffer)&&(this.audioView=new Float32Array(c,r,u*2),this.lastAudioBufferPtr=r,this.lastWasmBufferSize=o),t[0][0].set(this.audioView.subarray(0,u)),t[0][1].set(this.audioView.subarray(u,u*2))}}catch{}if(this.mode==="postMessage")this.readOscReplies(),this.readDebugMessages(),this.checkAndSendSnapshot(i);else if(this.atomicView){let r=this.atomicLoad(this.CONTROL_INDICES.OUT_HEAD),u=this.atomicLoad(this.CONTROL_INDICES.OUT_TAIL);r!==u&&Atomics.notify(this.atomicView,this.CONTROL_INDICES.OUT_HEAD,1)}return this.processCallCount%3750===0&&this.checkStatus(),h!==0}}catch(i){console.error("[AudioWorklet] process() error:",i),console.error("[AudioWorklet] Stack:",i.stack),this.atomicView&&this.mode==="sab"&&Atomics.or(this.atomicView,this.CONTROL_INDICES.STATUS_FLAGS,this.STATUS_FLAGS.WASM_ERROR)}return!0}checkStatus(){if(!this.atomicView)return;let e=this.atomicLoad(this.CONTROL_INDICES.STATUS_FLAGS);if(e!==this.STATUS_FLAGS.OK){let t={bufferFull:!!(e&this.STATUS_FLAGS.BUFFER_FULL),overrun:!!(e&this.STATUS_FLAGS.OVERRUN),wasmError:!!(e&this.STATUS_FLAGS.WASM_ERROR),fragmented:!!(e&this.STATUS_FLAGS.FRAGMENTED_MSG)},s={processCount:this.metricsView[0],messagesProcessed:this.metricsView[1],messagesDropped:this.metricsView[2],schedulerQueueDepth:this.metricsView[3],schedulerQueueMax:this.metricsView[4],schedulerQueueDropped:this.metricsView[5]};this.port.postMessage({type:"status",flags:e,status:t,metrics:s});let i=e&this.STATUS_FLAGS.BUFFER_FULL;this.atomicStore(this.CONTROL_INDICES.STATUS_FLAGS,i)}}};registerProcessor("scsynth-processor",A);})();