@libraz/libsonare 1.3.0 → 1.3.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/index.js CHANGED
@@ -2354,9 +2354,11 @@ var Audio = class _Audio {
2354
2354
 
2355
2355
  // src/live_audio.ts
2356
2356
  async function bindMicrophoneInput(context, engine, options = {}) {
2357
- const stream = options.stream ?? await navigator.mediaDevices.getUserMedia({
2358
- audio: options.audio ?? true,
2359
- video: false
2357
+ const { stream: providedStream, stopTracksOnClose = true, ...constraints } = options;
2358
+ const stream = providedStream ?? await navigator.mediaDevices.getUserMedia({
2359
+ ...constraints,
2360
+ audio: constraints.audio ?? true,
2361
+ video: constraints.video ?? false
2360
2362
  });
2361
2363
  const source = context.createMediaStreamSource(stream);
2362
2364
  const node = "node" in engine ? engine.node : engine;
@@ -2371,7 +2373,7 @@ async function bindMicrophoneInput(context, engine, options = {}) {
2371
2373
  }
2372
2374
  closed = true;
2373
2375
  source.disconnect();
2374
- if (options.stopTracksOnClose !== false) {
2376
+ if (stopTracksOnClose) {
2375
2377
  for (const track of stream.getAudioTracks()) {
2376
2378
  track.stop();
2377
2379
  }
@@ -2527,12 +2529,22 @@ self.onmessage = async (event) => {
2527
2529
  const frames = Math.min(pageFrames, numSamples - startFrame);
2528
2530
  const frameBytes = numChannels * 4;
2529
2531
  const bytes = new Uint8Array(frames * frameBytes);
2530
- const bytesRead = access.read(bytes, { at: dataOffsetBytes + startFrame * frameBytes });
2531
- const framesRead = Math.floor(bytesRead / frameBytes);
2532
- if (framesRead <= 0) {
2532
+ let bytesReadTotal = 0;
2533
+ const readOffset = dataOffsetBytes + startFrame * frameBytes;
2534
+ while (bytesReadTotal < bytes.byteLength) {
2535
+ const bytesRead = access.read(bytes.subarray(bytesReadTotal), {
2536
+ at: readOffset + bytesReadTotal,
2537
+ });
2538
+ if (bytesRead <= 0) {
2539
+ break;
2540
+ }
2541
+ bytesReadTotal += bytesRead;
2542
+ }
2543
+ if (bytesReadTotal !== bytes.byteLength || bytesReadTotal % frameBytes !== 0) {
2533
2544
  self.postMessage({ type: 'sonare:clip-page', requestId, pageIndex, ok: false });
2534
2545
  return;
2535
2546
  }
2547
+ const framesRead = bytesReadTotal / frameBytes;
2536
2548
  const view = new DataView(bytes.buffer, 0, framesRead * frameBytes);
2537
2549
  const channelBuffers = Array.from({ length: numChannels }, () => new ArrayBuffer(framesRead * 4));
2538
2550
  for (let ch = 0; ch < numChannels; ++ch) {
@@ -2598,7 +2610,12 @@ function createOpfsClipPageProvider(engine, options) {
2598
2610
  entry.resolve(false);
2599
2611
  return;
2600
2612
  }
2601
- provider.supply(response.pageIndex, channels);
2613
+ try {
2614
+ provider.supply(response.pageIndex, channels);
2615
+ } catch {
2616
+ entry.resolve(false);
2617
+ return;
2618
+ }
2602
2619
  entry.resolve(true);
2603
2620
  };
2604
2621
  worker.addEventListener("message", onMessage);
@@ -3964,15 +3981,15 @@ function isWebMidiAvailable() {
3964
3981
  return typeof globalThis.navigator?.requestMIDIAccess === "function";
3965
3982
  }
3966
3983
  async function bindWebMidi(engine, options = {}) {
3967
- const requestMIDIAccess = globalThis.navigator?.requestMIDIAccess;
3968
- if (typeof requestMIDIAccess !== "function") {
3984
+ const navigatorWithMidi = globalThis.navigator;
3985
+ if (typeof navigatorWithMidi?.requestMIDIAccess !== "function") {
3969
3986
  throw new Error("Web MIDI is not available in this environment");
3970
3987
  }
3971
3988
  const group = options.group ?? 0;
3972
3989
  assertNibble("bindWebMidi", group, "group");
3973
3990
  const destinationId = options.destinationId ?? 0;
3974
3991
  const selectedIds = new Set(options.inputIds ?? []);
3975
- const access = await requestMIDIAccess({
3992
+ const access = await navigatorWithMidi.requestMIDIAccess({
3976
3993
  sysex: options.sysex ?? false,
3977
3994
  software: options.software ?? true
3978
3995
  });
@@ -4003,9 +4020,7 @@ async function bindWebMidi(engine, options = {}) {
4003
4020
  runningStatus,
4004
4021
  options.timestampToSamples
4005
4022
  );
4006
- if (status !== 0) {
4007
- runningStatus = status;
4008
- }
4023
+ runningStatus = status;
4009
4024
  };
4010
4025
  if (input.addEventListener) {
4011
4026
  input.addEventListener("midimessage", listener);
@@ -4103,18 +4118,18 @@ function dispatchMidiMessage(engine, event, group, runningStatus, timestampToSam
4103
4118
  const message = status & 240;
4104
4119
  const channel = status & 15;
4105
4120
  if (message < 128 || message > 224) {
4106
- return status;
4121
+ return status >= 248 ? runningStatus : 0;
4107
4122
  }
4108
4123
  const a = readU7(data, offset);
4109
4124
  const b = readU7(data, offset + 1);
4110
- if (a < 0) {
4125
+ if (a < 0 || b < 0) {
4111
4126
  return status;
4112
4127
  }
4113
4128
  const portTimeSamples = timestampToSamples ? timestampToSamples(event.receivedTime ?? event.timeStamp ?? 0) : 0;
4114
4129
  if (message === 128) {
4115
- engine.pushMidiInputNoteOff(group, channel, a, b < 0 ? 0 : b, portTimeSamples);
4130
+ engine.pushMidiInputNoteOff(group, channel, a, b, portTimeSamples);
4116
4131
  } else if (message === 144) {
4117
- if ((b < 0 ? 0 : b) === 0) {
4132
+ if (b === 0) {
4118
4133
  engine.pushMidiInputNoteOff(group, channel, a, 0, portTimeSamples);
4119
4134
  } else {
4120
4135
  engine.pushMidiInputNoteOn(group, channel, a, b, portTimeSamples);