@opendaw/studio-core 0.0.36 → 0.0.38
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/AudioOfflineRenderer.d.ts.map +1 -1
- package/dist/AudioOfflineRenderer.js +4 -1
- package/dist/AudioWorklets.d.ts +6 -2
- package/dist/AudioWorklets.d.ts.map +1 -1
- package/dist/AudioWorklets.js +2 -2
- package/dist/Engine.d.ts +2 -1
- package/dist/Engine.d.ts.map +1 -1
- package/dist/EngineFacade.d.ts +1 -0
- package/dist/EngineFacade.d.ts.map +1 -1
- package/dist/EngineFacade.js +3 -1
- package/dist/EngineWorklet.d.ts +3 -2
- package/dist/EngineWorklet.d.ts.map +1 -1
- package/dist/EngineWorklet.js +12 -4
- package/dist/FilePickerAcceptTypes.d.ts +1 -0
- package/dist/FilePickerAcceptTypes.d.ts.map +1 -1
- package/dist/FilePickerAcceptTypes.js +4 -0
- package/dist/RecordingWorklet.d.ts.map +1 -1
- package/dist/RecordingWorklet.js +12 -5
- package/dist/capture/CaptureMidi.js +12 -12
- package/dist/capture/RecordAudio.d.ts +2 -2
- package/dist/capture/RecordAudio.d.ts.map +1 -1
- package/dist/clouds/CloudAuthManager.d.ts.map +1 -1
- package/dist/clouds/CloudAuthManager.js +10 -2
- package/dist/clouds/CloudBackup.d.ts +1 -1
- package/dist/clouds/CloudBackup.d.ts.map +1 -1
- package/dist/clouds/CloudBackup.js +41 -1
- package/dist/clouds/CloudBackupSamples.d.ts.map +1 -1
- package/dist/clouds/CloudBackupSamples.js +6 -1
- package/dist/index.d.ts +2 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -7
- package/dist/midi/MIDIMessageSubscriber.js +4 -4
- package/dist/midi/MidiDevices.d.ts +6 -2
- package/dist/midi/MidiDevices.d.ts.map +1 -1
- package/dist/midi/MidiDevices.js +11 -2
- package/dist/midi/SoftwareMIDIInput.d.ts +27 -0
- package/dist/midi/SoftwareMIDIInput.d.ts.map +1 -0
- package/dist/midi/SoftwareMIDIInput.js +42 -0
- package/dist/processors.js +3 -3
- package/dist/processors.js.map +4 -4
- package/dist/project/Project.d.ts +5 -4
- package/dist/project/Project.d.ts.map +1 -1
- package/dist/project/Project.js +21 -5
- package/dist/project/ProjectBundle.d.ts.map +1 -1
- package/dist/project/ProjectBundle.js +1 -1
- package/dist/project/ProjectEnv.d.ts +2 -2
- package/dist/project/ProjectEnv.d.ts.map +1 -1
- package/dist/samples/{MainThreadSampleLoader.d.ts → DefaultSampleLoader.d.ts} +4 -4
- package/dist/samples/DefaultSampleLoader.d.ts.map +1 -0
- package/dist/samples/{MainThreadSampleLoader.js → DefaultSampleLoader.js} +7 -2
- package/dist/samples/{MainThreadSampleManager.d.ts → DefaultSampleLoaderManager.d.ts} +4 -5
- package/dist/samples/DefaultSampleLoaderManager.d.ts.map +1 -0
- package/dist/samples/DefaultSampleLoaderManager.js +19 -0
- package/dist/samples/OpenSampleAPI.d.ts.map +1 -1
- package/dist/samples/OpenSampleAPI.js +3 -2
- package/dist/samples/P2PSampleProvider.d.ts +13 -0
- package/dist/samples/P2PSampleProvider.d.ts.map +1 -0
- package/dist/samples/P2PSampleProvider.js +350 -0
- package/dist/samples/SampleStorage.d.ts +7 -1
- package/dist/samples/SampleStorage.d.ts.map +1 -1
- package/dist/samples/SampleStorage.js +1 -1
- package/dist/samples/index.d.ts +9 -0
- package/dist/samples/index.d.ts.map +1 -0
- package/dist/samples/index.js +8 -0
- package/dist/ui/TimelineRange.d.ts +49 -0
- package/dist/ui/TimelineRange.d.ts.map +1 -0
- package/dist/ui/TimelineRange.js +83 -0
- package/dist/workers-main.js +2 -2
- package/dist/workers-main.js.map +3 -3
- package/package.json +19 -15
- package/dist/samples/MainThreadSampleLoader.d.ts.map +0 -1
- package/dist/samples/MainThreadSampleManager.d.ts.map +0 -1
- package/dist/samples/MainThreadSampleManager.js +0 -22
@@ -3,7 +3,7 @@ import { Events } from "@opendaw/lib-dom";
|
|
3
3
|
import { MidiData } from "@opendaw/lib-midi";
|
4
4
|
export class MIDIMessageSubscriber {
|
5
5
|
static subscribeMessageEvents(access, observer, channel) {
|
6
|
-
const
|
6
|
+
const listenToMIDIMessages = (input) => isDefined(channel)
|
7
7
|
? Events.subscribe(input, "midimessage", (event) => {
|
8
8
|
if (event.data === null || MidiData.readChannel(event.data) !== channel) {
|
9
9
|
return;
|
@@ -11,7 +11,7 @@ export class MIDIMessageSubscriber {
|
|
11
11
|
observer(event);
|
12
12
|
}) : Events.subscribe(input, "midimessage", observer);
|
13
13
|
const connections = Array.from(access.inputs.values())
|
14
|
-
.map(input => ([input,
|
14
|
+
.map(input => ([input, listenToMIDIMessages(input)]));
|
15
15
|
const stateSubscription = Events.subscribe(access, "statechange", (event) => {
|
16
16
|
const port = event.port;
|
17
17
|
if (!isInstanceOf(port, MIDIInput)) {
|
@@ -19,14 +19,14 @@ export class MIDIMessageSubscriber {
|
|
19
19
|
}
|
20
20
|
for (const [input, subscription] of connections) {
|
21
21
|
if (input === port) {
|
22
|
-
// Well, this
|
22
|
+
// Well, this seems odd, but if you start listening to a midi-input initially,
|
23
23
|
// it will change its state to 'connected', so we clean up the first old subscriptions.
|
24
24
|
subscription.terminate();
|
25
25
|
break;
|
26
26
|
}
|
27
27
|
}
|
28
28
|
if (port.state === "connected") {
|
29
|
-
connections.push([port,
|
29
|
+
connections.push([port, listenToMIDIMessages(port)]);
|
30
30
|
}
|
31
31
|
});
|
32
32
|
return {
|
@@ -1,12 +1,16 @@
|
|
1
1
|
import { byte, MutableObservableValue, ObservableOption, Observer, Option, Subscription } from "@opendaw/lib-std";
|
2
|
+
import { SoftwareMIDIInput } from "./SoftwareMIDIInput";
|
2
3
|
export declare class MidiDevices {
|
3
4
|
#private;
|
4
5
|
static canRequestMidiAccess(): boolean;
|
6
|
+
static readonly softwareMIDIInput: SoftwareMIDIInput;
|
5
7
|
static requestPermission(): Promise<undefined>;
|
6
8
|
static get(): ObservableOption<MIDIAccess>;
|
7
9
|
static subscribeMessageEvents(observer: Observer<MIDIMessageEvent>, channel?: byte): Subscription;
|
8
|
-
static
|
9
|
-
static
|
10
|
+
static inputDevices(): Option<ReadonlyArray<MIDIInput>>;
|
11
|
+
static findInputDeviceById(id: string): Option<MIDIInput>;
|
12
|
+
static externalInputDevices(): Option<ReadonlyArray<MIDIInput>>;
|
13
|
+
static externalOutputDevices(): Option<ReadonlyArray<MIDIOutput>>;
|
10
14
|
static panic(): void;
|
11
15
|
static available(): MutableObservableValue<boolean>;
|
12
16
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MidiDevices.d.ts","sourceRoot":"","sources":["../../src/midi/MidiDevices.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,IAAI,EAIJ,sBAAsB,EAEtB,gBAAgB,EAEhB,QAAQ,EACR,MAAM,EACN,YAAY,EAEf,MAAM,kBAAkB,CAAA;
|
1
|
+
{"version":3,"file":"MidiDevices.d.ts","sourceRoot":"","sources":["../../src/midi/MidiDevices.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,IAAI,EAIJ,sBAAsB,EAEtB,gBAAgB,EAEhB,QAAQ,EACR,MAAM,EACN,YAAY,EAEf,MAAM,kBAAkB,CAAA;AAIzB,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAA;AAErD,qBAAa,WAAW;;IACpB,MAAM,CAAC,oBAAoB,IAAI,OAAO;IAEtC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAA0B;WAIjE,iBAAiB;IAiB9B,MAAM,CAAC,GAAG,IAAI,gBAAgB,CAAC,UAAU,CAAC;IAE1C,MAAM,CAAC,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,EAAE,IAAI,GAAG,YAAY;IAWjG,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAKvD,MAAM,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC;IAIzD,MAAM,CAAC,oBAAoB,IAAI,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAI/D,MAAM,CAAC,qBAAqB,IAAI,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAIjE,MAAM,CAAC,KAAK,IAAI,IAAI;IAkBpB,MAAM,CAAC,SAAS,IAAI,sBAAsB,CAAC,OAAO,CAAC;CAqCtD"}
|
package/dist/midi/MidiDevices.js
CHANGED
@@ -11,8 +11,10 @@ import { Errors, Lazy, MutableObservableOption, MutableObservableValue, Notifier
|
|
11
11
|
import { MidiData } from "@opendaw/lib-midi";
|
12
12
|
import { Promises } from "@opendaw/lib-runtime";
|
13
13
|
import { MIDIMessageSubscriber } from "./MIDIMessageSubscriber";
|
14
|
+
import { SoftwareMIDIInput } from "./SoftwareMIDIInput";
|
14
15
|
export class MidiDevices {
|
15
16
|
static canRequestMidiAccess() { return "requestMIDIAccess" in navigator; }
|
17
|
+
static softwareMIDIInput = new SoftwareMIDIInput();
|
16
18
|
static #memoizedRequest = Promises.memoizeAsync(() => navigator.requestMIDIAccess({ sysex: false }));
|
17
19
|
static async requestPermission() {
|
18
20
|
if (this.canRequestMidiAccess()) {
|
@@ -41,10 +43,17 @@ export class MidiDevices {
|
|
41
43
|
some: midi => MIDIMessageSubscriber.subscribeMessageEvents(midi, observer, channel)
|
42
44
|
});
|
43
45
|
}
|
44
|
-
static
|
46
|
+
static inputDevices() {
|
47
|
+
return this.externalInputDevices()
|
48
|
+
.map((inputs) => Array.from(inputs.values()).concat(this.softwareMIDIInput));
|
49
|
+
}
|
50
|
+
static findInputDeviceById(id) {
|
51
|
+
return this.inputDevices().map(inputs => inputs.find(input => input.id === id));
|
52
|
+
}
|
53
|
+
static externalInputDevices() {
|
45
54
|
return this.get().map(({ inputs }) => Array.from(inputs.values()));
|
46
55
|
}
|
47
|
-
static
|
56
|
+
static externalOutputDevices() {
|
48
57
|
return this.get().map(({ outputs }) => Array.from(outputs.values()));
|
49
58
|
}
|
50
59
|
static panic() {
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { byte, Terminable, unitValue } from "@opendaw/lib-std";
|
2
|
+
export declare class SoftwareMIDIInput implements MIDIInput, Terminable {
|
3
|
+
#private;
|
4
|
+
readonly manufacturer: string | null;
|
5
|
+
readonly connection: MIDIPortConnectionState;
|
6
|
+
readonly id: string;
|
7
|
+
readonly name: string | null;
|
8
|
+
readonly state: MIDIPortDeviceState;
|
9
|
+
readonly type: MIDIPortType;
|
10
|
+
readonly version: string | null;
|
11
|
+
onmidimessage: ((this: MIDIInput, ev: MIDIMessageEvent) => any) | null;
|
12
|
+
onstatechange: ((this: MIDIPort, ev: MIDIConnectionEvent) => any) | null;
|
13
|
+
channel: byte;
|
14
|
+
constructor();
|
15
|
+
sendNoteOnEvent(note: byte, velocity?: unitValue): void;
|
16
|
+
sendNoteOffEvent(note: byte): void;
|
17
|
+
sendMIDIMessageData(data: Uint8Array): void;
|
18
|
+
open(): Promise<MIDIPort>;
|
19
|
+
close(): Promise<MIDIPort>;
|
20
|
+
addEventListener<K extends keyof MIDIInputEventMap>(type: K, listener: (this: MIDIInput, ev: MIDIInputEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
21
|
+
addEventListener<K extends keyof MIDIPortEventMap>(type: K, listener: (this: MIDIPort, ev: MIDIPortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
22
|
+
dispatchEvent(event: MIDIMessageEvent): boolean;
|
23
|
+
removeEventListener<K extends keyof MIDIInputEventMap>(type: K, listener: (this: MIDIInput, ev: MIDIInputEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
24
|
+
removeEventListener<K extends keyof MIDIPortEventMap>(type: K, listener: (this: MIDIPort, ev: MIDIPortEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
25
|
+
terminate(): void;
|
26
|
+
}
|
27
|
+
//# sourceMappingURL=SoftwareMIDIInput.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"SoftwareMIDIInput.d.ts","sourceRoot":"","sources":["../../src/midi/SoftwareMIDIInput.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAsB,UAAU,EAAE,SAAS,EAAC,MAAM,kBAAkB,CAAA;AAGhF,qBAAa,iBAAkB,YAAW,SAAS,EAAE,UAAU;;IAC3D,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAY;IAChD,QAAQ,CAAC,UAAU,EAAE,uBAAuB,CAAS;IACrD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAwB;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAsB;IAClD,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAc;IACjD,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAU;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAU;IAIzC,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,gBAAgB,KAAK,GAAG,CAAC,GAAG,IAAI,CAAO;IAC7E,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,mBAAmB,KAAK,GAAG,CAAC,GAAG,IAAI,CAAO;IAC/E,OAAO,EAAE,IAAI,CAAI;;IAIjB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAE,SAAe,GAAG,IAAI;IAK5D,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIlC,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAK3C,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC;IACzB,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC;IAC1B,gBAAgB,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI;IAC7K,gBAAgB,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI;IAI1K,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO;IAI/C,mBAAmB,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,oBAAoB,GAAG,IAAI;IAC7K,mBAAmB,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,oBAAoB,GAAG,IAAI;IAK1K,SAAS,IAAI,IAAI;CAGpB"}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import { clamp, safeExecute } from "@opendaw/lib-std";
|
2
|
+
import { MidiData } from "@opendaw/lib-midi";
|
3
|
+
export class SoftwareMIDIInput {
|
4
|
+
manufacturer = "openDAW";
|
5
|
+
connection = "open";
|
6
|
+
id = "software-midi-input";
|
7
|
+
name = "Software Keyboard";
|
8
|
+
state = "connected";
|
9
|
+
type = "input";
|
10
|
+
version = "1.0.0";
|
11
|
+
#dispatcher;
|
12
|
+
onmidimessage = null;
|
13
|
+
onstatechange = null; // has no effect. always on.
|
14
|
+
channel = 0; // 0...16
|
15
|
+
constructor() { this.#dispatcher = new EventTarget(); }
|
16
|
+
sendNoteOnEvent(note, velocity = 1.0) {
|
17
|
+
const velocityByte = Math.round(clamp(velocity, 0, 1) * 127);
|
18
|
+
this.sendMIDIMessageData(MidiData.noteOn(this.channel, note, velocityByte));
|
19
|
+
}
|
20
|
+
sendNoteOffEvent(note) {
|
21
|
+
this.sendMIDIMessageData(MidiData.noteOff(this.channel, note));
|
22
|
+
}
|
23
|
+
sendMIDIMessageData(data) {
|
24
|
+
const eventInit = { data };
|
25
|
+
this.dispatchEvent(new MessageEvent("midimessage", eventInit));
|
26
|
+
}
|
27
|
+
open() { return Promise.resolve(this); }
|
28
|
+
close() { return Promise.resolve(this); }
|
29
|
+
addEventListener(type, listener, options) {
|
30
|
+
this.#dispatcher.addEventListener(type, listener, options);
|
31
|
+
}
|
32
|
+
dispatchEvent(event) {
|
33
|
+
safeExecute(this.onmidimessage, event);
|
34
|
+
return this.#dispatcher.dispatchEvent(event);
|
35
|
+
}
|
36
|
+
removeEventListener(type, listener, options) {
|
37
|
+
this.#dispatcher.removeEventListener(type, listener, options);
|
38
|
+
}
|
39
|
+
terminate() {
|
40
|
+
this.#dispatcher.dispatchEvent(new Event("close"));
|
41
|
+
}
|
42
|
+
}
|