supersonic-scsynth 0.4.0 → 0.6.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/dist/supersonic.js +903 -483
- package/dist/wasm/manifest.json +3 -3
- package/dist/wasm/scsynth-nrt.wasm +0 -0
- package/dist/workers/debug_worker.js +20 -26
- package/dist/workers/osc_in_worker.js +27 -31
- package/dist/workers/osc_out_prescheduler_worker.js +86 -91
- package/dist/workers/scsynth_audio_worklet.js +46 -55
- package/package.json +1 -1
|
@@ -143,6 +143,38 @@ class ScsynthProcessor extends AudioWorkletProcessor {
|
|
|
143
143
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
// Write worldOptions to SharedArrayBuffer for C++ to read
|
|
147
|
+
// WorldOptions are written after ring buffer storage (65536 bytes)
|
|
148
|
+
writeWorldOptionsToMemory() {
|
|
149
|
+
if (!this.worldOptions || !this.wasmMemory) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// WorldOptions location: ringBufferBase + 65536 (after ring_buffer_storage)
|
|
154
|
+
const WORLD_OPTIONS_OFFSET = this.ringBufferBase + 65536;
|
|
155
|
+
const uint32View = new Uint32Array(this.wasmMemory.buffer, WORLD_OPTIONS_OFFSET, 32);
|
|
156
|
+
const float32View = new Float32Array(this.wasmMemory.buffer, WORLD_OPTIONS_OFFSET, 32);
|
|
157
|
+
|
|
158
|
+
// Write worldOptions as uint32/float32 values
|
|
159
|
+
// Order must match C++ reading code in audio_processor.cpp
|
|
160
|
+
uint32View[0] = this.worldOptions.numBuffers || 1024;
|
|
161
|
+
uint32View[1] = this.worldOptions.maxNodes || 1024;
|
|
162
|
+
uint32View[2] = this.worldOptions.maxGraphDefs || 1024;
|
|
163
|
+
uint32View[3] = this.worldOptions.maxWireBufs || 64;
|
|
164
|
+
uint32View[4] = this.worldOptions.numAudioBusChannels || 128;
|
|
165
|
+
uint32View[5] = this.worldOptions.numInputBusChannels || 0;
|
|
166
|
+
uint32View[6] = this.worldOptions.numOutputBusChannels || 2;
|
|
167
|
+
uint32View[7] = this.worldOptions.numControlBusChannels || 4096;
|
|
168
|
+
uint32View[8] = this.worldOptions.bufLength || 128;
|
|
169
|
+
uint32View[9] = this.worldOptions.realTimeMemorySize || 16384;
|
|
170
|
+
uint32View[10] = this.worldOptions.numRGens || 64;
|
|
171
|
+
uint32View[11] = this.worldOptions.realTime ? 1 : 0;
|
|
172
|
+
uint32View[12] = this.worldOptions.memoryLocking ? 1 : 0;
|
|
173
|
+
uint32View[13] = this.worldOptions.loadGraphDefs || 0;
|
|
174
|
+
uint32View[14] = this.worldOptions.preferredSampleRate || 0;
|
|
175
|
+
uint32View[15] = this.worldOptions.verbosity || 0;
|
|
176
|
+
}
|
|
177
|
+
|
|
146
178
|
// Write debug message to SharedArrayBuffer DEBUG ring buffer
|
|
147
179
|
js_debug(message) {
|
|
148
180
|
if (!this.uint8View || !this.atomicView || !this.CONTROL_INDICES || !this.ringBufferBase) {
|
|
@@ -217,6 +249,10 @@ class ScsynthProcessor extends AudioWorkletProcessor {
|
|
|
217
249
|
// Save memory reference for later use (WASM imports memory, doesn't export it)
|
|
218
250
|
this.wasmMemory = memory;
|
|
219
251
|
|
|
252
|
+
// Store worldOptions and sampleRate for C++ initialization
|
|
253
|
+
this.worldOptions = data.worldOptions || {};
|
|
254
|
+
this.sampleRate = data.sampleRate || 48000; // Fallback to 48000 if not provided
|
|
255
|
+
|
|
220
256
|
// Import object for WASM
|
|
221
257
|
// scsynth with pthread support requires these imports
|
|
222
258
|
// (pthread stubs are no-ops - AudioWorklet is single-threaded)
|
|
@@ -271,9 +307,13 @@ class ScsynthProcessor extends AudioWorkletProcessor {
|
|
|
271
307
|
|
|
272
308
|
this.calculateBufferIndices(this.ringBufferBase);
|
|
273
309
|
|
|
310
|
+
// Write worldOptions to SharedArrayBuffer for C++ to read
|
|
311
|
+
this.writeWorldOptionsToMemory();
|
|
312
|
+
|
|
274
313
|
// Initialize WASM memory
|
|
275
314
|
if (this.wasmInstance.exports.init_memory) {
|
|
276
|
-
|
|
315
|
+
// Pass actual sample rate from AudioContext (not hardcoded!)
|
|
316
|
+
this.wasmInstance.exports.init_memory(this.sampleRate);
|
|
277
317
|
|
|
278
318
|
this.isInitialized = true;
|
|
279
319
|
|
|
@@ -299,9 +339,13 @@ class ScsynthProcessor extends AudioWorkletProcessor {
|
|
|
299
339
|
|
|
300
340
|
this.calculateBufferIndices(this.ringBufferBase);
|
|
301
341
|
|
|
342
|
+
// Write worldOptions to SharedArrayBuffer for C++ to read
|
|
343
|
+
this.writeWorldOptionsToMemory();
|
|
344
|
+
|
|
302
345
|
// Initialize WASM memory
|
|
303
346
|
if (this.wasmInstance.exports.init_memory) {
|
|
304
|
-
|
|
347
|
+
// Pass actual sample rate from AudioContext (not hardcoded!)
|
|
348
|
+
this.wasmInstance.exports.init_memory(this.sampleRate);
|
|
305
349
|
|
|
306
350
|
this.isInitialized = true;
|
|
307
351
|
|
|
@@ -317,59 +361,6 @@ class ScsynthProcessor extends AudioWorkletProcessor {
|
|
|
317
361
|
}
|
|
318
362
|
}
|
|
319
363
|
|
|
320
|
-
if (data.type === 'getMetrics') {
|
|
321
|
-
// Return current metrics (only if initialized)
|
|
322
|
-
if (this.atomicView && this.METRICS_INDICES && this.CONTROL_INDICES && this.bufferConstants) {
|
|
323
|
-
// Calculate buffer usage percentages (use constants from WASM)
|
|
324
|
-
const IN_BUFFER_SIZE = this.bufferConstants.IN_BUFFER_SIZE;
|
|
325
|
-
const OUT_BUFFER_SIZE = this.bufferConstants.OUT_BUFFER_SIZE;
|
|
326
|
-
const DEBUG_BUFFER_SIZE = this.bufferConstants.DEBUG_BUFFER_SIZE;
|
|
327
|
-
|
|
328
|
-
const inHead = Atomics.load(this.atomicView, this.CONTROL_INDICES.IN_HEAD);
|
|
329
|
-
const inTail = Atomics.load(this.atomicView, this.CONTROL_INDICES.IN_TAIL);
|
|
330
|
-
const inUsed = (inHead - inTail + IN_BUFFER_SIZE) % IN_BUFFER_SIZE;
|
|
331
|
-
const inPercentage = Math.round((inUsed / IN_BUFFER_SIZE) * 100);
|
|
332
|
-
|
|
333
|
-
const outHead = Atomics.load(this.atomicView, this.CONTROL_INDICES.OUT_HEAD);
|
|
334
|
-
const outTail = Atomics.load(this.atomicView, this.CONTROL_INDICES.OUT_TAIL);
|
|
335
|
-
const outUsed = (outHead - outTail + OUT_BUFFER_SIZE) % OUT_BUFFER_SIZE;
|
|
336
|
-
const outPercentage = Math.round((outUsed / OUT_BUFFER_SIZE) * 100);
|
|
337
|
-
|
|
338
|
-
const debugHead = Atomics.load(this.atomicView, this.CONTROL_INDICES.DEBUG_HEAD);
|
|
339
|
-
const debugTail = Atomics.load(this.atomicView, this.CONTROL_INDICES.DEBUG_TAIL);
|
|
340
|
-
const debugUsed = (debugHead - debugTail + DEBUG_BUFFER_SIZE) % DEBUG_BUFFER_SIZE;
|
|
341
|
-
const debugPercentage = Math.round((debugUsed / DEBUG_BUFFER_SIZE) * 100);
|
|
342
|
-
|
|
343
|
-
const metrics = {
|
|
344
|
-
processCount: Atomics.load(this.atomicView, this.METRICS_INDICES.PROCESS_COUNT),
|
|
345
|
-
bufferOverruns: Atomics.load(this.atomicView, this.METRICS_INDICES.BUFFER_OVERRUNS),
|
|
346
|
-
messagesProcessed: Atomics.load(this.atomicView, this.METRICS_INDICES.MESSAGES_PROCESSED),
|
|
347
|
-
messagesDropped: Atomics.load(this.atomicView, this.METRICS_INDICES.MESSAGES_DROPPED),
|
|
348
|
-
schedulerQueueDepth: Atomics.load(this.atomicView, this.METRICS_INDICES.SCHEDULER_QUEUE_DEPTH),
|
|
349
|
-
schedulerQueueMax: Atomics.load(this.atomicView, this.METRICS_INDICES.SCHEDULER_QUEUE_MAX),
|
|
350
|
-
schedulerQueueDropped: Atomics.load(this.atomicView, this.METRICS_INDICES.SCHEDULER_QUEUE_DROPPED),
|
|
351
|
-
statusFlags: Atomics.load(this.atomicView, this.CONTROL_INDICES.STATUS_FLAGS),
|
|
352
|
-
inBufferUsed: {
|
|
353
|
-
bytes: inUsed,
|
|
354
|
-
percentage: inPercentage
|
|
355
|
-
},
|
|
356
|
-
outBufferUsed: {
|
|
357
|
-
bytes: outUsed,
|
|
358
|
-
percentage: outPercentage
|
|
359
|
-
},
|
|
360
|
-
debugBufferUsed: {
|
|
361
|
-
bytes: debugUsed,
|
|
362
|
-
percentage: debugPercentage
|
|
363
|
-
}
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
this.port.postMessage({
|
|
367
|
-
type: 'metrics',
|
|
368
|
-
metrics: metrics
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
364
|
if (data.type === 'getVersion') {
|
|
374
365
|
// Return Supersonic/SuperCollider version string
|
|
375
366
|
if (this.wasmInstance && this.wasmInstance.exports.get_supersonic_version_string) {
|
package/package.json
CHANGED