@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 +33 -18
- package/dist/index.js.map +1 -1
- package/dist/sonare-rt.wasm +0 -0
- package/dist/sonare.wasm +0 -0
- package/dist/worklet.d.ts +1 -1
- package/package.json +1 -1
- package/src/live_audio.ts +6 -4
- package/src/opfs_clip_pages.ts +19 -4
- package/src/web_midi.ts +10 -11
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 =
|
|
2358
|
-
|
|
2359
|
-
|
|
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 (
|
|
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
|
-
|
|
2531
|
-
const
|
|
2532
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
4130
|
+
engine.pushMidiInputNoteOff(group, channel, a, b, portTimeSamples);
|
|
4116
4131
|
} else if (message === 144) {
|
|
4117
|
-
if (
|
|
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);
|