supersonic-scsynth-core 0.24.3
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/LICENSE +17 -0
- package/README.md +54 -0
- package/index.js +9 -0
- package/package.json +35 -0
- package/wasm/scsynth-nrt.wasm +0 -0
- package/workers/debug_worker.js +3 -0
- package/workers/osc_in_worker.js +1 -0
- package/workers/osc_out_prescheduler_worker.js +1 -0
- package/workers/scsynth_audio_worklet.js +2 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
SuperSonic Core - WebAssembly Audio Synthesis Engine
|
|
2
|
+
Copyright (c) 2025 Sam Aaron
|
|
3
|
+
|
|
4
|
+
Based on SuperCollider's scsynth
|
|
5
|
+
Copyright (c) 2002-2023 James McCartney and SuperCollider contributors
|
|
6
|
+
|
|
7
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
8
|
+
the terms of the GNU General Public License as published by the Free Software
|
|
9
|
+
Foundation, either version 3 of the License, or (at your option) any later
|
|
10
|
+
version.
|
|
11
|
+
|
|
12
|
+
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
13
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
14
|
+
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU General Public License along with
|
|
17
|
+
this program. If not, see <https://www.gnu.org/licenses/>.
|
package/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# supersonic-scsynth-core
|
|
2
|
+
|
|
3
|
+
The SuperCollider scsynth WebAssembly engine and AudioWorklet processor for [SuperSonic](https://github.com/samaaron/supersonic).
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package contains the GPL-licensed runtime components:
|
|
8
|
+
|
|
9
|
+
- `wasm/scsynth-nrt.wasm` - The scsynth engine compiled to WebAssembly
|
|
10
|
+
- `workers/*.js` - AudioWorklet processor and supporting workers
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
This package is typically loaded automatically by `supersonic-scsynth` from CDN:
|
|
15
|
+
|
|
16
|
+
```javascript
|
|
17
|
+
import { SuperSonic } from 'supersonic-scsynth';
|
|
18
|
+
|
|
19
|
+
const supersonic = new SuperSonic();
|
|
20
|
+
// Loads core from: https://unpkg.com/supersonic-scsynth-core@latest/
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Self-Hosting
|
|
24
|
+
|
|
25
|
+
To host the core yourself:
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
import { SuperSonic } from 'supersonic-scsynth';
|
|
29
|
+
|
|
30
|
+
const supersonic = new SuperSonic({
|
|
31
|
+
coreBaseURL: '/path/to/supersonic-scsynth-core/'
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install supersonic-scsynth-core
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Then serve the `wasm/` and `workers/` directories from your static file server.
|
|
42
|
+
|
|
43
|
+
## License
|
|
44
|
+
|
|
45
|
+
GPL-3.0-or-later
|
|
46
|
+
|
|
47
|
+
This package is derived from [SuperCollider](https://supercollider.github.io/) by James McCartney and the SuperCollider community.
|
|
48
|
+
|
|
49
|
+
## Related Packages
|
|
50
|
+
|
|
51
|
+
- [`supersonic-scsynth`](https://www.npmjs.com/package/supersonic-scsynth) - MIT-licensed client API
|
|
52
|
+
- [`supersonic-scsynth-synthdefs`](https://www.npmjs.com/package/supersonic-scsynth-synthdefs) - Synth definitions (MIT)
|
|
53
|
+
- [`supersonic-scsynth-samples`](https://www.npmjs.com/package/supersonic-scsynth-samples) - Audio samples (CC0)
|
|
54
|
+
- [`supersonic-scsynth-bundle`](https://www.npmjs.com/package/supersonic-scsynth-bundle) - Everything together
|
package/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
// Copyright (c) 2025 Sam Aaron
|
|
3
|
+
|
|
4
|
+
// CDN path helper for supersonic-scsynth-core
|
|
5
|
+
// This is the base URL for loading WASM and worker files from CDN
|
|
6
|
+
|
|
7
|
+
export const CORE_CDN = 'https://unpkg.com/supersonic-scsynth-core@latest/';
|
|
8
|
+
export const WASM_CDN = 'https://unpkg.com/supersonic-scsynth-core@latest/wasm/';
|
|
9
|
+
export const WORKERS_CDN = 'https://unpkg.com/supersonic-scsynth-core@latest/workers/';
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "supersonic-scsynth-core",
|
|
3
|
+
"version": "0.24.3",
|
|
4
|
+
"description": "SuperCollider scsynth WebAssembly engine and AudioWorklet for SuperSonic",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"unpkg": "index.js",
|
|
8
|
+
"jsdelivr": "index.js",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/samaaron/supersonic.git"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"supercollider",
|
|
15
|
+
"scsynth",
|
|
16
|
+
"audio",
|
|
17
|
+
"synthesis",
|
|
18
|
+
"webassembly",
|
|
19
|
+
"audioworklet",
|
|
20
|
+
"wasm"
|
|
21
|
+
],
|
|
22
|
+
"author": "Sam Aaron",
|
|
23
|
+
"license": "GPL-3.0-or-later",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/samaaron/supersonic/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/samaaron/supersonic#readme",
|
|
28
|
+
"files": [
|
|
29
|
+
"wasm/",
|
|
30
|
+
"workers/",
|
|
31
|
+
"index.js",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
(()=>{function C({uint8View:t,dataView:e,bufferStart:s,bufferSize:o,head:i,tail:D,messageMagic:R,paddingMagic:m,headerSize:c,maxMessages:y=1/0,onMessage:b,onCorruption:f}){let r=D,T=0;for(;r!==i&&T<y;){if(o-r<c){r=0;continue}let g=s+r,d=e.getUint32(g,!0);if(d===m){r=0;continue}if(d!==R){f&&f(r),r=(r+1)%o;continue}let _=e.getUint32(g+4,!0),w=e.getUint32(g+8,!0);if(_<c||_>o){f&&f(r),r=(r+1)%o;continue}let x=_-c,L=g+c,B=new Uint8Array(x);for(let S=0;S<x;S++)B[S]=t[L+S];b(B,w,_),r=(r+_)%o,T++}return{newTail:r,messagesRead:T}}var p="sab",l=null,u=null,n=null,I=null,M=null,E=null,a={},U=null,A=!1,G=new TextDecoder("utf-8"),k=(...t)=>{},H=(t,e,s)=>{l=t,u=e,E=s,n=new Int32Array(l),I=new DataView(l),M=new Uint8Array(l),a={DEBUG_HEAD:(u+E.CONTROL_START+16)/4,DEBUG_TAIL:(u+E.CONTROL_START+20)/4};let o=u+E.METRICS_START;U=new Uint32Array(l,o,E.METRICS_SIZE/4)},h=()=>{let t=Atomics.load(n,a.DEBUG_HEAD),e=Atomics.load(n,a.DEBUG_TAIL);if(t===e)return null;let s=[],{newTail:o,messagesRead:i}=C({uint8View:M,dataView:I,bufferStart:u+E.DEBUG_BUFFER_START,bufferSize:E.DEBUG_BUFFER_SIZE,head:t,tail:e,messageMagic:E.MESSAGE_MAGIC,paddingMagic:E.PADDING_MAGIC,headerSize:E.MESSAGE_HEADER_SIZE,maxMessages:1e3,onMessage:(D,R,m)=>{let c=G.decode(D);c.endsWith(`
|
|
2
|
+
`)&&(c=c.slice(0,-1)),s.push({text:c,timestamp:performance.now(),sequence:R}),U&&(Atomics.add(U,20,1),Atomics.add(U,21,D.length))},onCorruption:D=>{console.error("[DebugWorker] Corrupted message at position",D)}});return i>0&&Atomics.store(n,a.DEBUG_TAIL,o),s.length>0?s:null},W=()=>{for(;A;)try{let t=Atomics.load(n,a.DEBUG_HEAD),e=Atomics.load(n,a.DEBUG_TAIL);if(t===e){let o=Atomics.wait(n,a.DEBUG_HEAD,t,100);if(!(o==="ok"||o==="not-equal")){if(o==="timed-out")continue}}let s=h();s&&s.length>0&&self.postMessage({type:"debug",messages:s})}catch(t){console.error("[DebugWorker] Error in wait loop:",t),self.postMessage({type:"error",error:t.message}),Atomics.wait(n,0,n[0],10)}},F=()=>{if(!l){console.error("[DebugWorker] Cannot start - not initialized");return}if(A){console.warn("[DebugWorker] Already running");return}A=!0,W()},Q=()=>{A=!1},Y=()=>{l&&(Atomics.store(n,a.DEBUG_HEAD,0),Atomics.store(n,a.DEBUG_TAIL,0))},V=t=>{let e=[];for(let s of t)try{let o=new Uint8Array(s.bytes),i=G.decode(o);i.endsWith(`
|
|
3
|
+
`)&&(i=i.slice(0,-1)),e.push({text:i,timestamp:performance.now(),sequence:s.sequence})}catch(o){console.error("[DebugWorker] Failed to decode message:",o)}e.length>0&&self.postMessage({type:"debug",messages:e})};self.addEventListener("message",t=>{let{data:e}=t;try{switch(e.type){case"init":p=e.mode||"sab",p==="sab"&&H(e.sharedBuffer,e.ringBufferBase,e.bufferConstants),self.postMessage({type:"initialized"});break;case"start":p==="sab"&&F();break;case"stop":Q();break;case"clear":p==="sab"&&Y();break;case"debugRaw":e.messages&&V(e.messages);break;default:console.warn("[DebugWorker] Unknown message type:",e.type)}}catch(s){console.error("[DebugWorker] Error:",s),self.postMessage({type:"error",error:s.message})}});k("[DebugWorker] Script loaded");})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{function m({uint8View:e,dataView:t,bufferStart:r,bufferSize:o,head:C,tail:l,messageMagic:i,paddingMagic:u,headerSize:c,maxMessages:f=1/0,onMessage:F,onCorruption:A}){let s=l,I=0;for(;s!==C&&I<f;){if(o-s<c){s=0;continue}let U=r+s,g=t.getUint32(U,!0);if(g===u){s=0;continue}if(g!==i){A&&A(s),s=(s+1)%o;continue}let p=t.getUint32(U+4,!0),L=t.getUint32(U+8,!0);if(p<c||p>o){A&&A(s),s=(s+1)%o;continue}let d=p-c,B=U+c,x=new Uint8Array(d);for(let D=0;D<d;D++)x[D]=e[B+D];F(x,L,p),s=(s+p)%o,I++}return{newTail:s,messagesRead:I}}var _=null,T=null,E=null,P=null,y=null,n=null,S={},a=null,R=!1,H=(...e)=>{},O=-1,k=(e,t,r)=>{_=e,T=t,n=r,E=new Int32Array(_),P=new DataView(_),y=new Uint8Array(_),S={OUT_HEAD:(T+n.CONTROL_START+8)/4,OUT_TAIL:(T+n.CONTROL_START+12)/4};let o=T+n.METRICS_START;a=new Uint32Array(_,o,n.METRICS_SIZE/4)},W=()=>{let e=Atomics.load(E,S.OUT_HEAD),t=Atomics.load(E,S.OUT_TAIL);if(e===t)return[];let r=[],{newTail:o,messagesRead:C}=m({uint8View:y,dataView:P,bufferStart:T+n.OUT_BUFFER_START,bufferSize:n.OUT_BUFFER_SIZE,head:e,tail:t,messageMagic:n.MESSAGE_MAGIC,paddingMagic:n.PADDING_MAGIC,headerSize:n.MESSAGE_HEADER_SIZE,maxMessages:100,onMessage:(l,i,u)=>{if(O>=0){let c=O+1&4294967295;if(i!==c){let f=i-c+4294967296&4294967295;f<1e3&&(console.warn("[OSCInWorker] Detected",f,"dropped messages (expected seq",c,"got",i,")"),a&&Atomics.add(a,18,f))}}O=i,r.push({oscData:l,sequence:i}),a&&(Atomics.add(a,17,1),Atomics.add(a,19,l.length))},onCorruption:l=>{console.error("[OSCInWorker] Corrupted message at position",l),a&&Atomics.add(a,18,1)}});return C>0&&Atomics.store(E,S.OUT_TAIL,o),r},b=()=>{for(;R;)try{let e=Atomics.load(E,S.OUT_HEAD),t=Atomics.load(E,S.OUT_TAIL);if(e===t){let o=Atomics.wait(E,S.OUT_HEAD,e,100);if(!(o==="ok"||o==="not-equal")){if(o==="timed-out")continue}}let r=W();r.length>0&&self.postMessage({type:"messages",messages:r})}catch(e){console.error("[OSCInWorker] Error in wait loop:",e),self.postMessage({type:"error",error:e.message}),Atomics.wait(E,0,E[0],10)}},h=()=>{if(!_){console.error("[OSCInWorker] Cannot start - not initialized");return}if(R){console.warn("[OSCInWorker] Already running");return}R=!0,b()},Q=()=>{R=!1};self.addEventListener("message",e=>{let{data:t}=e;try{switch(t.type){case"init":k(t.sharedBuffer,t.ringBufferBase,t.bufferConstants),self.postMessage({type:"initialized"});break;case"start":h();break;case"stop":Q();break;default:console.warn("[OSCInWorker] Unknown message type:",t.type)}}catch(r){console.error("[OSCInWorker] Error:",r),self.postMessage({type:"error",error:r.message})}});H("[OSCInWorker] Script loaded");})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{function F(e,t,n){return(n-1-e+t)%n}function k({uint8View:e,dataView:t,bufferStart:n,bufferSize:s,head:c,payload:o,sequence:d,messageMagic:h,headerSize:S}){let U=o.length,m=S+U+3&-4,g=s-c;if(m>g){let u=new Uint8Array(S),R=new DataView(u.buffer);R.setUint32(0,h,!0),R.setUint32(4,m,!0),R.setUint32(8,d,!0),R.setUint32(12,0,!0);let I=n+c,x=n;if(g>=S){e.set(u,I);let P=g-S;P>0&&e.set(o.subarray(0,P),I+S),e.set(o.subarray(P),x)}else{e.set(u.subarray(0,g),I),e.set(u.subarray(g),x);let P=S-g;e.set(o,x+P)}}else{let u=n+c;t.setUint32(u,h,!0),t.setUint32(u+4,m,!0),t.setUint32(u+8,d,!0),t.setUint32(u+12,0,!0),e.set(o,u+S)}return(c+m)%s}function le(e,t,n=0){for(let s=0;s<=n;s++)if(Atomics.compareExchange(e,t,0,1)===0)return!0;return!1}function ie(e,t){Atomics.store(e,t,0)}function G({atomicView:e,dataView:t,uint8View:n,bufferConstants:s,ringBufferBase:c,controlIndices:o,oscMessage:d,maxSpins:h=0}){let S=d.length,U=s.MESSAGE_HEADER_SIZE+S;if(U>s.IN_BUFFER_SIZE-s.MESSAGE_HEADER_SIZE||!le(e,o.IN_WRITE_LOCK,h))return!1;try{let O=Atomics.load(e,o.IN_HEAD),m=Atomics.load(e,o.IN_TAIL),g=U+3&-4;if(F(O,m,s.IN_BUFFER_SIZE)<g)return!1;let R=Atomics.add(e,o.IN_SEQUENCE,1),I=k({uint8View:n,dataView:t,bufferStart:c+s.IN_BUFFER_START,bufferSize:s.IN_BUFFER_SIZE,head:O,payload:d,sequence:R,messageMagic:s.MESSAGE_MAGIC,headerSize:s.MESSAGE_HEADER_SIZE});return Atomics.load(e,o.IN_HEAD),Atomics.store(e,o.IN_HEAD,I),!0}finally{ie(e,o.IN_WRITE_LOCK)}}var p="sab",T=null,_=null,a=null,w=null,z=null,$=null,j={},i=null,D=null,Y=null,B=25,A=(e,t)=>{i&&(p==="sab"?Atomics.store(i,e,t):i[e]=t)},J=e=>i?p==="sab"?Atomics.load(i,e):i[e]:0,f=(e,t)=>{i&&(p==="sab"?Atomics.add(i,e,t):i[e]+=t)},Se=()=>{if(p!=="postMessage"||Y!==null)return;let e=()=>{D&&i&&self.postMessage({type:"preschedulerMetrics",metrics:new Uint32Array(D.slice(0))}),Y=setTimeout(e,B)};e(),E("[PreScheduler] Started metrics sending (every "+B+"ms)")};var r=[],ee=null,ge=0,W=!1,l=[],K=5,C=65536,pe=2208988800,te=25,de=.2,E=(...e)=>{},se=()=>(performance.timeOrigin+performance.now())/1e3+pe,Te=e=>{if(e.length>=16&&e[0]===35){let t=new DataView(e.buffer,e.byteOffset),n=t.getUint32(8,!1),s=t.getUint32(12,!1);return n+s/4294967296}return null};var _e=()=>{if(!T||!a){console.error("[PreScheduler] Cannot init - missing buffer or constants");return}w=new Int32Array(T),z=new DataView(T),$=new Uint8Array(T),j={IN_HEAD:(_+a.CONTROL_START+0)/4,IN_TAIL:(_+a.CONTROL_START+4)/4,IN_SEQUENCE:(_+a.CONTROL_START+24)/4,IN_WRITE_LOCK:(_+a.CONTROL_START+40)/4};let e=_+a.METRICS_START;i=new Uint32Array(T,e,a.METRICS_SIZE/4),E("[PreScheduler] SharedArrayBuffer initialized with direct ring buffer writing and metrics")},N=()=>{if(!i)return;A(6,r.length);let e=r.length,t=J(7);e>t&&A(7,e)},M=(e,t,n=null)=>{if(p==="postMessage")return self.postMessage({type:"dispatch",oscData:e,timestamp:n}),f(8,1),!0;if(!T||!w)return console.error("[PreScheduler] Not initialized for ring buffer writing"),!1;let s=e.length,c=a.MESSAGE_HEADER_SIZE+s;return c>a.IN_BUFFER_SIZE-a.MESSAGE_HEADER_SIZE?(console.error("[PreScheduler] Message too large:",c),!1):G({atomicView:w,dataView:z,uint8View:$,bufferConstants:a,ringBufferBase:_,controlIndices:j,oscMessage:e,maxSpins:10})?(f(8,1),!0):(t||console.warn("[PreScheduler] Ring buffer full, message will be queued for retry"),!1)},y=(e,t)=>{let n=r.length+l.length;if(n>=C){console.error("[PreScheduler] Backpressure: dropping retry ("+n+" pending)"),f(10,1);return}l.push({oscData:e,retryCount:0,context:t||"unknown",queuedAt:performance.now()}),A(15,l.length);let s=J(16);l.length>s&&A(16,l.length),E("[PreScheduler] Queued message for retry:",t,"queue size:",l.length)},he=()=>{if(l.length===0)return;let e=0;for(;e<l.length;){let t=l[e];if(M(t.oscData,!0))l.splice(e,1),f(9,1),f(14,1),A(15,l.length),E("[PreScheduler] Retry succeeded for:",t.context,"after",t.retryCount+1,"attempts");else if(t.retryCount++,f(14,1),t.retryCount>=K){let s=`Ring buffer full - dropped message after ${K} retries (${t.context})`;console.error("[PreScheduler]",s),l.splice(e,1),f(10,1),A(15,l.length),self.postMessage({type:"error",error:s})}else e++}},me=(e,t,n)=>{let s=r.length+l.length;if(s>=C)return console.warn("[PreScheduler] Backpressure: rejecting message ("+s+" pending)"),!1;let c=Te(e);if(c===null)return E("[PreScheduler] Non-bundle message, dispatching immediately"),M(e,!1)||y(e,"immediate message"),!0;let o=se(),d=c-o,h={ntpTime:c,seq:ge++,sessionId:t||0,runTag:n||"",oscData:e};return Re(h),f(11,1),N(),E("[PreScheduler] Scheduled bundle:","NTP="+c.toFixed(3),"current="+o.toFixed(3),"wait="+(d*1e3).toFixed(1)+"ms","pending="+r.length),!0},Re=e=>{r.push(e),Pe(r.length-1)},Ae=()=>r.length>0?r[0]:null,Ie=()=>{if(r.length===0)return null;let e=r[0],t=r.pop();return r.length>0&&(r[0]=t,ne(0)),e},Pe=e=>{for(;e>0;){let t=Math.floor((e-1)/2);if(b(r[e],r[t])>=0)break;re(e,t),e=t}},ne=e=>{let t=r.length;for(;;){let n=2*e+1,s=2*e+2,c=e;if(n<t&&b(r[n],r[c])<0&&(c=n),s<t&&b(r[s],r[c])<0&&(c=s),c===e)break;re(e,c),e=c}},b=(e,t)=>e.ntpTime===t.ntpTime?e.seq-t.seq:e.ntpTime-t.ntpTime,re=(e,t)=>{let n=r[e];r[e]=r[t],r[t]=n},Me=()=>{if(ee!==null){console.warn("[PreScheduler] Polling already started");return}E("[PreScheduler] Starting periodic polling (every "+te+"ms)"),ce()};var ce=()=>{W=!0,he();let e=se(),t=e+de,n=0;for(;r.length>0;){let s=Ae();if(s.ntpTime<=t){Ie(),N();let c=s.ntpTime-e;f(13,1),E("[PreScheduler] Dispatching bundle:","NTP="+s.ntpTime.toFixed(3),"current="+e.toFixed(3),"early="+(c*1e3).toFixed(1)+"ms","remaining="+r.length),M(s.oscData,!1)||y(s.oscData,"scheduled bundle NTP="+s.ntpTime.toFixed(3)),n++}else break}(n>0||r.length>0||l.length>0)&&E("[PreScheduler] Dispatch cycle complete:","dispatched="+n,"pending="+r.length,"retrying="+l.length),W=!1,ee=setTimeout(ce,te)},H=e=>{if(r.length===0)return;let t=r.length,n=[];for(let c=0;c<r.length;c++){let o=r[c];e(o)||n.push(o)}let s=t-n.length;s>0&&(r=n,Ue(),f(12,s),N(),E("[PreScheduler] Cancelled "+s+" events, "+r.length+" remaining"))},Ue=()=>{for(let e=Math.floor(r.length/2)-1;e>=0;e--)ne(e)},De=(e,t)=>{H(n=>n.sessionId===e&&n.runTag===t)},Ce=e=>{H(t=>t.sessionId===e)},ye=e=>{H(t=>t.runTag===e)},Ne=()=>{if(r.length===0)return;let e=r.length;f(12,e),r=[],N(),E("[PreScheduler] Cancelled all "+e+" events")},Oe=e=>!e||e.length<8?!1:e[0]===35&&e[1]===98&&e[2]===117&&e[3]===110&&e[4]===100&&e[5]===108&&e[6]===101&&e[7]===0,xe=e=>{let t=[],n=new DataView(e.buffer,e.byteOffset,e.byteLength),s=16;for(;s<e.length;){let c=n.getInt32(s,!1);if(s+=4,c<=0||s+c>e.length)break;let o=e.slice(s,s+c);for(t.push(o),s+=c;s%4!==0&&s<e.length;)s++}return t},Le=e=>{if(Oe(e)){let t=xe(e);for(let n=0;n<t.length;n++)M(t[n],!1)||y(t[n],"immediate bundle message "+n)}else M(e,!1)||y(e,"immediate message")};self.addEventListener("message",e=>{let{data:t}=e;try{switch(t.type){case"init":p=t.mode||"sab",t.maxPendingMessages&&(C=t.maxPendingMessages),t.snapshotIntervalMs&&(B=t.snapshotIntervalMs),p==="sab"?(T=t.sharedBuffer,_=t.ringBufferBase,a=t.bufferConstants,_e()):(D=new ArrayBuffer(128),i=new Uint32Array(D),Se()),Me(),E("[OSCPreSchedulerWorker] Initialized with NTP-based scheduling, mode="+p+", capacity="+C),self.postMessage({type:"initialized"});break;case"send":me(t.oscData,t.sessionId||0,t.runTag||"");break;case"sendImmediate":Le(t.oscData);break;case"cancelSessionTag":t.runTag!==void 0&&t.runTag!==null&&t.runTag!==""&&De(t.sessionId||0,t.runTag);break;case"cancelSession":Ce(t.sessionId||0);break;case"cancelTag":t.runTag!==void 0&&t.runTag!==null&&t.runTag!==""&&ye(t.runTag);break;case"cancelAll":Ne();break;default:console.warn("[OSCPreSchedulerWorker] Unknown message type:",t.type)}}catch(n){console.error("[OSCPreSchedulerWorker] Error:",n),self.postMessage({type:"error",error:n.message})}});E("[OSCPreSchedulerWorker] Script loaded");})();
|
|
@@ -0,0 +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);})();
|