@opendaw/studio-core 0.0.23 → 0.0.25
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/AudioDevices.d.ts.map +1 -1
- package/dist/AudioDevices.js +1 -0
- package/dist/AudioOfflineRenderer.d.ts +8 -0
- package/dist/AudioOfflineRenderer.d.ts.map +1 -0
- package/dist/AudioOfflineRenderer.js +88 -0
- package/dist/{Worklets.d.ts → AudioWorklets.d.ts} +6 -5
- package/dist/AudioWorklets.d.ts.map +1 -0
- package/dist/{Worklets.js → AudioWorklets.js} +6 -4
- package/dist/EffectFactory.d.ts +1 -1
- package/dist/EffectFactory.d.ts.map +1 -1
- package/dist/Engine.d.ts +6 -16
- package/dist/Engine.d.ts.map +1 -1
- package/dist/EngineFacade.d.ts +10 -9
- package/dist/EngineFacade.d.ts.map +1 -1
- package/dist/EngineFacade.js +28 -25
- package/dist/EngineWorklet.d.ts +7 -7
- package/dist/EngineWorklet.d.ts.map +1 -1
- package/dist/EngineWorklet.js +8 -16
- package/dist/FilePickerAcceptTypes.d.ts +8 -0
- package/dist/FilePickerAcceptTypes.d.ts.map +1 -0
- package/dist/FilePickerAcceptTypes.js +27 -0
- package/dist/MidiDevices.d.ts +2 -1
- package/dist/MidiDevices.d.ts.map +1 -1
- package/dist/MidiDevices.js +12 -1
- package/dist/PeaksWriter.d.ts +19 -0
- package/dist/PeaksWriter.d.ts.map +1 -0
- package/dist/PeaksWriter.js +43 -0
- package/dist/RecordingWorklet.d.ts +4 -2
- package/dist/RecordingWorklet.d.ts.map +1 -1
- package/dist/RecordingWorklet.js +36 -62
- package/dist/WorkerAgents.d.ts +1 -1
- package/dist/WorkerAgents.d.ts.map +1 -1
- package/dist/WorkerAgents.js +3 -3
- package/dist/capture/Capture.d.ts +5 -6
- package/dist/capture/Capture.d.ts.map +1 -1
- package/dist/capture/CaptureAudio.d.ts +4 -5
- package/dist/capture/CaptureAudio.d.ts.map +1 -1
- package/dist/capture/CaptureAudio.js +31 -14
- package/dist/capture/{CaptureManager.d.ts → CaptureDevices.d.ts} +4 -3
- package/dist/capture/CaptureDevices.d.ts.map +1 -0
- package/dist/capture/{CaptureManager.js → CaptureDevices.js} +10 -1
- package/dist/capture/CaptureMidi.d.ts +8 -6
- package/dist/capture/CaptureMidi.d.ts.map +1 -1
- package/dist/capture/CaptureMidi.js +67 -47
- package/dist/capture/RecordAudio.d.ts +2 -2
- package/dist/capture/RecordAudio.d.ts.map +1 -1
- package/dist/capture/RecordAudio.js +50 -36
- package/dist/capture/RecordMidi.d.ts +3 -2
- package/dist/capture/RecordMidi.d.ts.map +1 -1
- package/dist/capture/RecordMidi.js +19 -22
- package/dist/capture/Recording.d.ts +2 -2
- package/dist/capture/Recording.d.ts.map +1 -1
- package/dist/capture/Recording.js +10 -11
- package/dist/dawproject/DawProject.d.ts +1 -1
- package/dist/dawproject/DawProject.d.ts.map +1 -1
- package/dist/dawproject/DawProject.js +3 -2
- package/dist/dawproject/DawProjectExporter.d.ts +1 -1
- package/dist/dawproject/DawProjectExporter.d.ts.map +1 -1
- package/dist/dawproject/DawProjectExporter.test.js +6 -5
- package/dist/index.d.ts +16 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -6
- package/dist/processors.js +3 -3
- package/dist/processors.js.map +4 -4
- package/dist/{Project.d.ts → project/Project.d.ts} +8 -7
- package/dist/project/Project.d.ts.map +1 -0
- package/dist/{Project.js → project/Project.js} +17 -9
- package/dist/{ProjectApi.d.ts → project/ProjectApi.d.ts} +5 -5
- package/dist/project/ProjectApi.d.ts.map +1 -0
- package/dist/{ProjectApi.js → project/ProjectApi.js} +2 -2
- package/dist/project/ProjectBundle.d.ts +8 -0
- package/dist/project/ProjectBundle.d.ts.map +1 -0
- package/dist/project/ProjectBundle.js +90 -0
- package/dist/project/ProjectEnv.d.ts +8 -0
- package/dist/project/ProjectEnv.d.ts.map +1 -0
- package/dist/project/ProjectMeta.d.ts +14 -0
- package/dist/project/ProjectMeta.d.ts.map +1 -0
- package/dist/project/ProjectMeta.js +12 -0
- package/dist/project/ProjectMigration.d.ts.map +1 -0
- package/dist/project/ProjectPaths.d.ts +12 -0
- package/dist/project/ProjectPaths.d.ts.map +1 -0
- package/dist/project/ProjectPaths.js +12 -0
- package/dist/project/ProjectProfile.d.ts +21 -0
- package/dist/project/ProjectProfile.d.ts.map +1 -0
- package/dist/project/ProjectProfile.js +83 -0
- package/dist/samples/MainThreadSampleLoader.d.ts +0 -2
- package/dist/samples/MainThreadSampleLoader.d.ts.map +1 -1
- package/dist/samples/MainThreadSampleLoader.js +1 -26
- package/dist/samples/MainThreadSampleManager.d.ts +1 -0
- package/dist/samples/MainThreadSampleManager.d.ts.map +1 -1
- package/dist/samples/MainThreadSampleManager.js +1 -0
- package/dist/samples/OpenSampleAPI.d.ts +14 -0
- package/dist/samples/OpenSampleAPI.d.ts.map +1 -0
- package/dist/samples/OpenSampleAPI.js +109 -0
- package/dist/samples/SampleAPI.d.ts +10 -0
- package/dist/samples/SampleAPI.d.ts.map +1 -0
- package/dist/samples/SampleImporter.d.ts +11 -0
- package/dist/samples/SampleImporter.d.ts.map +1 -0
- package/dist/samples/SampleImporter.js +1 -0
- package/dist/sync-log/Commit.d.ts +1 -1
- package/dist/sync-log/Commit.d.ts.map +1 -1
- package/dist/sync-log/SyncLogReader.d.ts +2 -2
- package/dist/sync-log/SyncLogReader.d.ts.map +1 -1
- package/dist/sync-log/SyncLogReader.js +1 -1
- package/dist/sync-log/SyncLogWriter.d.ts +1 -1
- package/dist/sync-log/SyncLogWriter.d.ts.map +1 -1
- package/dist/workers.js +2 -2
- package/dist/workers.js.map +4 -4
- package/package.json +14 -14
- package/dist/Project.d.ts.map +0 -1
- package/dist/ProjectApi.d.ts.map +0 -1
- package/dist/ProjectEnv.d.ts +0 -5
- package/dist/ProjectEnv.d.ts.map +0 -1
- package/dist/ProjectMigration.d.ts.map +0 -1
- package/dist/Worklets.d.ts.map +0 -1
- package/dist/capture/CaptureManager.d.ts.map +0 -1
- package/dist/capture/RecordingContext.d.ts +0 -10
- package/dist/capture/RecordingContext.d.ts.map +0 -1
- /package/dist/{ProjectEnv.js → project/ProjectEnv.js} +0 -0
- /package/dist/{ProjectMigration.d.ts → project/ProjectMigration.d.ts} +0 -0
- /package/dist/{ProjectMigration.js → project/ProjectMigration.js} +0 -0
- /package/dist/{capture/RecordingContext.js → samples/SampleAPI.js} +0 -0
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"AudioDevices.d.ts","sourceRoot":"","sources":["../src/AudioDevices.ts"],"names":[],"mappings":"AAIA,qBAAa,YAAY;;WACR,iBAAiB;WAQjB,aAAa,CAAC,WAAW,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;
|
1
|
+
{"version":3,"file":"AudioDevices.d.ts","sourceRoot":"","sources":["../src/AudioDevices.ts"],"names":[],"mappings":"AAIA,qBAAa,YAAY;;WACR,iBAAiB;WAQjB,aAAa,CAAC,WAAW,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;WAcvE,eAAe;IAY5B,MAAM,KAAK,MAAM,IAAI,aAAa,CAAC,eAAe,CAAC,CAAsB;CAC5E"}
|
package/dist/AudioDevices.js
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
import { int, Option } from "@opendaw/lib-std";
|
2
|
+
import { ExportStemsConfiguration } from "@opendaw/studio-adapters";
|
3
|
+
import { Project } from "./project/Project";
|
4
|
+
import { ProjectMeta } from "./project/ProjectMeta";
|
5
|
+
export declare namespace AudioOfflineRenderer {
|
6
|
+
const start: (source: Project, meta: ProjectMeta, optExportConfiguration: Option<ExportStemsConfiguration>, sampleRate?: int) => Promise<void>;
|
7
|
+
}
|
8
|
+
//# sourceMappingURL=AudioOfflineRenderer.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"AudioOfflineRenderer.d.ts","sourceRoot":"","sources":["../src/AudioOfflineRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,GAAG,EAAE,MAAM,EAAmC,MAAM,kBAAkB,CAAA;AAItG,OAAO,EAAC,wBAAwB,EAAC,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,WAAW,EAAC,MAAM,uBAAuB,CAAA;AAIjD,yBAAiB,oBAAoB,CAAC;IAC3B,MAAM,KAAK,GAAU,QAAQ,OAAO,EACf,MAAM,WAAW,EACjB,wBAAwB,MAAM,CAAC,wBAAwB,CAAC,EACxD,aAAY,GAAY,KAAG,OAAO,CAAC,IAAI,CA4BlE,CAAA;CA6CJ"}
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import { DefaultObservableValue, panic, RuntimeNotifier, TimeSpan } from "@opendaw/lib-std";
|
2
|
+
import { PPQN } from "@opendaw/lib-dsp";
|
3
|
+
import { AnimationFrame, Errors, Files } from "@opendaw/lib-dom";
|
4
|
+
import { Promises, Wait } from "@opendaw/lib-runtime";
|
5
|
+
import { ExportStemsConfiguration } from "@opendaw/studio-adapters";
|
6
|
+
import { encodeWavFloat } from "./Wav";
|
7
|
+
import { AudioWorklets } from "./AudioWorklets";
|
8
|
+
export var AudioOfflineRenderer;
|
9
|
+
(function (AudioOfflineRenderer) {
|
10
|
+
AudioOfflineRenderer.start = async (source, meta, optExportConfiguration, sampleRate = 48_000) => {
|
11
|
+
const project = source.copy();
|
12
|
+
const numStems = ExportStemsConfiguration.countStems(optExportConfiguration);
|
13
|
+
const progress = new DefaultObservableValue(0.0);
|
14
|
+
const dialog = RuntimeNotifier.progress({ headline: "Rendering...", progress });
|
15
|
+
project.boxGraph.beginTransaction();
|
16
|
+
project.timelineBox.loopArea.enabled.setValue(false);
|
17
|
+
project.boxGraph.endTransaction();
|
18
|
+
const durationInPulses = project.timelineBox.durationInPulses.getValue();
|
19
|
+
const numSamples = PPQN.pulsesToSamples(durationInPulses, project.bpm, sampleRate);
|
20
|
+
const context = new OfflineAudioContext(numStems * 2, numSamples, sampleRate);
|
21
|
+
const durationInSeconds = numSamples / sampleRate;
|
22
|
+
const worklets = await AudioWorklets.install(context);
|
23
|
+
const engineWorklet = worklets.createEngine(project, optExportConfiguration.unwrapOrUndefined());
|
24
|
+
engineWorklet.play();
|
25
|
+
engineWorklet.connect(context.destination);
|
26
|
+
await engineWorklet.isReady();
|
27
|
+
while (!await engineWorklet.queryLoadingComplete()) {
|
28
|
+
await Wait.timeSpan(TimeSpan.seconds(1));
|
29
|
+
}
|
30
|
+
const terminable = AnimationFrame.add(() => progress.setValue(context.currentTime / durationInSeconds));
|
31
|
+
const buffer = await context.startRendering();
|
32
|
+
terminable.terminate();
|
33
|
+
dialog.terminate();
|
34
|
+
project.terminate();
|
35
|
+
if (optExportConfiguration.isEmpty()) {
|
36
|
+
await saveWavFile(buffer, meta);
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
await saveZipFile(buffer, meta, Object.values(optExportConfiguration.unwrap()).map(({ fileName }) => fileName));
|
40
|
+
}
|
41
|
+
};
|
42
|
+
const saveWavFile = async (buffer, meta) => {
|
43
|
+
const approved = await RuntimeNotifier.approve({
|
44
|
+
headline: "Save Wav-File",
|
45
|
+
message: "",
|
46
|
+
approveText: "Save"
|
47
|
+
});
|
48
|
+
if (!approved) {
|
49
|
+
return;
|
50
|
+
}
|
51
|
+
const wavFile = encodeWavFloat(buffer);
|
52
|
+
const suggestedName = `${meta.name}.wav`;
|
53
|
+
const saveResult = await Promises.tryCatch(Files.save(wavFile, { suggestedName }));
|
54
|
+
if (saveResult.status === "rejected" && !Errors.isAbort(saveResult.error)) {
|
55
|
+
panic(String(saveResult.error));
|
56
|
+
}
|
57
|
+
};
|
58
|
+
const saveZipFile = async (buffer, meta, trackNames) => {
|
59
|
+
const { default: JSZip } = await import("jszip");
|
60
|
+
const dialog = RuntimeNotifier.progress({ headline: "Creating Zip File..." });
|
61
|
+
const numStems = buffer.numberOfChannels >> 1;
|
62
|
+
const zip = new JSZip();
|
63
|
+
for (let stemIndex = 0; stemIndex < numStems; stemIndex++) {
|
64
|
+
const l = buffer.getChannelData(stemIndex * 2);
|
65
|
+
const r = buffer.getChannelData(stemIndex * 2 + 1);
|
66
|
+
const file = encodeWavFloat({ channels: [l, r], sampleRate: buffer.sampleRate, numFrames: buffer.length });
|
67
|
+
zip.file(`${trackNames[stemIndex]}.wav`, file, { binary: true });
|
68
|
+
}
|
69
|
+
const arrayBuffer = await zip.generateAsync({
|
70
|
+
type: "arraybuffer",
|
71
|
+
compression: "DEFLATE",
|
72
|
+
compressionOptions: { level: 6 }
|
73
|
+
});
|
74
|
+
dialog.terminate();
|
75
|
+
const approved = await RuntimeNotifier.approve({
|
76
|
+
headline: "Save Zip",
|
77
|
+
message: `Size: ${arrayBuffer.byteLength >> 20}M`,
|
78
|
+
approveText: "Save"
|
79
|
+
});
|
80
|
+
if (!approved) {
|
81
|
+
return;
|
82
|
+
}
|
83
|
+
const saveResult = await Promises.tryCatch(Files.save(arrayBuffer, { suggestedName: `${meta.name}.zip` }));
|
84
|
+
if (saveResult.status === "rejected") {
|
85
|
+
panic(String(saveResult.error));
|
86
|
+
}
|
87
|
+
};
|
88
|
+
})(AudioOfflineRenderer || (AudioOfflineRenderer = {}));
|
@@ -1,16 +1,17 @@
|
|
1
1
|
import { int } from "@opendaw/lib-std";
|
2
2
|
import { ExportStemsConfiguration } from "@opendaw/studio-adapters";
|
3
|
+
import { Project } from "./project/Project";
|
3
4
|
import { EngineWorklet } from "./EngineWorklet";
|
4
5
|
import { MeterWorklet } from "./MeterWorklet";
|
5
6
|
import { RecordingWorklet } from "./RecordingWorklet";
|
6
|
-
|
7
|
-
export declare class Worklets {
|
7
|
+
export declare class AudioWorklets {
|
8
8
|
#private;
|
9
|
-
static install(context: BaseAudioContext
|
10
|
-
static get(context: BaseAudioContext):
|
9
|
+
static install(context: BaseAudioContext): Promise<AudioWorklets>;
|
10
|
+
static get(context: BaseAudioContext): AudioWorklets;
|
11
11
|
constructor(context: BaseAudioContext);
|
12
|
+
get context(): BaseAudioContext;
|
12
13
|
createMeter(numberOfChannels: int): MeterWorklet;
|
13
14
|
createEngine(project: Project, exportConfiguration?: ExportStemsConfiguration): EngineWorklet;
|
14
15
|
createRecording(numberOfChannels: int, numChunks: int, outputLatency: number): RecordingWorklet;
|
15
16
|
}
|
16
|
-
//# sourceMappingURL=
|
17
|
+
//# sourceMappingURL=AudioWorklets.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"AudioWorklets.d.ts","sourceRoot":"","sources":["../src/AudioWorklets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,GAAG,EAAC,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAC,wBAAwB,EAAa,MAAM,0BAA0B,CAAA;AAC7E,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AAKnD,qBAAa,aAAa;;WACT,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC;IAQvE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa;gBAMxC,OAAO,EAAE,gBAAgB;IAErC,IAAI,OAAO,IAAI,gBAAgB,CAAuB;IAEtD,WAAW,CAAC,gBAAgB,EAAE,GAAG,GAAG,YAAY;IAIhD,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,CAAC,EAAE,wBAAwB,GAAG,aAAa;IAI7F,eAAe,CAAC,gBAAgB,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,GAAG,gBAAgB;CAOlG"}
|
@@ -3,10 +3,11 @@ import { EngineWorklet } from "./EngineWorklet";
|
|
3
3
|
import { MeterWorklet } from "./MeterWorklet";
|
4
4
|
import { RecordingWorklet } from "./RecordingWorklet";
|
5
5
|
import { RenderQuantum } from "./RenderQuantum";
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
const WorkletsUrl = new URL("./processors.js", import.meta.url);
|
7
|
+
export class AudioWorklets {
|
8
|
+
static async install(context) {
|
9
|
+
return context.audioWorklet.addModule(WorkletsUrl).then(() => {
|
10
|
+
const worklets = new AudioWorklets(context);
|
10
11
|
this.#map.set(context, worklets);
|
11
12
|
return worklets;
|
12
13
|
});
|
@@ -15,6 +16,7 @@ export class Worklets {
|
|
15
16
|
static #map = new WeakMap();
|
16
17
|
#context;
|
17
18
|
constructor(context) { this.#context = context; }
|
19
|
+
get context() { return this.#context; }
|
18
20
|
createMeter(numberOfChannels) {
|
19
21
|
return new MeterWorklet(this.#context, numberOfChannels);
|
20
22
|
}
|
package/dist/EffectFactory.d.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { EffectPointerType, IconSymbol } from "@opendaw/studio-adapters";
|
2
2
|
import { Field } from "@opendaw/lib-box";
|
3
3
|
import { int } from "@opendaw/lib-std";
|
4
|
-
import { Project } from "./Project";
|
4
|
+
import { Project } from "./project/Project";
|
5
5
|
import { EffectBox } from "./EffectBox";
|
6
6
|
export interface EffectFactory {
|
7
7
|
get defaultName(): string;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"EffectFactory.d.ts","sourceRoot":"","sources":["../src/EffectFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAE,UAAU,EAAC,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAC,KAAK,EAAC,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAC,GAAG,EAAC,MAAM,kBAAkB,CAAA;AACpC,OAAO,EAAC,OAAO,EAAC,MAAM,
|
1
|
+
{"version":3,"file":"EffectFactory.d.ts","sourceRoot":"","sources":["../src/EffectFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAE,UAAU,EAAC,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAC,KAAK,EAAC,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAC,GAAG,EAAC,MAAM,kBAAkB,CAAA;AACpC,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAA;AAErC,MAAM,WAAW,aAAa;IAC1B,IAAI,WAAW,IAAI,MAAM,CAAA;IACzB,IAAI,WAAW,IAAI,UAAU,CAAA;IAC7B,IAAI,WAAW,IAAI,MAAM,CAAA;IACzB,IAAI,eAAe,IAAI,OAAO,CAAA;IAC9B,IAAI,IAAI,IAAI,OAAO,GAAG,MAAM,CAAA;IAE5B,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,GAAG,GAAG,SAAS,CAAA;CAClF"}
|
package/dist/Engine.d.ts
CHANGED
@@ -1,17 +1,7 @@
|
|
1
1
|
import { ppqn } from "@opendaw/lib-dsp";
|
2
|
-
import {
|
3
|
-
import { ClipNotification } from "@opendaw/studio-adapters";
|
4
|
-
import { Project } from "./Project";
|
5
|
-
export type NoteTrigger = {
|
6
|
-
type: "note-on";
|
7
|
-
uuid: UUID.Format;
|
8
|
-
pitch: byte;
|
9
|
-
velocity: unitValue;
|
10
|
-
} | {
|
11
|
-
type: "note-off";
|
12
|
-
uuid: UUID.Format;
|
13
|
-
pitch: byte;
|
14
|
-
};
|
2
|
+
import { int, Nullable, ObservableValue, Observer, Subscription, Terminable, UUID } from "@opendaw/lib-std";
|
3
|
+
import { ClipNotification, NoteSignal } from "@opendaw/studio-adapters";
|
4
|
+
import { Project } from "./project/Project";
|
15
5
|
export interface Engine extends Terminable {
|
16
6
|
play(): void;
|
17
7
|
stop(): void;
|
@@ -22,9 +12,9 @@ export interface Engine extends Terminable {
|
|
22
12
|
queryLoadingComplete(): Promise<boolean>;
|
23
13
|
stop(): void;
|
24
14
|
panic(): void;
|
25
|
-
|
26
|
-
|
27
|
-
|
15
|
+
noteSignal(signal: NoteSignal): void;
|
16
|
+
subscribeNotes(observer: Observer<NoteSignal>): Subscription;
|
17
|
+
ignoreNoteRegion(uuid: UUID.Format): void;
|
28
18
|
scheduleClipPlay(clipIds: ReadonlyArray<UUID.Format>): void;
|
29
19
|
scheduleClipStop(trackIds: ReadonlyArray<UUID.Format>): void;
|
30
20
|
subscribeClipNotification(observer: Observer<ClipNotification>): Subscription;
|
package/dist/Engine.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../src/Engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACrC,OAAO,
|
1
|
+
{"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../src/Engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACrC,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACzG,OAAO,EAAC,gBAAgB,EAAE,UAAU,EAAC,MAAM,0BAA0B,CAAA;AACrE,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AAEzC,MAAM,WAAW,MAAO,SAAQ,UAAU;IACtC,IAAI,IAAI,IAAI,CAAA;IACZ,IAAI,IAAI,IAAI,CAAA;IACZ,WAAW,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAA;IACjC,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACtC,aAAa,IAAI,IAAI,CAAA;IACrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACxB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IACxC,IAAI,IAAI,IAAI,CAAA;IACZ,KAAK,IAAI,IAAI,CAAA;IACb,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAA;IACpC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,YAAY,CAAA;IAC5D,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;IACzC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;IAC3D,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;IAC5D,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,YAAY,CAAA;IAE7E,IAAI,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,CAAA;IACrC,IAAI,SAAS,IAAI,eAAe,CAAC,OAAO,CAAC,CAAA;IACzC,IAAI,WAAW,IAAI,eAAe,CAAC,OAAO,CAAC,CAAA;IAC3C,IAAI,YAAY,IAAI,eAAe,CAAC,OAAO,CAAC,CAAA;IAC5C,IAAI,gBAAgB,IAAI,eAAe,CAAC,OAAO,CAAC,CAAA;IAChD,IAAI,iBAAiB,IAAI,eAAe,CAAC,IAAI,CAAC,CAAA;IAC9C,IAAI,iBAAiB,IAAI,eAAe,CAAC,GAAG,CAAC,CAAA;IAC7C,IAAI,qBAAqB,IAAI,eAAe,CAAC,MAAM,CAAC,CAAA;IACpD,IAAI,WAAW,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;IAChE,IAAI,OAAO,IAAI,OAAO,CAAA;CACzB"}
|
package/dist/EngineFacade.d.ts
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
import {
|
1
|
+
import { DefaultObservableValue, int, MutableObservableValue, Nullable, ObservableValue, Observer, Subscription, UUID } from "@opendaw/lib-std";
|
2
2
|
import { ppqn } from "@opendaw/lib-dsp";
|
3
|
-
import { ClipNotification } from "@opendaw/studio-adapters";
|
4
|
-
import { Engine
|
3
|
+
import { ClipNotification, NoteSignal } from "@opendaw/studio-adapters";
|
4
|
+
import { Engine } from "./Engine";
|
5
5
|
import { EngineWorklet } from "./EngineWorklet";
|
6
|
-
import { Project } from "./Project";
|
6
|
+
import { Project } from "./project/Project";
|
7
7
|
export declare class EngineFacade implements Engine {
|
8
8
|
#private;
|
9
9
|
constructor();
|
10
|
-
|
11
|
-
|
10
|
+
setWorklet(worklet: EngineWorklet): void;
|
11
|
+
assertWorklet(): void;
|
12
|
+
releaseWorklet(): void;
|
12
13
|
play(): void;
|
13
14
|
stop(reset?: boolean): void;
|
14
15
|
setPosition(position: ppqn): void;
|
@@ -29,9 +30,9 @@ export declare class EngineFacade implements Engine {
|
|
29
30
|
panic(): void;
|
30
31
|
sampleRate(): number;
|
31
32
|
subscribeClipNotification(observer: Observer<ClipNotification>): Subscription;
|
32
|
-
subscribeNotes(observer: Observer<
|
33
|
-
|
34
|
-
|
33
|
+
subscribeNotes(observer: Observer<NoteSignal>): Subscription;
|
34
|
+
ignoreNoteRegion(uuid: UUID.Format): void;
|
35
|
+
noteSignal(signal: NoteSignal): void;
|
35
36
|
scheduleClipPlay(clipIds: ReadonlyArray<UUID.Format>): void;
|
36
37
|
scheduleClipStop(trackIds: ReadonlyArray<UUID.Format>): void;
|
37
38
|
terminate(): void;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"EngineFacade.d.ts","sourceRoot":"","sources":["../src/EngineFacade.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,
|
1
|
+
{"version":3,"file":"EngineFacade.d.ts","sourceRoot":"","sources":["../src/EngineFacade.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EACtB,GAAG,EACH,sBAAsB,EACtB,QAAQ,EACR,eAAe,EACf,QAAQ,EAER,YAAY,EAEZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACrC,OAAO,EAAC,gBAAgB,EAAE,UAAU,EAAC,MAAM,0BAA0B,CAAA;AACrE,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AAEzC,qBAAa,YAAa,YAAW,MAAM;;;IAkBvC,UAAU,CAAC,OAAO,EAAE,aAAa;IAiBjC,aAAa,IAAI,IAAI;IAErB,cAAc,IAAI,IAAI;IAMtB,IAAI,IAAI,IAAI;IACZ,IAAI,CAAC,KAAK,GAAE,OAAe,GAAG,IAAI;IAClC,WAAW,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI;IACjC,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IACtC,aAAa,IAAI,IAAI;IAErB,IAAI,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,CAAwB;IAC7D,IAAI,SAAS,IAAI,eAAe,CAAC,OAAO,CAAC,CAAyB;IAClE,IAAI,WAAW,IAAI,eAAe,CAAC,OAAO,CAAC,CAA2B;IACtE,IAAI,YAAY,IAAI,eAAe,CAAC,OAAO,CAAC,CAA4B;IACxE,IAAI,gBAAgB,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAgC;IACvF,IAAI,iBAAiB,IAAI,eAAe,CAAC,IAAI,CAAC,CAAiC;IAC/E,IAAI,iBAAiB,IAAI,eAAe,CAAC,GAAG,CAAC,CAAiC;IAC9E,IAAI,qBAAqB,IAAI,eAAe,CAAC,GAAG,CAAC,CAAqC;IACtF,IAAI,WAAW,IAAI,sBAAsB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAA2B;IAClG,IAAI,OAAO,IAAI,OAAO,CAAmE;IAEzF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IACxB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;IAGxC,KAAK,IAAI,IAAI;IACb,UAAU,IAAI,MAAM;IACpB,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,YAAY;IAG7E,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,YAAY;IAG5D,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI;IAGzC,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAGpC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI;IAG3D,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI;IAI5D,SAAS,IAAI,IAAI;CAIpB"}
|
package/dist/EngineFacade.js
CHANGED
@@ -11,23 +11,24 @@ export class EngineFacade {
|
|
11
11
|
#isCountingIn = new DefaultObservableValue(false);
|
12
12
|
#metronomeEnabled = new DefaultObservableValue(false);
|
13
13
|
#markerState = new DefaultObservableValue(null);
|
14
|
-
#
|
14
|
+
#worklet = Option.None;
|
15
15
|
constructor() { }
|
16
|
-
|
17
|
-
this.#
|
16
|
+
setWorklet(worklet) {
|
17
|
+
this.#worklet = Option.wrap(worklet);
|
18
18
|
this.#lifecycle.terminate();
|
19
|
-
this.#lifecycle.ownAll(
|
19
|
+
this.#lifecycle.ownAll(worklet.playbackTimestamp.catchupAndSubscribe(owner => this.#playbackTimestamp.setValue(owner.getValue())), worklet.countInBeatsTotal.catchupAndSubscribe(owner => this.#countInBeatsTotal.setValue(owner.getValue())), worklet.countInBeatsRemaining.catchupAndSubscribe(owner => this.#countInBeatsRemaining.setValue(owner.getValue())), worklet.position.catchupAndSubscribe(owner => this.#position.setValue(owner.getValue())), worklet.isPlaying.catchupAndSubscribe(owner => this.#isPlaying.setValue(owner.getValue())), worklet.isRecording.catchupAndSubscribe(owner => this.#isRecording.setValue(owner.getValue())), worklet.isCountingIn.catchupAndSubscribe(owner => this.#isCountingIn.setValue(owner.getValue())), worklet.metronomeEnabled.catchupAndSubscribe(owner => this.#metronomeEnabled.setValue(owner.getValue())), worklet.markerState.catchupAndSubscribe(owner => this.#markerState.setValue(owner.getValue())), this.metronomeEnabled.catchupAndSubscribe(owner => worklet.metronomeEnabled.setValue(owner.getValue())));
|
20
20
|
}
|
21
|
-
|
21
|
+
assertWorklet() { this.#worklet.unwrap("No worklet available"); }
|
22
|
+
releaseWorklet() {
|
22
23
|
this.#lifecycle.terminate();
|
23
|
-
this.#
|
24
|
-
this.#
|
24
|
+
this.#worklet.ifSome(worklet => worklet.terminate());
|
25
|
+
this.#worklet = Option.None;
|
25
26
|
}
|
26
|
-
play() { this.#
|
27
|
-
stop(reset = false) { this.#
|
28
|
-
setPosition(position) { this.#
|
29
|
-
startRecording(countIn) { this.#
|
30
|
-
stopRecording() { this.#
|
27
|
+
play() { this.#worklet.ifSome(worklet => worklet.play()); }
|
28
|
+
stop(reset = false) { this.#worklet.ifSome(worklet => worklet.stop(reset)); }
|
29
|
+
setPosition(position) { this.#worklet.ifSome(worklet => worklet.setPosition(position)); }
|
30
|
+
startRecording(countIn) { this.#worklet.ifSome(worklet => worklet.startRecording(countIn)); }
|
31
|
+
stopRecording() { this.#worklet.ifSome(worklet => worklet.stopRecording()); }
|
31
32
|
get position() { return this.#position; }
|
32
33
|
get isPlaying() { return this.#isPlaying; }
|
33
34
|
get isRecording() { return this.#isRecording; }
|
@@ -37,31 +38,33 @@ export class EngineFacade {
|
|
37
38
|
get countInBeatsTotal() { return this.#countInBeatsTotal; }
|
38
39
|
get countInBeatsRemaining() { return this.#countInBeatsRemaining; }
|
39
40
|
get markerState() { return this.#markerState; }
|
40
|
-
get project() { return this.#
|
41
|
-
isReady() { return this.#
|
41
|
+
get project() { return this.#worklet.unwrap("No worklet to get project").project; }
|
42
|
+
isReady() { return this.#worklet.mapOr(worklet => worklet.isReady(), Promise.resolve()); }
|
42
43
|
queryLoadingComplete() {
|
43
|
-
return this.#
|
44
|
+
return this.#worklet.mapOr(worklet => worklet.queryLoadingComplete(), Promise.resolve(false));
|
44
45
|
}
|
45
|
-
panic() { this.#
|
46
|
-
sampleRate() { return this.#
|
46
|
+
panic() { this.#worklet.ifSome(worklet => worklet.panic()); }
|
47
|
+
sampleRate() { return this.#worklet.isEmpty() ? 44_100 : this.#worklet.unwrap().context.sampleRate; }
|
47
48
|
subscribeClipNotification(observer) {
|
48
|
-
return this.#
|
49
|
+
return this.#worklet.unwrap("No worklet to subscribeClipNotification").subscribeClipNotification(observer);
|
49
50
|
}
|
50
51
|
subscribeNotes(observer) {
|
51
|
-
return this.#
|
52
|
+
return this.#worklet.unwrap("No worklet to subscribeNotes").subscribeNotes(observer);
|
52
53
|
}
|
53
|
-
|
54
|
-
this.#
|
54
|
+
ignoreNoteRegion(uuid) {
|
55
|
+
this.#worklet.unwrap("No worklet to ignoreNoteRegion").ignoreNoteRegion(uuid);
|
56
|
+
}
|
57
|
+
noteSignal(signal) {
|
58
|
+
this.#worklet.unwrap("No worklet to noteOn").noteSignal(signal);
|
55
59
|
}
|
56
|
-
noteOff(uuid, pitch) { this.#client.unwrap("No engine").noteOff(uuid, pitch); }
|
57
60
|
scheduleClipPlay(clipIds) {
|
58
|
-
this.#
|
61
|
+
this.#worklet.unwrap("No worklet to scheduleClipPlay").scheduleClipPlay(clipIds);
|
59
62
|
}
|
60
63
|
scheduleClipStop(trackIds) {
|
61
|
-
this.#
|
64
|
+
this.#worklet.unwrap("No worklet to scheduleClipStop").scheduleClipStop(trackIds);
|
62
65
|
}
|
63
66
|
terminate() {
|
64
|
-
this.
|
67
|
+
this.releaseWorklet();
|
65
68
|
this.#terminator.terminate();
|
66
69
|
}
|
67
70
|
}
|
package/dist/EngineWorklet.d.ts
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
import {
|
1
|
+
import { int, MutableObservableValue, Nullable, ObservableValue, Observer, Subscription, UUID } from "@opendaw/lib-std";
|
2
2
|
import { ppqn } from "@opendaw/lib-dsp";
|
3
|
-
import { ClipNotification, ExportStemsConfiguration } from "@opendaw/studio-adapters";
|
4
|
-
import { Project } from "./Project";
|
5
|
-
import { Engine
|
3
|
+
import { ClipNotification, ExportStemsConfiguration, NoteSignal } from "@opendaw/studio-adapters";
|
4
|
+
import { Project } from "./project/Project";
|
5
|
+
import { Engine } from "./Engine";
|
6
6
|
export declare class EngineWorklet extends AudioWorkletNode implements Engine {
|
7
7
|
#private;
|
8
8
|
static ID: int;
|
@@ -26,9 +26,9 @@ export declare class EngineWorklet extends AudioWorkletNode implements Engine {
|
|
26
26
|
get project(): Project;
|
27
27
|
isReady(): Promise<void>;
|
28
28
|
queryLoadingComplete(): Promise<boolean>;
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
noteSignal(signal: NoteSignal): void;
|
30
|
+
subscribeNotes(observer: Observer<NoteSignal>): Subscription;
|
31
|
+
ignoreNoteRegion(uuid: UUID.Format): void;
|
32
32
|
scheduleClipPlay(clipIds: ReadonlyArray<UUID.Format>): void;
|
33
33
|
scheduleClipStop(trackIds: ReadonlyArray<UUID.Format>): void;
|
34
34
|
subscribeClipNotification(observer: Observer<ClipNotification>): Subscription;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"EngineWorklet.d.ts","sourceRoot":"","sources":["../src/EngineWorklet.ts"],"names":[],"mappings":"AAAA,OAAO,
|
1
|
+
{"version":3,"file":"EngineWorklet.d.ts","sourceRoot":"","sources":["../src/EngineWorklet.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,GAAG,EACH,sBAAsB,EAEtB,QAAQ,EACR,eAAe,EACf,QAAQ,EAER,YAAY,EAGZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAIrC,OAAO,EAEH,gBAAgB,EAOhB,wBAAwB,EACxB,UAAU,EACb,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAE/B,qBAAa,aAAc,SAAQ,gBAAiB,YAAW,MAAM;;IACjE,MAAM,CAAC,EAAE,EAAE,GAAG,CAAQ;IAEtB,QAAQ,CAAC,EAAE,SAAqB;gBAoBpB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,OAAO,EAChB,mBAAmB,CAAC,EAAE,wBAAwB;IA8F1D,IAAI,IAAI,IAAI;IACZ,IAAI,CAAC,KAAK,GAAE,OAAe,GAAG,IAAI;IAClC,WAAW,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI;IACjC,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IACtC,aAAa,IAAI,IAAI;IACrB,KAAK,IAAI,IAAI;IAEb,IAAI,SAAS,IAAI,eAAe,CAAC,OAAO,CAAC,CAAyB;IAClE,IAAI,WAAW,IAAI,eAAe,CAAC,OAAO,CAAC,CAA2B;IACtE,IAAI,YAAY,IAAI,eAAe,CAAC,OAAO,CAAC,CAA4B;IACxE,IAAI,iBAAiB,IAAI,eAAe,CAAC,GAAG,CAAC,CAAiC;IAC9E,IAAI,qBAAqB,IAAI,eAAe,CAAC,MAAM,CAAC,CAAqC;IACzF,IAAI,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,CAAwB;IAC7D,IAAI,iBAAiB,IAAI,sBAAsB,CAAC,MAAM,CAAC,CAAiC;IACxF,IAAI,gBAAgB,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAgC;IACvF,IAAI,WAAW,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAA2B;IAC3F,IAAI,OAAO,IAAI,OAAO,CAAuB;IAE7C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IACxB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;IACxC,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IACpC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,YAAY;IAC5D,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI;IACzC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI;IAI3D,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI;IAG5D,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,YAAY;IAQ7E,SAAS,IAAI,IAAI;CAIpB"}
|
package/dist/EngineWorklet.js
CHANGED
@@ -18,7 +18,7 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
18
18
|
#metronomeEnabled = new DefaultObservableValue(false);
|
19
19
|
#markerState = new DefaultObservableValue(null);
|
20
20
|
#notifyClipNotification;
|
21
|
-
#
|
21
|
+
#notifyNoteSignals;
|
22
22
|
#playingClips;
|
23
23
|
#commands;
|
24
24
|
#isReady;
|
@@ -48,7 +48,7 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
48
48
|
this.#project = project;
|
49
49
|
this.#isReady = promise;
|
50
50
|
this.#notifyClipNotification = this.#terminator.own(new Notifier());
|
51
|
-
this.#
|
51
|
+
this.#notifyNoteSignals = this.#terminator.own(new Notifier());
|
52
52
|
this.#playingClips = [];
|
53
53
|
this.#commands = this.#terminator.own(Communicator.sender(messenger.channel("engine-commands"), dispatcher => new class {
|
54
54
|
play() { dispatcher.dispatchAndForget(this.play); }
|
@@ -61,11 +61,9 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
61
61
|
return dispatcher.dispatchAndReturn(this.queryLoadingComplete);
|
62
62
|
}
|
63
63
|
panic() { dispatcher.dispatchAndForget(this.panic); }
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
noteOff(uuid, pitch) {
|
68
|
-
dispatcher.dispatchAndForget(this.noteOff, uuid, pitch);
|
64
|
+
noteSignal(signal) { dispatcher.dispatchAndForget(this.noteSignal, signal); }
|
65
|
+
ignoreNoteRegion(uuid) {
|
66
|
+
dispatcher.dispatchAndForget(this.ignoreNoteRegion, uuid);
|
69
67
|
}
|
70
68
|
scheduleClipPlay(clipIds) {
|
71
69
|
dispatcher.dispatchAndForget(this.scheduleClipPlay, clipIds);
|
@@ -125,15 +123,9 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
125
123
|
get project() { return this.#project; }
|
126
124
|
isReady() { return this.#isReady; }
|
127
125
|
queryLoadingComplete() { return this.#commands.queryLoadingComplete(); }
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
}
|
132
|
-
noteOff(uuid, pitch) {
|
133
|
-
this.#commands.noteOff(uuid, pitch);
|
134
|
-
this.#notifyNoteTrigger.notify({ type: "note-off", uuid, pitch });
|
135
|
-
}
|
136
|
-
subscribeNotes(observer) { return this.#notifyNoteTrigger.subscribe(observer); }
|
126
|
+
noteSignal(signal) { this.#commands.noteSignal(signal); }
|
127
|
+
subscribeNotes(observer) { return this.#notifyNoteSignals.subscribe(observer); }
|
128
|
+
ignoreNoteRegion(uuid) { this.#commands.ignoreNoteRegion(uuid); }
|
137
129
|
scheduleClipPlay(clipIds) {
|
138
130
|
this.#notifyClipNotification.notify({ type: "waiting", clips: clipIds });
|
139
131
|
this.#commands.scheduleClipPlay(clipIds);
|
@@ -0,0 +1,8 @@
|
|
1
|
+
export declare namespace FilePickerAcceptTypes {
|
2
|
+
const WavFiles: FilePickerOptions;
|
3
|
+
const ProjectSyncLog: FilePickerOptions;
|
4
|
+
const ProjectFileType: FilePickerAcceptType;
|
5
|
+
const ProjectBundleFileType: FilePickerAcceptType;
|
6
|
+
const DawprojectFileType: FilePickerAcceptType;
|
7
|
+
}
|
8
|
+
//# sourceMappingURL=FilePickerAcceptTypes.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"FilePickerAcceptTypes.d.ts","sourceRoot":"","sources":["../src/FilePickerAcceptTypes.ts"],"names":[],"mappings":"AAAA,yBAAiB,qBAAqB,CAAC;IAC5B,MAAM,QAAQ,EAAE,iBAKtB,CAAA;IACM,MAAM,cAAc,EAAE,iBAK5B,CAAA;IAEM,MAAM,eAAe,EAAE,oBAG7B,CAAA;IAEM,MAAM,qBAAqB,EAAE,oBAGnC,CAAA;IAEM,MAAM,kBAAkB,EAAE,oBAGhC,CAAA;CACJ"}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
export var FilePickerAcceptTypes;
|
2
|
+
(function (FilePickerAcceptTypes) {
|
3
|
+
FilePickerAcceptTypes.WavFiles = {
|
4
|
+
types: [{
|
5
|
+
description: "wav-file",
|
6
|
+
accept: { "audio/wav": [".wav"] }
|
7
|
+
}]
|
8
|
+
};
|
9
|
+
FilePickerAcceptTypes.ProjectSyncLog = {
|
10
|
+
types: [{
|
11
|
+
description: "openDAW sync-log-file",
|
12
|
+
accept: { "application/octet-stream": [".odsl"] }
|
13
|
+
}]
|
14
|
+
};
|
15
|
+
FilePickerAcceptTypes.ProjectFileType = {
|
16
|
+
description: "openDAW project",
|
17
|
+
accept: { "application/octet-stream": [".od"] }
|
18
|
+
};
|
19
|
+
FilePickerAcceptTypes.ProjectBundleFileType = {
|
20
|
+
description: "openDAW project bundle",
|
21
|
+
accept: { "application/octet-stream": [".odb"] }
|
22
|
+
};
|
23
|
+
FilePickerAcceptTypes.DawprojectFileType = {
|
24
|
+
description: "dawproject",
|
25
|
+
accept: { "application/octet-stream": [".dawproject"] }
|
26
|
+
};
|
27
|
+
})(FilePickerAcceptTypes || (FilePickerAcceptTypes = {}));
|
package/dist/MidiDevices.d.ts
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
import { MutableObservableValue, ObservableOption, Option } from "@opendaw/lib-std";
|
1
|
+
import { byte, MutableObservableValue, ObservableOption, Observer, Option, Subscription } from "@opendaw/lib-std";
|
2
2
|
export declare class MidiDevices {
|
3
3
|
#private;
|
4
4
|
static canRequestMidiAccess(): boolean;
|
5
5
|
static requestPermission(): Promise<undefined>;
|
6
6
|
static get(): ObservableOption<MIDIAccess>;
|
7
|
+
static subscribeMessageEvents(observer: Observer<MIDIMessageEvent>, channel?: byte): Subscription;
|
7
8
|
static inputs(): Option<ReadonlyArray<MIDIInput>>;
|
8
9
|
static outputs(): Option<ReadonlyArray<MIDIOutput>>;
|
9
10
|
static panic(): void;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MidiDevices.d.ts","sourceRoot":"","sources":["../src/MidiDevices.ts"],"names":[],"mappings":"AAAA,OAAO,
|
1
|
+
{"version":3,"file":"MidiDevices.d.ts","sourceRoot":"","sources":["../src/MidiDevices.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,IAAI,EAGJ,sBAAsB,EAEtB,gBAAgB,EAEhB,QAAQ,EACR,MAAM,EACN,YAAY,EAGf,MAAM,kBAAkB,CAAA;AAKzB,qBAAa,WAAW;;IACpB,MAAM,CAAC,oBAAoB,IAAI,OAAO;WAEzB,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,MAAM,IAAI,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAIjD,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAInD,MAAM,CAAC,KAAK,IAAI,IAAI;IAkBpB,MAAM,CAAC,SAAS,IAAI,sBAAsB,CAAC,OAAO,CAAC;CAqCtD"}
|
package/dist/MidiDevices.js
CHANGED
@@ -7,9 +7,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
9
9
|
};
|
10
|
-
import { Lazy, MutableObservableOption, MutableObservableValue, Notifier, warn } from "@opendaw/lib-std";
|
10
|
+
import { Lazy, MutableObservableOption, MutableObservableValue, Notifier, Terminator, warn } from "@opendaw/lib-std";
|
11
11
|
import { MidiData } from "@opendaw/lib-midi";
|
12
12
|
import { Promises } from "@opendaw/lib-runtime";
|
13
|
+
import { MIDIMessageSubscriber } from "@opendaw/app-studio/src/midi/devices/MIDIMessageSubscriber";
|
13
14
|
export class MidiDevices {
|
14
15
|
static canRequestMidiAccess() { return "requestMIDIAccess" in navigator; }
|
15
16
|
static async requestPermission() {
|
@@ -29,6 +30,16 @@ export class MidiDevices {
|
|
29
30
|
}
|
30
31
|
}
|
31
32
|
static get() { return this.#midiAccess; }
|
33
|
+
static subscribeMessageEvents(observer, channel) {
|
34
|
+
return this.get().match({
|
35
|
+
none: () => {
|
36
|
+
const terminator = new Terminator();
|
37
|
+
terminator.own(this.available().subscribe(() => terminator.own(this.subscribeMessageEvents(observer, channel))));
|
38
|
+
return terminator;
|
39
|
+
},
|
40
|
+
some: midi => MIDIMessageSubscriber.subscribeMessageEvents(midi, observer, channel)
|
41
|
+
});
|
42
|
+
}
|
32
43
|
static inputs() {
|
33
44
|
return this.get().map(({ inputs }) => Array.from(inputs.values()));
|
34
45
|
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { Peaks } from "@opendaw/lib-fusion";
|
2
|
+
import { int, Nullable } from "@opendaw/lib-std";
|
3
|
+
export declare class PeaksWriter implements Peaks, Peaks.Stage {
|
4
|
+
#private;
|
5
|
+
readonly numChannels: int;
|
6
|
+
readonly data: Array<Int32Array>;
|
7
|
+
readonly stages: ReadonlyArray<Peaks.Stage>;
|
8
|
+
readonly dataOffset: int;
|
9
|
+
readonly shift: int;
|
10
|
+
readonly dataIndex: Int32Array;
|
11
|
+
constructor(numChannels: int);
|
12
|
+
set numFrames(value: int);
|
13
|
+
get numFrames(): int;
|
14
|
+
get numPeaks(): int;
|
15
|
+
unitsEachPeak(): int;
|
16
|
+
append(frames: ReadonlyArray<Float32Array>): void;
|
17
|
+
nearest(_unitsPerPixel: number): Nullable<Peaks.Stage>;
|
18
|
+
}
|
19
|
+
//# sourceMappingURL=PeaksWriter.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"PeaksWriter.d.ts","sourceRoot":"","sources":["../src/PeaksWriter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAmB,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAiB,GAAG,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAG9D,qBAAa,WAAY,YAAW,KAAK,EAAE,KAAK,CAAC,KAAK;;IAStC,QAAQ,CAAC,WAAW,EAAE,GAAG;IARrC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC3C,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAI;IAC5B,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAI;IACvB,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAA;gBAIT,WAAW,EAAE,GAAG;IAOrC,IAAI,SAAS,CAAC,KAAK,EAAE,GAAG,EAA2B;IACnD,IAAI,SAAS,IAAI,GAAG,CAAyB;IAC7C,IAAI,QAAQ,IAAI,GAAG,CAAwD;IAE3E,aAAa,IAAI,GAAG;IAEpB,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,IAAI;IAqBjD,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;CACzD"}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { SamplePeakWorker } from "@opendaw/lib-fusion";
|
2
|
+
import { Arrays, assert } from "@opendaw/lib-std";
|
3
|
+
import { RenderQuantum } from "./RenderQuantum";
|
4
|
+
export class PeaksWriter {
|
5
|
+
numChannels;
|
6
|
+
data;
|
7
|
+
stages;
|
8
|
+
dataOffset = 0;
|
9
|
+
shift = 7;
|
10
|
+
dataIndex;
|
11
|
+
#numFrames = 0 | 0;
|
12
|
+
constructor(numChannels) {
|
13
|
+
this.numChannels = numChannels;
|
14
|
+
this.data = Arrays.create(() => new Int32Array(1 << 10), numChannels);
|
15
|
+
this.dataIndex = new Int32Array(numChannels);
|
16
|
+
this.stages = [this];
|
17
|
+
}
|
18
|
+
set numFrames(value) { this.#numFrames = value; }
|
19
|
+
get numFrames() { return this.#numFrames; }
|
20
|
+
get numPeaks() { return Math.ceil(this.#numFrames / (1 << this.shift)); }
|
21
|
+
unitsEachPeak() { return 1 << this.shift; }
|
22
|
+
append(frames) {
|
23
|
+
for (let channel = 0; channel < this.numChannels; ++channel) {
|
24
|
+
const channelFrames = frames[channel];
|
25
|
+
assert(channelFrames.length === RenderQuantum, "Invalid number of frames.");
|
26
|
+
let min = Number.POSITIVE_INFINITY;
|
27
|
+
let max = Number.NEGATIVE_INFINITY;
|
28
|
+
for (let i = 0; i < RenderQuantum; ++i) {
|
29
|
+
const frame = channelFrames[i];
|
30
|
+
min = Math.min(frame, min);
|
31
|
+
max = Math.max(frame, max);
|
32
|
+
}
|
33
|
+
const channelData = this.data[channel];
|
34
|
+
channelData[this.dataIndex[channel]++] = SamplePeakWorker.pack(min, max);
|
35
|
+
if (this.dataIndex[channel] === channelData.length) {
|
36
|
+
const newArray = new Int32Array(channelData.length << 1);
|
37
|
+
newArray.set(channelData, 0);
|
38
|
+
this.data[channel] = newArray;
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
nearest(_unitsPerPixel) { return this.stages.at(0) ?? null; }
|
43
|
+
}
|