@onda-lang/webaudio 0.7.3 → 0.7.5

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/worklet.js +44 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onda-lang/webaudio",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "type": "module",
5
5
  "description": "Optional Web Audio adapter for Onda processor WebAssembly artifacts",
6
6
  "license": "MIT",
@@ -32,7 +32,7 @@
32
32
  "test": "node --test"
33
33
  },
34
34
  "dependencies": {
35
- "@onda-lang/processor-abi": "0.7.3"
35
+ "@onda-lang/processor-abi": "0.7.5"
36
36
  },
37
37
  "publishConfig": {
38
38
  "access": "public"
package/src/worklet.js CHANGED
@@ -403,9 +403,53 @@ class OndaWasmProcessor extends AudioWorkletProcessor {
403
403
  snapshot.subarray(packedOffset, packedOffset + byteSize),
404
404
  physicalOffset,
405
405
  );
406
+ this.normalizeSnapshotIntegerRange(entry, state, physicalOffset, byteSize);
406
407
  }
407
408
  }
408
409
 
410
+ normalizeSnapshotIntegerRange(entry, state, offset, byteSize) {
411
+ const range = entry.integer_range;
412
+ if (range === null || range === undefined) return;
413
+ if (entry.array_len !== 1 || (entry.scalar !== "i32" && entry.scalar !== "i64")) {
414
+ throw new Error(`state '${String(entry.name)}' has an invalid integer range`);
415
+ }
416
+ const mode = range.mode;
417
+ if (mode !== "clamp" && mode !== "wrap") {
418
+ throw new Error(`state '${String(entry.name)}' has an invalid integer range mode`);
419
+ }
420
+ const view = new DataView(state.buffer, state.byteOffset + offset, byteSize);
421
+ if (entry.scalar === "i32") {
422
+ const min = Number(range.min?.value);
423
+ const max = Number(range.max?.value);
424
+ if (!Number.isInteger(min) || !Number.isInteger(max) || min > max || byteSize !== 4) {
425
+ throw new Error(`state '${String(entry.name)}' has invalid i32 range bounds`);
426
+ }
427
+ const value = view.getInt32(0, true);
428
+ const normalized = mode === "clamp"
429
+ ? Math.min(Math.max(value, min), max)
430
+ : min + (((value - min) % (max - min + 1)) + (max - min + 1)) % (max - min + 1);
431
+ view.setInt32(0, normalized, true);
432
+ return;
433
+ }
434
+ let min;
435
+ let max;
436
+ try {
437
+ min = BigInt(range.min?.value);
438
+ max = BigInt(range.max?.value);
439
+ } catch {
440
+ throw new Error(`state '${String(entry.name)}' has invalid i64 range bounds`);
441
+ }
442
+ if (min > max || byteSize !== 8) {
443
+ throw new Error(`state '${String(entry.name)}' has invalid i64 range bounds`);
444
+ }
445
+ const value = view.getBigInt64(0, true);
446
+ const width = max - min + 1n;
447
+ const normalized = mode === "clamp"
448
+ ? (value < min ? min : (value > max ? max : value))
449
+ : min + ((value - min) % width + width) % width;
450
+ view.setBigInt64(0, normalized, true);
451
+ }
452
+
409
453
  snapshotBytes(value) {
410
454
  if (value instanceof Uint8Array) return value;
411
455
  if (value instanceof ArrayBuffer) return new Uint8Array(value);