supersonic-scsynth 0.20.0 → 0.20.1
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/dist/supersonic.js +1 -1
- package/dist/wasm/scsynth-nrt.wasm +0 -0
- package/package.json +1 -1
package/dist/supersonic.js
CHANGED
|
@@ -18,5 +18,5 @@ SharedArrayBuffer is available but cross-origin isolation is not enabled. Please
|
|
|
18
18
|
SharedArrayBuffer is not available. This may be due to:
|
|
19
19
|
1. Missing COOP/COEP headers
|
|
20
20
|
2. Browser doesn't support SharedArrayBuffer
|
|
21
|
-
3. Browser security settings`),r}return this.#_}#se(){let e=this.#i.memory;this.#a=new WebAssembly.Memory({initial:e.totalPages,maximum:e.totalPages,shared:!0}),this.#s=this.#a.buffer}#$(){return this.#i.audioContext?this.#t=this.#i.audioContext:this.#t=new AudioContext(this.#i.audioContextOptions),this.#t.addEventListener("statechange",()=>{let e=this.#t?.state;if(!e)return;let t=this.#z;this.#z=e,e==="running"&&(t==="suspended"||t==="interrupted")&&this.#K(),this.#u("audiocontext:statechange",{state:e}),e==="suspended"?this.#u("audiocontext:suspended"):e==="running"?this.#u("audiocontext:resumed"):e==="interrupted"&&this.#u("audiocontext:interrupted")}),this.#t}#ie(){this.#c=new M({audioContext:this.#t,sharedBuffer:this.#s,bufferPoolConfig:{start:this.#i.memory.bufferPoolOffset,size:this.#i.memory.bufferPoolSize},sampleBaseURL:this.#m,maxBuffers:this.#i.worldOptions.numBuffers,assetLoader:this.#T})}#V(){this.#E=new x({bufferManager:this.#c,getDefaultSampleRate:()=>this.#t?.sampleRate||44100})}async#W(){if(this.#M)return this.#M;let e=this.#i.wasmUrl.split("/").pop();this.#u("loading:start",{type:"wasm",name:e});let t;try{t=await fetch(this.#i.wasmUrl)}catch(s){throw new Error(`Failed to fetch WASM from ${this.#i.wasmUrl}: ${s.message}`)}if(!t.ok)throw new Error(`Failed to load WASM: ${t.status} ${t.statusText}`);let r=await t.arrayBuffer();return this.#u("loading:complete",{type:"wasm",name:e,size:r.byteLength}),this.#M=r,r}async#H(e){await this.#t.audioWorklet.addModule(this.#i.workletUrl),this.#n=new AudioWorkletNode(this.#t,"scsynth-processor",{numberOfInputs:0,numberOfOutputs:1,outputChannelCount:[2]}),this.#i.autoConnect&&this.#n.connect(this.#t.destination),this.#d=this.#ne(),this.#n.port.postMessage({type:"init",sharedBuffer:this.#s}),this.#n.port.postMessage({type:"loadWasm",wasmBytes:e,wasmMemory:this.#a,worldOptions:this.#i.worldOptions,sampleRate:this.#t.sampleRate}),await this.#oe()}#ne(){let e=this.#n;return Object.freeze({connect:(t,r,s)=>e.connect(t,r,s),disconnect:(t,r,s)=>e.disconnect(t,r,s),get context(){return e.context},get numberOfOutputs(){return e.numberOfOutputs},get channelCount(){return e.channelCount}})}async#G(){this.#o=new C(this.#i.workerBaseURL),this.#o.onRawOSC(e=>{this.#u("message:raw",e)}),this.#o.onParsedOSC(e=>{if(e.address==="/supersonic/buffer/freed")this.#c?.handleBufferFreed(e.args);else if(e.address==="/supersonic/buffer/allocated")this.#c?.handleBufferAllocated(e.args);else if(e.address==="/supersonic/synthdef/loaded"){let t=e.args[0]}else if(e.address==="/synced"&&e.args.length>0){let t=e.args[0];this.#h&&this.#h.has(t)&&this.#h.get(t)(e)}if(this.#u("message",e),this.#i.debug||this.#i.debugOscIn){let t=this.#i.activityConsoleLog.oscIn??this.#i.activityConsoleLog.maxLineLength,r=e.args?.map(s=>{let n=JSON.stringify(s);return n.length>t?n.slice(0,t)+"...":n}).join(", ")||"";console.log(`[
|
|
21
|
+
3. Browser security settings`),r}return this.#_}#se(){let e=this.#i.memory;this.#a=new WebAssembly.Memory({initial:e.totalPages,maximum:e.totalPages,shared:!0}),this.#s=this.#a.buffer}#$(){return this.#i.audioContext?this.#t=this.#i.audioContext:this.#t=new AudioContext(this.#i.audioContextOptions),this.#t.addEventListener("statechange",()=>{let e=this.#t?.state;if(!e)return;let t=this.#z;this.#z=e,e==="running"&&(t==="suspended"||t==="interrupted")&&this.#K(),this.#u("audiocontext:statechange",{state:e}),e==="suspended"?this.#u("audiocontext:suspended"):e==="running"?this.#u("audiocontext:resumed"):e==="interrupted"&&this.#u("audiocontext:interrupted")}),this.#t}#ie(){this.#c=new M({audioContext:this.#t,sharedBuffer:this.#s,bufferPoolConfig:{start:this.#i.memory.bufferPoolOffset,size:this.#i.memory.bufferPoolSize},sampleBaseURL:this.#m,maxBuffers:this.#i.worldOptions.numBuffers,assetLoader:this.#T})}#V(){this.#E=new x({bufferManager:this.#c,getDefaultSampleRate:()=>this.#t?.sampleRate||44100})}async#W(){if(this.#M)return this.#M;let e=this.#i.wasmUrl.split("/").pop();this.#u("loading:start",{type:"wasm",name:e});let t;try{t=await fetch(this.#i.wasmUrl)}catch(s){throw new Error(`Failed to fetch WASM from ${this.#i.wasmUrl}: ${s.message}`)}if(!t.ok)throw new Error(`Failed to load WASM: ${t.status} ${t.statusText}`);let r=await t.arrayBuffer();return this.#u("loading:complete",{type:"wasm",name:e,size:r.byteLength}),this.#M=r,r}async#H(e){await this.#t.audioWorklet.addModule(this.#i.workletUrl),this.#n=new AudioWorkletNode(this.#t,"scsynth-processor",{numberOfInputs:0,numberOfOutputs:1,outputChannelCount:[2]}),this.#i.autoConnect&&this.#n.connect(this.#t.destination),this.#d=this.#ne(),this.#n.port.postMessage({type:"init",sharedBuffer:this.#s}),this.#n.port.postMessage({type:"loadWasm",wasmBytes:e,wasmMemory:this.#a,worldOptions:this.#i.worldOptions,sampleRate:this.#t.sampleRate}),await this.#oe()}#ne(){let e=this.#n;return Object.freeze({connect:(t,r,s)=>e.connect(t,r,s),disconnect:(t,r,s)=>e.disconnect(t,r,s),get context(){return e.context},get numberOfOutputs(){return e.numberOfOutputs},get channelCount(){return e.channelCount}})}async#G(){this.#o=new C(this.#i.workerBaseURL),this.#o.onRawOSC(e=>{this.#u("message:raw",e)}),this.#o.onParsedOSC(e=>{if(e.address==="/supersonic/buffer/freed")this.#c?.handleBufferFreed(e.args);else if(e.address==="/supersonic/buffer/allocated")this.#c?.handleBufferAllocated(e.args);else if(e.address==="/supersonic/synthdef/loaded"){let t=e.args[0]}else if(e.address==="/synced"&&e.args.length>0){let t=e.args[0];this.#h&&this.#h.has(t)&&this.#h.get(t)(e)}if(this.#u("message",e),this.#i.debug||this.#i.debugOscIn){let t=this.#i.activityConsoleLog.oscIn??this.#i.activityConsoleLog.maxLineLength,r=e.args?.map(s=>{let n=JSON.stringify(s);return n.length>t?n.slice(0,t)+"...":n}).join(", ")||"";console.log(`[\u2190 OSC] ${e.address}${r?" "+r:""}`)}}),this.#o.onDebugMessage(e=>{let t=this.#i.activityEvent.scsynth??this.#i.activityEvent.maxLineLength;if(t>0&&e.text&&e.text.length>t&&(e={...e,text:e.text.slice(0,t)+"..."}),this.#u("debug",e),this.#i.debug||this.#i.debugScsynth){let r=this.#i.activityConsoleLog.scsynth??this.#i.activityConsoleLog.maxLineLength,s=e.text.length>r?e.text.slice(0,r)+"...":e.text;console.log(`[synth] ${s}`)}}),this.#o.onError((e,t)=>{console.error(`[SuperSonic] ${t} error:`,e),this.#u("error",new Error(`${t}: ${e}`))}),await this.#o.init(this.#s,this.#r,this.#e,{preschedulerCapacity:this.#i.preschedulerCapacity})}#Z(){this.#l=!0,this.#S=!1,this.bootStats.initDuration=performance.now()-this.bootStats.initStartTime,this.#u("ready",{capabilities:this.#_,bootStats:this.bootStats})}#oe(){return new Promise((e,t)=>{let r=setTimeout(()=>{t(new Error("AudioWorklet initialization timeout"))},5e3),s=async n=>{if(n.data.type!=="debug"){if(n.data.type==="error"){console.error("[AudioWorklet] Error:",n.data.error),clearTimeout(r),this.#n.port.removeEventListener("message",s),t(new Error(n.data.error||"AudioWorklet error"));return}n.data.type==="initialized"&&(clearTimeout(r),this.#n.port.removeEventListener("message",s),n.data.success?(n.data.ringBufferBase!==void 0?this.#r=n.data.ringBufferBase:console.warn("[SuperSonic] Warning: ringBufferBase not provided by worklet"),n.data.bufferConstants!==void 0?(this.#e=n.data.bufferConstants,this.#le(),this.#ue(),await this.#fe(),this.#pe()):console.warn("[SuperSonic] Warning: bufferConstants not provided by worklet"),e()):t(new Error(n.data.error||"AudioWorklet initialization failed")))}};this.#n.port.addEventListener("message",s),this.#n.port.start()})}#q(){this.#n.port.onmessage=e=>{let{data:t}=e;switch(t.type){case"error":console.error("[Worklet] Error:",t.error),t.diagnostics&&(console.error("[Worklet] Diagnostics:",t.diagnostics),console.table(t.diagnostics)),this.#u("error",new Error(t.error));break;case"process_debug":break;case"debug":break;case"version":this.#B=t.version;break}}}#ae(){if(!this.#A)return null;let e=this.#A;return{workletProcessCount:e[0],workletMessagesProcessed:e[1],workletMessagesDropped:e[2],workletSchedulerDepth:e[3],workletSchedulerMax:e[4],workletSchedulerDropped:e[5],workletSequenceGaps:e[24],preschedulerPending:e[6],preschedulerPeak:e[7],preschedulerSent:e[8],preschedulerRetriesSucceeded:e[9],preschedulerRetriesFailed:e[10],preschedulerBundlesScheduled:e[11],preschedulerEventsCancelled:e[12],preschedulerTotalDispatches:e[13],preschedulerMessagesRetried:e[14],preschedulerRetryQueueSize:e[15],preschedulerRetryQueueMax:e[16],preschedulerBypassed:e[25],oscInMessagesReceived:e[17],oscInMessagesDropped:e[18],oscInBytesReceived:e[19],debugMessagesReceived:e[20],debugBytesReceived:e[21],mainMessagesSent:e[22],mainBytesSent:e[23]}}#ce(){if(!this.#I||!this.#e||!this.#r)return null;let e=this.#r+this.#e.CONTROL_START,t=this.#I,r=Atomics.load(t,(e+0)/4),s=Atomics.load(t,(e+4)/4),n=Atomics.load(t,(e+8)/4),a=Atomics.load(t,(e+12)/4),c=Atomics.load(t,(e+16)/4),l=Atomics.load(t,(e+20)/4),u=(r-s+this.#e.IN_BUFFER_SIZE)%this.#e.IN_BUFFER_SIZE,h=(n-a+this.#e.OUT_BUFFER_SIZE)%this.#e.OUT_BUFFER_SIZE,f=(c-l+this.#e.DEBUG_BUFFER_SIZE)%this.#e.DEBUG_BUFFER_SIZE;return{inBufferUsed:{bytes:u,percentage:u/this.#e.IN_BUFFER_SIZE*100},outBufferUsed:{bytes:h,percentage:h/this.#e.OUT_BUFFER_SIZE*100},debugBufferUsed:{bytes:f,percentage:f/this.#e.DEBUG_BUFFER_SIZE*100}}}#k(e,t=1){if(!this.#A)return;let r={mainMessagesSent:22,mainBytesSent:23,preschedulerBypassed:25};Atomics.add(this.#A,r[e],t)}#Y(){let e=performance.now(),t=this.#ae()||{},r=this.#ce();if(r&&Object.assign(t,r),t.driftOffsetMs=this.#de(),t.audioContextState=this.#t?.state||"unknown",this.#c){let n=this.#c.getStats();t.bufferPoolUsedBytes=n.used.size,t.bufferPoolAvailableBytes=n.available,t.bufferPoolAllocations=n.used.count}t.loadedSynthDefs=this.loadedSynthDefs?.size||0;let s=performance.now()-e;return s>1&&console.warn(`[SuperSonic] Slow metrics gathering: ${s.toFixed(2)}ms`),t}#F(){this.#P();let e=this.#N;this.#U=setInterval(()=>{if(!(!this.#b.has("metrics")||this.#b.get("metrics").size===0)){if(this.#x){console.warn(`[SuperSonic] Metrics gathering took >${e}ms, skipping this interval`);return}this.#x=!0;try{let t=this.#Y();this.#u("metrics",t)}catch(t){console.error("[SuperSonic] Metrics gathering failed:",t)}finally{this.#x=!1}}},e)}#P(){this.#U&&(clearInterval(this.#U),this.#U=null)}#C(e="perform this operation"){if(!this.#l)throw new Error(`SuperSonic not initialized. Call init() before attempting to ${e}.`)}#le(){if(!this.#s||!this.#r||!this.#e){console.warn("[SuperSonic] Cannot initialize shared views - missing buffer info");return}this.#I=new Int32Array(this.#s);let e=this.#r+this.#e.METRICS_START;this.#A=new Uint32Array(this.#s,e,this.#e.METRICS_SIZE/4),this.#R=new Float64Array(this.#s,this.#r+this.#e.NTP_START_TIME_START,1),this.#O=new Int32Array(this.#s,this.#r+this.#e.DRIFT_OFFSET_START,1),this.#v=new Int32Array(this.#s,this.#r+this.#e.GLOBAL_OFFSET_START,1)}#ue(){this.#D=new k({sharedBuffer:this.#s,ringBufferBase:this.#r,bufferConstants:this.#e,getAudioContextTime:()=>this.#t?.currentTime??null,getNTPStartTime:()=>this.#R?.[0]??0})}#he(e){return e.includes("/")||e.includes("://")}#Ee(){return this.#c?.getStats()}async#fe(){if(!this.#e||!this.#t)return;let e;for(;e=this.#t.getOutputTimestamp(),!(e.contextTime>0);)await new Promise(n=>setTimeout(n,50));let t=performance.timeOrigin+e.performanceTime,r=F(t),s=Z(r,e.contextTime);this.#R[0]=s,this.#f=s}#Q(){if(!this.#e||!this.#t||this.#f===void 0)return;let e=this.#t.getOutputTimestamp(),t=performance.timeOrigin+e.performanceTime,s=F(t)-this.#f,n=ne(s,e.contextTime);Atomics.store(this.#O,0,n)}#de(){return this.#O?Atomics.load(this.#O,0):0}#K(){if(!this.#t||!this.#R||!this.#O)return;let e=this.#t.getOutputTimestamp();if(!e||e.contextTime<=0)return;let t=performance.timeOrigin+e.performanceTime,r=F(t),s=Z(r,e.contextTime);this.#R[0]=s,this.#f=s,this.#Q()}#pe(){this.#L(),this.#g=setInterval(()=>{this.#Q()},15e3)}#L(){this.#g&&(clearInterval(this.#g),this.#g=null)}#me(e){if(e instanceof Uint8Array)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);throw new Error("oscData must be ArrayBuffer or Uint8Array")}async#Se(e){let t={metadata:!0,unpackSingleArgs:!1};try{let r=i.osc.decode(e,t),{packet:s,changed:n}=await this.#E.rewritePacket(r);return n?i.osc.encode(s):e}catch(r){throw console.error("[SuperSonic] Failed to prepare OSC packet:",r),r}}#we(e){if(e.length<16||String.fromCharCode.apply(null,e.slice(0,8))!=="#bundle\0")return null;let r=this.#R[0];if(r===0)return console.warn("[SuperSonic] NTP start time not yet initialized"),null;let n=Atomics.load(this.#O,0)/1e3,c=Atomics.load(this.#v,0)/1e3,l=r+n+c,u=new DataView(e.buffer,e.byteOffset),h=u.getUint32(8,!1),f=u.getUint32(12,!1);if(h===0&&(f===0||f===1))return null;let m=h+f/4294967296-l,S=this.#t.currentTime;return{audioTimeS:m,currentTimeS:S}}};export{Se as SuperSonic};
|
|
22
22
|
/*! osc.js 2.4.5, Copyright 2024 Colin Clark | github.com/colinbdclark/osc.js */
|
|
Binary file
|
package/package.json
CHANGED