supersonic-scsynth 0.64.0 → 0.66.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/LICENSE +56 -32
- package/README.md +41 -13
- package/README.npm.md +41 -13
- package/dist/metrics_component.js +1 -1
- package/dist/osc_channel.js +1 -1
- package/dist/osc_fast.js +1 -1
- package/dist/supersonic.js +5 -5
- package/dist/workers/debug_worker.js +3 -3
- package/dist/workers/osc_in_worker.js +1 -1
- package/dist/workers/osc_out_log_sab_worker.js +1 -1
- package/dist/workers/osc_out_prescheduler_worker.js +1 -1
- package/package.json +1 -1
- package/supersonic.d.ts +102 -1
package/LICENSE
CHANGED
|
@@ -1,31 +1,46 @@
|
|
|
1
|
-
SuperSonic -
|
|
1
|
+
SuperSonic - Audio Synthesis Engine
|
|
2
2
|
Copyright (c) 2025 Sam Aaron
|
|
3
3
|
|
|
4
4
|
This project is dual-licensed depending on the component:
|
|
5
5
|
|
|
6
6
|
================================================================================
|
|
7
|
-
|
|
7
|
+
Client Libraries (MIT OR GPL-3.0-or-later)
|
|
8
8
|
================================================================================
|
|
9
9
|
|
|
10
|
-
The following
|
|
11
|
-
GPL-3.0-or-later
|
|
10
|
+
The following client API files are dual-licensed under your choice of MIT or
|
|
11
|
+
GPL-3.0-or-later. These communicate with the engine exclusively via serialised
|
|
12
|
+
Open Sound Control (OSC) messages and contain no GPL-derived code.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
JavaScript client:
|
|
15
|
+
js/supersonic.js
|
|
16
|
+
js/lib/
|
|
17
|
+
js/workers/debug_worker.js
|
|
18
|
+
js/workers/osc_in_worker.js
|
|
19
|
+
js/workers/osc_out_log_sab_worker.js
|
|
20
|
+
js/workers/osc_out_prescheduler_worker.js
|
|
21
|
+
|
|
22
|
+
Erlang/BEAM client:
|
|
23
|
+
src/nif/supersonic.erl
|
|
19
24
|
|
|
20
25
|
================================================================================
|
|
21
|
-
Audio Engine
|
|
26
|
+
Audio Engine (GPL-3.0-or-later)
|
|
22
27
|
================================================================================
|
|
23
28
|
|
|
24
29
|
The following components are licensed under GPL-3.0-or-later only:
|
|
25
30
|
|
|
26
|
-
src/ (C
|
|
31
|
+
src/ (C++ audio engine — shared across all
|
|
32
|
+
build targets: WASM, native, NIF)
|
|
33
|
+
src/native/ (Native JUCE host wrapper)
|
|
27
34
|
js/workers/scsynth_audio_worklet.js (AudioWorklet that executes WASM)
|
|
28
35
|
|
|
36
|
+
The engine compiles to three targets:
|
|
37
|
+
- WebAssembly (AudioWorklet) — for browsers
|
|
38
|
+
- Native executable (JUCE) — for desktop use and Sonic Pi
|
|
39
|
+
- NIF shared library (BEAM) — for Erlang/Elixir applications
|
|
40
|
+
|
|
41
|
+
All three targets link the same GPL-licensed engine code derived from
|
|
42
|
+
SuperCollider's scsynth.
|
|
43
|
+
|
|
29
44
|
Based on SuperCollider's scsynth
|
|
30
45
|
Copyright (c) 2002-2023 James McCartney and SuperCollider contributors
|
|
31
46
|
|
|
@@ -76,33 +91,42 @@ It is provided for clarification and guidance only and does not modify,
|
|
|
76
91
|
supersede, or reinterpret the terms of the GPL.
|
|
77
92
|
|
|
78
93
|
SuperSonic is deliberately designed with a strict execution boundary between
|
|
79
|
-
the GPL-licensed audio engine and application-level code
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
- The
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
shared-memory transport used only for
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
the GPL-licensed audio engine and application-level code. All communication
|
|
95
|
+
crosses this boundary via serialised OSC messages — a language-neutral,
|
|
96
|
+
protocol-level messaging system comparable to network or IPC-based
|
|
97
|
+
communication between independent software components.
|
|
98
|
+
|
|
99
|
+
The boundary is enforced by architecture on each platform:
|
|
100
|
+
|
|
101
|
+
- Web (WASM): The engine runs inside an AudioWorklet, providing strong
|
|
102
|
+
execution isolation. Code outside the AudioWorklet cannot directly access
|
|
103
|
+
engine internals, shared closures, object references, or function calls.
|
|
104
|
+
The MIT-licensed JavaScript client communicates exclusively via
|
|
105
|
+
postMessage or shared-memory transport used only for serialised OSC
|
|
106
|
+
message exchange.
|
|
107
|
+
|
|
108
|
+
- Native (JUCE): The engine runs as a standalone process or within a host
|
|
109
|
+
application. External code communicates via UDP OSC messages over a
|
|
110
|
+
network socket — a clear process boundary.
|
|
111
|
+
|
|
112
|
+
- NIF (BEAM): The engine is loaded as a NIF shared library. The
|
|
113
|
+
MIT-licensed Erlang module (src/nif/supersonic.erl) exposes five
|
|
114
|
+
functions: start, stop, send_osc, set_notification_pid, and
|
|
115
|
+
clear_notification_pid. All data crossing the NIF boundary consists of
|
|
116
|
+
raw OSC binary blobs and Erlang messages — no engine types, data
|
|
117
|
+
structures, or callbacks leak into the Erlang API. This is functionally
|
|
118
|
+
equivalent to communication over a network socket.
|
|
94
119
|
|
|
95
120
|
It is the project author's good-faith interpretation that application code
|
|
96
|
-
which uses the MIT-licensed client
|
|
121
|
+
which uses the MIT-licensed client libraries solely to send and receive OSC
|
|
97
122
|
messages with the engine would generally not constitute a derivative work of
|
|
98
123
|
the GPL-licensed audio engine, provided that:
|
|
99
124
|
|
|
100
|
-
1. The GPL-licensed components
|
|
101
|
-
|
|
102
|
-
modifications to these components remain subject to the GPL.
|
|
125
|
+
1. The GPL-licensed components are not modified. Any modifications to these
|
|
126
|
+
components remain subject to the GPL.
|
|
103
127
|
|
|
104
128
|
2. Application code interacts with the engine exclusively through the
|
|
105
|
-
documented OSC message interface via the MIT-licensed client
|
|
129
|
+
documented OSC message interface via the MIT-licensed client libraries.
|
|
106
130
|
|
|
107
131
|
3. Distribution of the GPL-licensed engine components remains compliant
|
|
108
132
|
with the GPL, including providing access to corresponding source code
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SuperSonic 0.
|
|
1
|
+
# SuperSonic 0.66.0
|
|
2
2
|
|
|
3
3
|
> SuperCollider's scsynth in the browser as an AudioWorklet.
|
|
4
4
|
>
|
|
@@ -247,6 +247,7 @@ scsynth with low latency inside a web page.
|
|
|
247
247
|
| [`ringBufferBase`](#ringbufferbase) | Ring buffer base offset in SharedArrayBuffer. |
|
|
248
248
|
| [`sharedBuffer`](#sharedbuffer) | The SharedArrayBuffer (SAB mode) or null (postMessage mode). |
|
|
249
249
|
| [`getLoadedBuffers()`](#getloadedbuffers) | Get info about all loaded audio buffers. |
|
|
250
|
+
| [`getSystemReport()`](#getsystemreport) | Get a comprehensive system performance report. |
|
|
250
251
|
| [`nextNodeId()`](#nextnodeid) | Get the next unique node ID. |
|
|
251
252
|
| [`getRawTreeSchema()`](#getrawtreeschema) | Get schema describing the raw flat node tree structure. |
|
|
252
253
|
| [`getTreeSchema()`](#gettreeschema) | Get schema describing the hierarchical node tree structure. |
|
|
@@ -859,6 +860,7 @@ if (loaded.some(b => b.hash === info.hash)) {
|
|
|
859
860
|
| <a id="audiocontextoptions"></a> `audioContextOptions?` | `AudioContextOptions` | Options passed to `new AudioContext()`. Ignored if `audioContext` is provided. | |
|
|
860
861
|
| <a id="autoconnect"></a> `autoConnect?` | `boolean` | Auto-connect the AudioWorkletNode to the AudioContext destination. Default: true. | |
|
|
861
862
|
| <a id="baseurl"></a> `baseURL?` | `string` | Convenience shorthand when all assets (WASM, workers, synthdefs, samples) are co-located. | Yes\* |
|
|
863
|
+
| <a id="buffergrowincrement"></a> `bufferGrowIncrement?` | `number` | Bytes to grow the buffer pool per growth event. Default: 32MB. | |
|
|
862
864
|
| <a id="bypasslookaheadms"></a> `bypassLookaheadMs?` | `number` | Bundles scheduled within this many ms of now are dispatched immediately for lowest latency. Bundles further in the future are held and dispatched closer to their scheduled time. Default: 500. | |
|
|
863
865
|
| <a id="corebaseurl"></a> `coreBaseURL?` | `string` | Base URL for GPL assets: WASM and AudioWorklet (supersonic-scsynth-core package). Defaults to `baseURL`. | |
|
|
864
866
|
| <a id="debug-1"></a> `debug?` | `boolean` | Enable all debug console logging. Default: false. | |
|
|
@@ -867,6 +869,7 @@ if (loaded.some(b => b.hash === info.hash)) {
|
|
|
867
869
|
| <a id="debugscsynth"></a> `debugScsynth?` | `boolean` | Log scsynth debug output to console. Default: false. | |
|
|
868
870
|
| <a id="fetchmaxretries"></a> `fetchMaxRetries?` | `number` | Max fetch retries when loading assets. Default: 3. | |
|
|
869
871
|
| <a id="fetchretrydelay"></a> `fetchRetryDelay?` | `number` | Base delay between retries in ms (exponential backoff). Default: 1000. | |
|
|
872
|
+
| <a id="maxbuffermemory"></a> `maxBufferMemory?` | `number` | Maximum buffer pool capacity in bytes. Pool grows on demand up to this limit. Default: 256MB. | |
|
|
870
873
|
| <a id="mode-5"></a> `mode?` | [`TransportMode`](#transportmode) | Transport mode. - `'postMessage'` (default) — works everywhere, no special headers needed - `'sab'` — lowest latency, requires Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers See docs/MODES.md for a full comparison of communication modes. | |
|
|
871
874
|
| <a id="preschedulercapacity-1"></a> `preschedulerCapacity?` | `number` | Max pending events in the JS prescheduler. Default: 65536. | |
|
|
872
875
|
| <a id="samplebaseurl"></a> `sampleBaseURL?` | `string` | Base URL for audio sample files (used by [SuperSonic.loadSample](#loadsample)). | |
|
|
@@ -1329,6 +1332,30 @@ Useful for capturing state for bug reports or debugging timing issues.
|
|
|
1329
1332
|
|
|
1330
1333
|
[`Snapshot`](#snapshot)
|
|
1331
1334
|
|
|
1335
|
+
##### getSystemReport()
|
|
1336
|
+
|
|
1337
|
+
> **getSystemReport**(): [`SystemReport`](#systemreport)
|
|
1338
|
+
|
|
1339
|
+
Get a comprehensive system performance report.
|
|
1340
|
+
|
|
1341
|
+
Includes hardware info, audio configuration, Chrome playbackStats (if available),
|
|
1342
|
+
a cross-browser audio health percentage, and a human-readable health assessment.
|
|
1343
|
+
Useful for diagnosing audio crackling on constrained hardware.
|
|
1344
|
+
|
|
1345
|
+
###### Returns
|
|
1346
|
+
|
|
1347
|
+
[`SystemReport`](#systemreport)
|
|
1348
|
+
|
|
1349
|
+
###### Example
|
|
1350
|
+
|
|
1351
|
+
```ts
|
|
1352
|
+
const report = sonic.getSystemReport();
|
|
1353
|
+
console.log(report.health.summary);
|
|
1354
|
+
if (report.health.audioHealthPct < 95) {
|
|
1355
|
+
console.warn('Audio thread struggling:', report.health.issues);
|
|
1356
|
+
}
|
|
1357
|
+
```
|
|
1358
|
+
|
|
1332
1359
|
##### getTree()
|
|
1333
1360
|
|
|
1334
1361
|
> **getTree**(): [`Tree`](#tree)
|
|
@@ -1573,11 +1600,7 @@ Subscribe to an event.
|
|
|
1573
1600
|
|
|
1574
1601
|
Unsubscribe function — call it to remove the listener
|
|
1575
1602
|
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
###### Returns
|
|
1579
|
-
|
|
1580
|
-
`void`
|
|
1603
|
+
() => `void`
|
|
1581
1604
|
|
|
1582
1605
|
###### Example
|
|
1583
1606
|
|
|
@@ -1614,11 +1637,7 @@ Returns an unsubscribe function (matching [on](#on)).
|
|
|
1614
1637
|
|
|
1615
1638
|
Unsubscribe function — call it to remove the listener before it fires
|
|
1616
1639
|
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
###### Returns
|
|
1620
|
-
|
|
1621
|
-
`void`
|
|
1640
|
+
() => `void`
|
|
1622
1641
|
|
|
1623
1642
|
##### purge()
|
|
1624
1643
|
|
|
@@ -1699,6 +1718,7 @@ Remove all listeners for an event, or all listeners entirely.
|
|
|
1699
1718
|
| <a id="audiocontextresumed"></a> `audiocontext:resumed` | AudioContext resumed to 'running' state. |
|
|
1700
1719
|
| <a id="audiocontextstatechange"></a> `audiocontext:statechange` | AudioContext state changed. State is one of: `'running'`, `'suspended'`, `'closed'`, or `'interrupted'`. |
|
|
1701
1720
|
| <a id="audiocontextsuspended"></a> `audiocontext:suspended` | AudioContext was suspended (e.g. tab backgrounded, autoplay policy, iOS audio interruption). Show a restart UI and call `recover()` when the user interacts. |
|
|
1721
|
+
| <a id="bufferpoolgrown"></a> `buffer:pool:grown` | Buffer pool grew on demand. Fired when the initial pool was exhausted and a new segment was added. |
|
|
1702
1722
|
| <a id="debug"></a> `debug` | Debug text output from scsynth (e.g. synthdef compilation messages). Includes NTP timestamp and sequence number. |
|
|
1703
1723
|
| <a id="destroy-1"></a> `destroy` | Engine has been destroyed. Only fired by `destroy()`, not by `shutdown()` or `reset()`. Last chance to clean up before all listeners are cleared. |
|
|
1704
1724
|
| <a id="error"></a> `error` | Error from any component (worklet, transport, workers). |
|
|
@@ -3053,13 +3073,21 @@ Start capturing audio output to a buffer. SAB mode only.
|
|
|
3053
3073
|
|
|
3054
3074
|
##### stopCapture()
|
|
3055
3075
|
|
|
3056
|
-
> **stopCapture**(): `
|
|
3076
|
+
> **stopCapture**(): `object`
|
|
3057
3077
|
|
|
3058
3078
|
Stop capturing and return the captured audio data.
|
|
3059
3079
|
|
|
3060
3080
|
###### Returns
|
|
3061
3081
|
|
|
3062
|
-
`
|
|
3082
|
+
`object`
|
|
3083
|
+
|
|
3084
|
+
| Name | Type |
|
|
3085
|
+
| ------------ | --------------------------------- |
|
|
3086
|
+
| `channels` | `number` |
|
|
3087
|
+
| `frames` | `number` |
|
|
3088
|
+
| `left` | `Float32Array` |
|
|
3089
|
+
| `right` | `Float32Array`<`ArrayBufferLike`> |
|
|
3090
|
+
| `sampleRate` | `number` |
|
|
3063
3091
|
|
|
3064
3092
|
##### suspend()
|
|
3065
3093
|
|
package/README.npm.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SuperSonic 0.
|
|
1
|
+
# SuperSonic 0.66.0
|
|
2
2
|
|
|
3
3
|
> SuperCollider's scsynth in the browser as an AudioWorklet.
|
|
4
4
|
>
|
|
@@ -247,6 +247,7 @@ scsynth with low latency inside a web page.
|
|
|
247
247
|
| [`ringBufferBase`](#ringbufferbase) | Ring buffer base offset in SharedArrayBuffer. |
|
|
248
248
|
| [`sharedBuffer`](#sharedbuffer) | The SharedArrayBuffer (SAB mode) or null (postMessage mode). |
|
|
249
249
|
| [`getLoadedBuffers()`](#getloadedbuffers) | Get info about all loaded audio buffers. |
|
|
250
|
+
| [`getSystemReport()`](#getsystemreport) | Get a comprehensive system performance report. |
|
|
250
251
|
| [`nextNodeId()`](#nextnodeid) | Get the next unique node ID. |
|
|
251
252
|
| [`getRawTreeSchema()`](#getrawtreeschema) | Get schema describing the raw flat node tree structure. |
|
|
252
253
|
| [`getTreeSchema()`](#gettreeschema) | Get schema describing the hierarchical node tree structure. |
|
|
@@ -859,6 +860,7 @@ if (loaded.some(b => b.hash === info.hash)) {
|
|
|
859
860
|
| <a id="audiocontextoptions"></a> `audioContextOptions?` | `AudioContextOptions` | Options passed to `new AudioContext()`. Ignored if `audioContext` is provided. | |
|
|
860
861
|
| <a id="autoconnect"></a> `autoConnect?` | `boolean` | Auto-connect the AudioWorkletNode to the AudioContext destination. Default: true. | |
|
|
861
862
|
| <a id="baseurl"></a> `baseURL?` | `string` | Convenience shorthand when all assets (WASM, workers, synthdefs, samples) are co-located. | Yes\* |
|
|
863
|
+
| <a id="buffergrowincrement"></a> `bufferGrowIncrement?` | `number` | Bytes to grow the buffer pool per growth event. Default: 32MB. | |
|
|
862
864
|
| <a id="bypasslookaheadms"></a> `bypassLookaheadMs?` | `number` | Bundles scheduled within this many ms of now are dispatched immediately for lowest latency. Bundles further in the future are held and dispatched closer to their scheduled time. Default: 500. | |
|
|
863
865
|
| <a id="corebaseurl"></a> `coreBaseURL?` | `string` | Base URL for GPL assets: WASM and AudioWorklet (supersonic-scsynth-core package). Defaults to `baseURL`. | |
|
|
864
866
|
| <a id="debug-1"></a> `debug?` | `boolean` | Enable all debug console logging. Default: false. | |
|
|
@@ -867,6 +869,7 @@ if (loaded.some(b => b.hash === info.hash)) {
|
|
|
867
869
|
| <a id="debugscsynth"></a> `debugScsynth?` | `boolean` | Log scsynth debug output to console. Default: false. | |
|
|
868
870
|
| <a id="fetchmaxretries"></a> `fetchMaxRetries?` | `number` | Max fetch retries when loading assets. Default: 3. | |
|
|
869
871
|
| <a id="fetchretrydelay"></a> `fetchRetryDelay?` | `number` | Base delay between retries in ms (exponential backoff). Default: 1000. | |
|
|
872
|
+
| <a id="maxbuffermemory"></a> `maxBufferMemory?` | `number` | Maximum buffer pool capacity in bytes. Pool grows on demand up to this limit. Default: 256MB. | |
|
|
870
873
|
| <a id="mode-5"></a> `mode?` | [`TransportMode`](#transportmode) | Transport mode. - `'postMessage'` (default) — works everywhere, no special headers needed - `'sab'` — lowest latency, requires Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers See docs/MODES.md for a full comparison of communication modes. | |
|
|
871
874
|
| <a id="preschedulercapacity-1"></a> `preschedulerCapacity?` | `number` | Max pending events in the JS prescheduler. Default: 65536. | |
|
|
872
875
|
| <a id="samplebaseurl"></a> `sampleBaseURL?` | `string` | Base URL for audio sample files (used by [SuperSonic.loadSample](#loadsample)). | |
|
|
@@ -1329,6 +1332,30 @@ Useful for capturing state for bug reports or debugging timing issues.
|
|
|
1329
1332
|
|
|
1330
1333
|
[`Snapshot`](#snapshot)
|
|
1331
1334
|
|
|
1335
|
+
##### getSystemReport()
|
|
1336
|
+
|
|
1337
|
+
> **getSystemReport**(): [`SystemReport`](#systemreport)
|
|
1338
|
+
|
|
1339
|
+
Get a comprehensive system performance report.
|
|
1340
|
+
|
|
1341
|
+
Includes hardware info, audio configuration, Chrome playbackStats (if available),
|
|
1342
|
+
a cross-browser audio health percentage, and a human-readable health assessment.
|
|
1343
|
+
Useful for diagnosing audio crackling on constrained hardware.
|
|
1344
|
+
|
|
1345
|
+
###### Returns
|
|
1346
|
+
|
|
1347
|
+
[`SystemReport`](#systemreport)
|
|
1348
|
+
|
|
1349
|
+
###### Example
|
|
1350
|
+
|
|
1351
|
+
```ts
|
|
1352
|
+
const report = sonic.getSystemReport();
|
|
1353
|
+
console.log(report.health.summary);
|
|
1354
|
+
if (report.health.audioHealthPct < 95) {
|
|
1355
|
+
console.warn('Audio thread struggling:', report.health.issues);
|
|
1356
|
+
}
|
|
1357
|
+
```
|
|
1358
|
+
|
|
1332
1359
|
##### getTree()
|
|
1333
1360
|
|
|
1334
1361
|
> **getTree**(): [`Tree`](#tree)
|
|
@@ -1573,11 +1600,7 @@ Subscribe to an event.
|
|
|
1573
1600
|
|
|
1574
1601
|
Unsubscribe function — call it to remove the listener
|
|
1575
1602
|
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
###### Returns
|
|
1579
|
-
|
|
1580
|
-
`void`
|
|
1603
|
+
() => `void`
|
|
1581
1604
|
|
|
1582
1605
|
###### Example
|
|
1583
1606
|
|
|
@@ -1614,11 +1637,7 @@ Returns an unsubscribe function (matching [on](#on)).
|
|
|
1614
1637
|
|
|
1615
1638
|
Unsubscribe function — call it to remove the listener before it fires
|
|
1616
1639
|
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
###### Returns
|
|
1620
|
-
|
|
1621
|
-
`void`
|
|
1640
|
+
() => `void`
|
|
1622
1641
|
|
|
1623
1642
|
##### purge()
|
|
1624
1643
|
|
|
@@ -1699,6 +1718,7 @@ Remove all listeners for an event, or all listeners entirely.
|
|
|
1699
1718
|
| <a id="audiocontextresumed"></a> `audiocontext:resumed` | AudioContext resumed to 'running' state. |
|
|
1700
1719
|
| <a id="audiocontextstatechange"></a> `audiocontext:statechange` | AudioContext state changed. State is one of: `'running'`, `'suspended'`, `'closed'`, or `'interrupted'`. |
|
|
1701
1720
|
| <a id="audiocontextsuspended"></a> `audiocontext:suspended` | AudioContext was suspended (e.g. tab backgrounded, autoplay policy, iOS audio interruption). Show a restart UI and call `recover()` when the user interacts. |
|
|
1721
|
+
| <a id="bufferpoolgrown"></a> `buffer:pool:grown` | Buffer pool grew on demand. Fired when the initial pool was exhausted and a new segment was added. |
|
|
1702
1722
|
| <a id="debug"></a> `debug` | Debug text output from scsynth (e.g. synthdef compilation messages). Includes NTP timestamp and sequence number. |
|
|
1703
1723
|
| <a id="destroy-1"></a> `destroy` | Engine has been destroyed. Only fired by `destroy()`, not by `shutdown()` or `reset()`. Last chance to clean up before all listeners are cleared. |
|
|
1704
1724
|
| <a id="error"></a> `error` | Error from any component (worklet, transport, workers). |
|
|
@@ -3053,13 +3073,21 @@ Start capturing audio output to a buffer. SAB mode only.
|
|
|
3053
3073
|
|
|
3054
3074
|
##### stopCapture()
|
|
3055
3075
|
|
|
3056
|
-
> **stopCapture**(): `
|
|
3076
|
+
> **stopCapture**(): `object`
|
|
3057
3077
|
|
|
3058
3078
|
Stop capturing and return the captured audio data.
|
|
3059
3079
|
|
|
3060
3080
|
###### Returns
|
|
3061
3081
|
|
|
3062
|
-
`
|
|
3082
|
+
`object`
|
|
3083
|
+
|
|
3084
|
+
| Name | Type |
|
|
3085
|
+
| ------------ | --------------------------------- |
|
|
3086
|
+
| `channels` | `number` |
|
|
3087
|
+
| `frames` | `number` |
|
|
3088
|
+
| `left` | `Float32Array` |
|
|
3089
|
+
| `right` | `Float32Array`<`ArrayBufferLike`> |
|
|
3090
|
+
| `sampleRate` | `number` |
|
|
3063
3091
|
|
|
3064
3092
|
##### suspend()
|
|
3065
3093
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
function h(n){if(!Number.isFinite(n)||n<=0)return"0 B";let c=["B","KB","MB","GB"],s=0;for(;n>=1024&&s<c.length-1;)n/=1024,s++;return`${n.toFixed(s>0?1:0)} ${c[s]}`}function E(n){return n===4294967295?"-":String(n)}function k(n,c){return c[n]??String(n)}function v(n){return String(n|0)}function u(n){return(n/1e3).toFixed(1)}function C(n,c,s){if(n.format==="bytes")return e=>h(e);if(n.format==="headroom")return e=>E(e);if(n.format==="signed")return e=>v(e);if(n.format==="percent")return e=>String(e);if(n.format==="latencyUs")return e=>u(e);if(n.format==="enum"&&c?.values){let e=c.values;return i=>k(i,e)}let t=s.hasPlaybackStats?.offset;return n.format==="chromeOnly"?(e,i)=>t!==void 0&&i&&!i[t]?"-":String(e):n.format==="chromeLatencyUs"?(e,i)=>t!==void 0&&i&&!i[t]?"-":u(e):e=>String(e)}var m=class extends HTMLElement{#e=null;#t=null;#s=[];#n=[];#a=!1;buildFromSchema(c){let s=c.getMetricsSchema(),t=s.metrics,e=s.layout;this.innerHTML="",this.#s=[],this.#n=[];for(let i of e.panels){let o=document.createElement("div");o.className="ssm-panel"+(i.class?` ssm-panel--${i.class}`:"");let a=document.createElement("div");a.className="ssm-title",a.textContent=i.title,o.appendChild(a);for(let l of i.rows)l.type==="bar"?this.#i(o,l,t):this.#l(o,l,t);this.appendChild(o)}this.#a=!0}connect(c,s={}){this.disconnect(),this.#e=c,this.#a||this.buildFromSchema(c.constructor);let t=s.refreshRate??10;this.#t=setInterval(()=>this.#c(),1e3/t)}disconnect(){this.#t!==null&&(clearInterval(this.#t),this.#t=null),this.#e=null}disconnectedCallback(){this.disconnect()}#l(c,s,t){let e=document.createElement("div");if(e.className="ssm-row",s.tooltip)e.title=s.tooltip;else{let a=s.cells?.find(l=>l.key);if(a){let l=t[a.key];l?.description&&(e.title=l.description)}}let i=document.createElement("span");i.className="ssm-label",i.textContent=s.label,e.appendChild(i);let o=document.createElement("span");for(let a of s.cells||[])if(a.sep!==void 0){let l=document.createElement("span");l.className="ssm-sep",l.textContent=a.sep,o.appendChild(l)}else if(a.text!==void 0){let l=document.createElement("span");l.className="ssm-value",a.kind&&l.setAttribute("data-kind",a.kind),l.textContent=a.text,o.appendChild(l)}else if(a.key){let l=t[a.key];if(!l)continue;let r=document.createElement("span");r.className="ssm-value",a.kind&&r.setAttribute("data-kind",a.kind),r.textContent="-",o.appendChild(r),this.#s.push({offset:l.offset,format:C(a,l,t),el:r,prev:-1})}e.appendChild(o),c.appendChild(e)}#i(c,s,t){let e=document.createElement("div");e.className="ssm-bar";let i=t[s.usedKey],o=t[s.peakKey],a=t[s.capacityKey];i?.description&&(e.title=i.description);let l=document.createElement("span");l.className="ssm-bar-label",l.textContent=s.label,e.appendChild(l);let r=document.createElement("div");r.className="ssm-bar-track";let f=document.createElement("div");f.className=`ssm-bar-fill ssm-bar-fill--${s.color}`,r.appendChild(f);let p=document.createElement("div");p.className=`ssm-bar-peak ssm-bar-peak--${s.color}`,r.appendChild(p),e.appendChild(r);let d=document.createElement("span");d.className="ssm-bar-value ssm-value",s.color==="green"?d.setAttribute("data-kind","green"):s.color==="purple"&&d.setAttribute("data-kind","purple"),d.textContent="-",e.appendChild(d),c.appendChild(e),this.#n.push({usedOffset:i?.offset??0,peakOffset:o?.offset??0,capacityOffset:a?.offset??0,fillEl:f,peakEl:p,labelEl:d,prevUsed:-1,prevPeak:-1,prevCap:-1})}#c(){if(!this.#e)return;let c=this.#e.getMetricsArray();for(let s=0;s<this.#s.length;s++){let t=this.#s[s],e=c[t.offset];e!==t.prev&&(t.el.textContent=t.format(e,c),t.prev=e)}for(let s=0;s<this.#n.length;s++){let t=this.#n[s],e=c[t.usedOffset],i=c[t.peakOffset],o=c[t.capacityOffset];if(e!==t.prevUsed||o!==t.prevCap){if(o>0){let a=e/o*100;t.fillEl.style.width=a+"%",t.labelEl.textContent=a.toFixed(1)+"%"}else t.fillEl.style.width="0%",t.labelEl.textContent="N/A";t.prevUsed=e,t.prevCap=o}if(i!==t.prevPeak&&o>0){let a=i/o*100;t.peakEl.style.left=`calc(${a}% - 1px)`,t.prevPeak=i}}}};typeof customElements<"u"&&!customElements.get("supersonic-metrics")&&customElements.define("supersonic-metrics",m);export{m as SupersonicMetrics};
|
package/dist/osc_channel.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
function g(s,t,e){return(e-1-s+t)%e}function Y({uint8View:s,dataView:t,bufferStart:e,bufferSize:r,head:n,payload:o,sequence:E,messageMagic:c,headerSize:i,sourceId:S=0,headerScratch:a=null,headerScratchView:I=null}){let f=o.length,u=i+f+3&-4,T=r-n;if(u>T){let _=a||new Uint8Array(i),A=I||new DataView(_.buffer);A.setUint32(0,c,!0),A.setUint32(4,u,!0),A.setUint32(8,E,!0),A.setUint32(12,S,!0);let d=e+n,l=e;if(T>=i){s.set(_,d);let h=T-i;h>0&&s.set(o.subarray(0,h),d+i),s.set(o.subarray(h),l)}else{s.set(_.subarray(0,T),d),s.set(_.subarray(T),l);let h=i-T;s.set(o,l+h)}}else{let _=e+n;t.setUint32(_,c,!0),t.setUint32(_+4,u,!0),t.setUint32(_+8,E,!0),t.setUint32(_+12,S,!0),s.set(o,_+i)}return(n+u)%r}function b(s,t,e=0,r=!1){for(let n=0;n<=e;n++)if(Atomics.compareExchange(s,t,0,1)===0)return!0;if(r){for(let o=0;o<100;o++)if(Atomics.wait(s,t,1,100),Atomics.compareExchange(s,t,0,1)===0)return!0;return console.error("[RingBuffer] Lock acquisition timeout after 10s - possible deadlock"),!1}return!1}function y(s,t){Atomics.store(s,t,0),Atomics.notify(s,t,1)}function N({atomicView:s,dataView:t,uint8View:e,bufferConstants:r,ringBufferBase:n,controlIndices:o,oscMessage:E,sourceId:c=0,maxSpins:i=0,useWait:S=!1}){let a=E.length,I=r.MESSAGE_HEADER_SIZE+a;if(I>r.IN_BUFFER_SIZE-r.MESSAGE_HEADER_SIZE||!b(s,o.IN_WRITE_LOCK,i,S))return!1;try{let f=Atomics.load(s,o.IN_HEAD),U=Atomics.load(s,o.IN_TAIL),u=I+3&-4;if(g(f,U,r.IN_BUFFER_SIZE)<u)return!1;let _=Atomics.add(s,o.IN_SEQUENCE,1),A=Y({uint8View:e,dataView:t,bufferStart:n+r.IN_BUFFER_START,bufferSize:r.IN_BUFFER_SIZE,head:f,payload:E,sequence:_,messageMagic:r.MESSAGE_MAGIC,headerSize:r.MESSAGE_HEADER_SIZE,sourceId:c});return Atomics.load(s,o.IN_HEAD),Atomics.store(s,o.IN_HEAD,A),Atomics.notify(s,o.IN_HEAD,1),!0}finally{y(s,o.IN_WRITE_LOCK)}}function B(s,t){let e=s+t;return{IN_HEAD:(e+0)/4,IN_TAIL:(e+4)/4,IN_SEQUENCE:(e+24)/4,IN_WRITE_LOCK:(e+40)/4,IN_LOG_TAIL:(e+44)/4}}function X(s){return s.length>=8&&s[0]===35&&s[1]===98&&s[2]===117&&s[3]===110&&s[4]===100&&s[5]===108&&s[6]===101&&s[7]===0}var p=.5;function w(s){if(s.length<16)return null;let t=new DataView(s.buffer,s.byteOffset,s.byteLength);return{ntpSeconds:t.getUint32(8,!1),ntpFraction:t.getUint32(12,!1)}}function C(){return(performance.timeOrigin+performance.now())/1e3+2208988800}function O(s,t={}){let{getCurrentNTP:e=C,bypassLookaheadS:r=p}=t;if(!X(s))return"nonBundle";let n=w(s);if(!n)return"nonBundle";let{ntpSeconds:o,ntpFraction:E}=n;if(o===0&&E<=1)return"immediate";let c=e();if(c===null||c===0)return"immediate";let S=o+E/4294967296-c;return S<0?"late":S<r?"nearFuture":"farFuture"}function L(s){return s!=="farFuture"}var K={nonBundle:38,immediate:39,nearFuture:40,late:41},R=class s{#s;#r;#o;#u;#e;#t;#I;#E;#f;#d;#l;#p;#T;#_;#a;#c;#S;#i;#A;#n={messagesSent:0,bytesSent:0,nonBundle:0,immediate:0,nearFuture:0,late:0,bypassed:0};constructor(t,e){if(this.#s=t,this.#e=e.preschedulerPort||null,this.#I=e.bypassLookaheadS??p,this.#E=e.sourceId??0,this.#f=e.blocking??this.#E!==0,this.#d=e.getCurrentNTP??C,this.#a=1e3,t==="postMessage")this.#r=e.port;else{if(this.#o={sharedBuffer:e.sharedBuffer,ringBufferBase:e.ringBufferBase,bufferConstants:e.bufferConstants,controlIndices:e.controlIndices},this.#B(),e.sharedBuffer&&e.bufferConstants){let r=e.ringBufferBase+e.bufferConstants.METRICS_START;this.#t=new Int32Array(e.sharedBuffer,r,e.bufferConstants.METRICS_SIZE/4)}if(e.sharedBuffer&&e.bufferConstants?.NODE_ID_COUNTER_START!==void 0){let r=e.ringBufferBase+e.bufferConstants.NODE_ID_COUNTER_START;this.#l=new Int32Array(e.sharedBuffer,r,1),this.#R()}}e.nodeIdSource&&(this.#c=e.nodeIdSource,this.#R()),e.nodeIdRange&&(this.#p=e.nodeIdRange.from,this.#T=e.nodeIdRange.to,this.#_=e.nodeIdRange.from),e.nodeIdPort&&(this.#S=e.nodeIdPort,this.#S.onmessage=r=>{r.data.type==="nodeIdRange"&&(this.#i={from:r.data.from,to:r.data.to})},this.#h())}#B(){let t=this.#o.sharedBuffer;this.#u={atomicView:new Int32Array(t),dataView:new DataView(t),uint8View:new Uint8Array(t)}}classify(t){return O(t,{getCurrentNTP:this.#d,bypassLookaheadS:this.#I})}#U(t,e=null){if(this.#s==="sab"&&this.#t){if(Atomics.add(this.#t,24,1),Atomics.add(this.#t,25,t),e){let r=K[e];r!==void 0&&(Atomics.add(this.#t,r,1),Atomics.add(this.#t,22,1))}}else this.#n.messagesSent++,this.#n.bytesSent+=t,e&&e in this.#n&&(this.#n[e]++,this.#n.bypassed++)}getAndResetMetrics(){let t={...this.#n};return this.#n={messagesSent:0,bytesSent:0,nonBundle:0,immediate:0,nearFuture:0,late:0,bypassed:0},t}getMetrics(){return this.#s==="sab"&&this.#t?{messagesSent:Atomics.load(this.#t,24),bytesSent:Atomics.load(this.#t,25),nonBundle:Atomics.load(this.#t,38),immediate:Atomics.load(this.#t,39),nearFuture:Atomics.load(this.#t,40),late:Atomics.load(this.#t,41),bypassed:Atomics.load(this.#t,22)}:{...this.#n}}#C(t,e=null,r=!0){if(this.#s==="postMessage")return this.#r?(this.#r.postMessage({type:"osc",oscData:t,bypassCategory:e,sourceId:this.#E}),!0):!1;{let n=this.#f,o=N({atomicView:this.#u.atomicView,dataView:this.#u.dataView,uint8View:this.#u.uint8View,bufferConstants:this.#o.bufferConstants,ringBufferBase:this.#o.ringBufferBase,controlIndices:this.#o.controlIndices,oscMessage:t,sourceId:this.#E,maxSpins:n?10:0,useWait:n});return!o&&!n&&r&&this.#e?(this.#t&&Atomics.add(this.#t,45,1),this.#e.postMessage({type:"directDispatch",oscData:t,sourceId:this.#E}),!0):o}}#N(t){return this.#e?(this.#e.postMessage({type:"osc",oscData:t,sourceId:this.#E}),!0):(console.error("[OscChannel] No prescheduler port, sending direct"),this.#C(t))}send(t){let e=this.classify(t);if(L(e)){let r=this.#C(t,e);return r&&this.#U(t.length,e),r}else{let r=this.#N(t);return r&&this.#U(t.length,null),r}}sendDirect(t){return this.#C(t)}sendToPrescheduler(t){return this.#N(t)}nextNodeId(){if(this.#l)return Atomics.add(this.#l,0,1);this.#_>=this.#T&&this.#R();let t=this.#_++;return this.#S&&!this.#i&&this.#T-this.#_<=this.#a>>>1&&this.#h(),t}#R(){if(this.#c){let t=this.#c(this.#a);this.#p=t.from,this.#T=t.to,this.#_=t.from}else this.#i?(this.#p=this.#i.from,this.#T=this.#i.to,this.#_=this.#i.from,this.#i=null,this.#h()):this.#S&&(console.warn("[OscChannel] nextNodeId() range exhausted before async refill arrived. IDs may not be unique. Yield to the event loop between large batches of nextNodeId() calls."),this.#h())}#h(){this.#S&&this.#S.postMessage({type:"requestNodeIdRange"})}set getCurrentNTP(t){this.#d=t}get mode(){return this.#s}get transferable(){let t={mode:this.#s,preschedulerPort:this.#e,bypassLookaheadS:this.#I,sourceId:this.#E,blocking:this.#f};if(this.#s==="postMessage"){let e=this.#a*10,r,n;if(this.#c){let o=this.#c(e);r={from:o.from,to:o.to};let E=new MessageChannel,c=this.#c,i=this.#a;E.port1.onmessage=S=>{if(S.data.type==="requestNodeIdRange"){let a=c(i);E.port1.postMessage({type:"nodeIdRange",from:a.from,to:a.to})}},n=E.port2,this.#A=n}return{...t,port:this.#r,nodeIdRange:r,nodeIdPort:n}}else return{...t,sharedBuffer:this.#o.sharedBuffer,ringBufferBase:this.#o.ringBufferBase,bufferConstants:this.#o.bufferConstants,controlIndices:this.#o.controlIndices}}get transferList(){let t=[];return this.#s==="postMessage"&&this.#r&&t.push(this.#r),this.#e&&t.push(this.#e),this.#A&&(t.push(this.#A),this.#A=null),t}close(){this.#s==="postMessage"&&this.#r&&(this.#r.close(),this.#r=null),this.#e&&(this.#e.close(),this.#e=null)}static createPostMessage(t){return t instanceof MessagePort?new s("postMessage",{port:t}):new s("postMessage",t)}static createSAB(t){let e=t.controlIndices;return e||(e=B(t.ringBufferBase,t.bufferConstants.CONTROL_START)),new s("sab",{sharedBuffer:t.sharedBuffer,ringBufferBase:t.ringBufferBase,bufferConstants:t.bufferConstants,controlIndices:e,preschedulerPort:t.preschedulerPort,bypassLookaheadS:t.bypassLookaheadS,sourceId:t.sourceId,blocking:t.blocking})}static fromTransferable(t){return t.mode==="postMessage"?new s("postMessage",{port:t.port,preschedulerPort:t.preschedulerPort,bypassLookaheadS:t.bypassLookaheadS,sourceId:t.sourceId,blocking:t.blocking,nodeIdRange:t.nodeIdRange,nodeIdPort:t.nodeIdPort}):new s("sab",{sharedBuffer:t.sharedBuffer,ringBufferBase:t.ringBufferBase,bufferConstants:t.bufferConstants,controlIndices:t.controlIndices,preschedulerPort:t.preschedulerPort,bypassLookaheadS:t.bypassLookaheadS,sourceId:t.sourceId,blocking:t.blocking})}};export{R as OscChannel};
|
package/dist/osc_fast.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var B=new Uint8Array(2097152),O=new DataView(B.buffer),l=B,c=O,a=new Map,z=1e3,W=new TextDecoder,X=new TextEncoder,U=[null,0],j=2208988800,b=4294967296,F=new Uint8Array([35,98,117,110,100,108,101,0]),G=44,T=105,d=102,g=115,E=98,k=84,_=70,D=104,P=100,L=116,M=117;function y(e,t,n=0){let i=e.length+4;i+=t.length-n+4;for(let r=n;r<t.length;r++){let f=t[r];if(f instanceof Uint8Array)i+=4+f.length+3;else if(f instanceof ArrayBuffer)i+=4+f.byteLength+3;else if(typeof f=="string")i+=f.length*3+4;else if(f&&f.type==="string")i+=f.value.length*3+4;else if(f&&f.type==="blob"){let u=f.value,s=u instanceof Uint8Array?u.length:u.byteLength;i+=4+s+3}else f&&f.type==="uuid"?i+=16:i+=8}return i}function N(e){let t=16;for(let n of e)t+=4,Array.isArray(n)?t+=y(n[0],n,1):n.packets!==void 0?t+=N(n.packets):t+=y(n.address,n.args||[]);return t}function I(e){if(e<=2097152){l=B,c=O;return}l=new Uint8Array(e),c=new DataView(l.buffer)}function p(e,t=[]){let n=y(e,t);I(n);let i=0;i=v(e,i),i=m(t,i);for(let r=0;r<t.length;r++)i=w(t[r],i);return l.subarray(0,i)}function ee(e,t){let n=N(t);I(n);let i=0;l.set(F,i),i+=8,i=A(e,i);for(let r=0;r<t.length;r++){let f=t[r],u=i;i+=4;let s=i;Array.isArray(f)?i=h(f[0],f,i,1):f.packets!==void 0?i=V(f.timeTag,f.packets,i):i=h(f.address,f.args||[],i);let o=i-s;c.setUint32(u,o,!1)}return l.subarray(0,i)}function te(e,t,n=[]){let i=20+y(t,n);I(i);let r=0;l.set(F,r),r+=8,r=A(e,r);let f=r;r+=4;let u=r;r=v(t,r),r=m(n,r);for(let s=0;s<n.length;s++)r=w(n[s],r);return c.setUint32(f,r-u,!1),l.subarray(0,r)}function h(e,t,n,i=0){n=v(e,n),n=m(t,n,i);for(let r=i;r<t.length;r++)n=w(t[r],n);return n}function V(e,t,n){l.set(F,n),n+=8,n=A(e,n);for(let i=0;i<t.length;i++){let r=t[i],f=n;n+=4;let u=n;Array.isArray(r)?n=h(r[0],r,n,1):r.packets!==void 0?n=V(r.timeTag,r.packets,n):n=h(r.address,r.args||[],n),c.setUint32(f,n-u,!1)}return n}function v(e,t){let n=a.get(e);if(n)return l.set(n,t),t+n.length;let i=t;if(t=S(e,t),a.size<z){let r=l.slice(i,t);a.set(e,r)}return t}function S(e,t){let n=!1;for(let i=0;i<e.length;i++)if(e.charCodeAt(i)>=128){n=!0;break}if(n){let i=X.encodeInto(e,l.subarray(t));t+=i.written}else for(let i=0;i<e.length;i++)l[t++]=e.charCodeAt(i);for(l[t++]=0;t&3;)l[t++]=0;return t}function m(e,t,n=0){l[t++]=G;for(let i=n;i<e.length;i++){let r=e[i],f=typeof r;if(f==="number")l[t++]=Number.isInteger(r)?T:d;else if(f==="string")l[t++]=g;else if(f==="boolean")l[t++]=r?k:_;else if(r instanceof Uint8Array||r instanceof ArrayBuffer)l[t++]=E;else if(r&&r.type==="int")l[t++]=T;else if(r&&r.type==="float")l[t++]=d;else if(r&&r.type==="string")l[t++]=g;else if(r&&r.type==="blob")l[t++]=E;else if(r&&r.type==="bool")l[t++]=r.value?k:_;else if(r&&r.type==="int64")l[t++]=D;else if(r&&r.type==="double")l[t++]=P;else if(r&&r.type==="timetag")l[t++]=L;else if(r&&r.type==="uuid")l[t++]=M;else throw r==null?new Error(`OSC argument at index ${i} is ${r}`):new Error(`Unknown OSC argument type at index ${i}: ${f}`)}for(l[t++]=0;t&3;)l[t++]=0;return t}function w(e,t){let n=typeof e;if(n==="number")return Number.isInteger(e)?(c.setInt32(t,e,!1),t+4):(c.setFloat32(t,e,!1),t+4);if(n==="string")return S(e,t);if(n==="boolean")return t;if(e instanceof Uint8Array){let i=e.length;for(c.setUint32(t,i,!1),t+=4,l.set(e,t),t+=i;t&3;)l[t++]=0;return t}if(e instanceof ArrayBuffer)return w(new Uint8Array(e),t);if(e&&e.type==="int")return c.setInt32(t,e.value,!1),t+4;if(e&&e.type==="float")return c.setFloat32(t,e.value,!1),t+4;if(e&&e.type==="string")return S(e.value,t);if(e&&e.type==="blob"){let i=e.value instanceof Uint8Array?e.value:new Uint8Array(e.value),r=i.length;for(c.setUint32(t,r,!1),t+=4,l.set(i,t),t+=r;t&3;)l[t++]=0;return t}return e&&e.type==="bool"?t:e&&e.type==="int64"?(c.setBigInt64(t,BigInt(e.value),!1),t+8):e&&e.type==="double"?(c.setFloat64(t,e.value,!1),t+8):e&&e.type==="timetag"?A(e.value,t):e&&e.type==="uuid"?(l.set(e.value,t),t+16):t}function A(e,t){if(e===1||e===null||e===void 0)return c.setUint32(t,0,!1),c.setUint32(t+4,1,!1),t+8;if(Array.isArray(e)){if(e.length!==2)throw new Error(`TimeTag array must have exactly 2 elements [seconds, fraction], got ${e.length}`);return c.setUint32(t,e[0]>>>0,!1),c.setUint32(t+4,e[1]>>>0,!1),t+8}if(typeof e!="number")throw new TypeError(`TimeTag must be a number, array, null, or undefined, got ${typeof e}`);e>1&&e<j&&console.warn(`TimeTag ${e} looks like a Unix timestamp (< NTP_EPOCH_OFFSET). Did you mean to add NTP_EPOCH_OFFSET (2208988800)?`);let n=e>>>0,i=(e-Math.floor(e))*b>>>0;return c.setUint32(t,n,!1),c.setUint32(t+4,i,!1),t+8}function q(e){return e instanceof Uint8Array||(e=new Uint8Array(e)),e[0]===35&&e[1]===98?K(e):J(e)}function J(e){e instanceof Uint8Array||(e=new Uint8Array(e));let t=new DataView(e.buffer,e.byteOffset,e.byteLength),n=0,[i,r]=x(e,n);if(n=r,n>=e.length||e[n]!==G)return[i];let[f,u]=x(e,n);n=u;let s=[i];for(let o=1;o<f.length;o++)switch(f.charCodeAt(o)){case T:s.push(t.getInt32(n,!1)),n+=4;break;case d:s.push(t.getFloat32(n,!1)),n+=4;break;case g:let[R,$]=x(e,n);s.push(R),n=$;break;case E:let C=t.getUint32(n,!1);n+=4,s.push(e.slice(n,n+C)),n+=C,n=n+3&-4;break;case D:s.push(t.getBigInt64(n,!1)),n+=8;break;case P:s.push(t.getFloat64(n,!1)),n+=8;break;case k:s.push(!0);break;case _:s.push(!1);break;case L:let H=t.getUint32(n,!1),Z=t.getUint32(n+4,!1);s.push(H+Z/b),n+=8;break;case M:s.push({type:"uuid",value:e.slice(n,n+16)}),n+=16;break}return s}function K(e){e instanceof Uint8Array||(e=new Uint8Array(e));let t=new DataView(e.buffer,e.byteOffset,e.byteLength),n=8,i=t.getUint32(n,!1),r=t.getUint32(n+4,!1),f=i+r/b;n+=8;let u=[];for(;n<e.length;){let s=t.getUint32(n,!1);if(n+=4,s>0&&n+s<=e.length){let o=e.subarray(n,n+s);u.push(q(o))}n+=s}return{timeTag:f,packets:u}}function x(e,t){let n=t;for(;n<e.length&&e[n]!==0;)n++;let i=W.decode(e.subarray(t,n));return n++,n=n+3&-4,U[0]=i,U[1]=n,U}function ne(e){return e.slice()}function ie(){a.clear()}function re(){return{stringCacheSize:a.size,maxSize:z}}function Q(e){return!e||e.length<8?!1:e[0]===35&&e[1]===98}function fe(e){if(!Q(e))return null;let t=new DataView(e.buffer,e.byteOffset,e.byteLength),n=t.getUint32(8,!1),i=t.getUint32(12,!1);return n+i/b}export{j as NTP_EPOCH_OFFSET,b as TWO_POW_32,ie as clearCache,ne as copyEncoded,K as decodeBundle,J as decodeMessage,q as decodePacket,ee as encodeBundle,p as encodeMessage,te as encodeSingleBundle,fe as getBundleTimeTag,re as getCacheStats,Q as isBundle};
|