@opendaw/studio-core 0.0.101 → 0.0.103
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/AssetService.js +2 -2
- package/dist/EffectFactories.d.ts +2 -0
- package/dist/EffectFactories.d.ts.map +1 -1
- package/dist/EffectFactories.js +5 -0
- package/dist/Engine.d.ts +3 -0
- package/dist/Engine.d.ts.map +1 -1
- package/dist/EngineFacade.d.ts +3 -0
- package/dist/EngineFacade.d.ts.map +1 -1
- package/dist/EngineFacade.js +20 -2
- package/dist/EngineWorklet.d.ts +3 -0
- package/dist/EngineWorklet.d.ts.map +1 -1
- package/dist/EngineWorklet.js +97 -9
- package/dist/OfflineEngineRenderer.d.ts +3 -1
- package/dist/OfflineEngineRenderer.d.ts.map +1 -1
- package/dist/OfflineEngineRenderer.js +11 -2
- package/dist/StudioPreferences.d.ts +1 -0
- package/dist/StudioPreferences.d.ts.map +1 -1
- package/dist/StudioSettings.d.ts +1 -0
- package/dist/StudioSettings.d.ts.map +1 -1
- package/dist/StudioSettings.js +4 -2
- package/dist/capture/CaptureAudio.d.ts +3 -1
- package/dist/capture/CaptureAudio.d.ts.map +1 -1
- package/dist/capture/CaptureAudio.js +43 -18
- package/dist/capture/CaptureMidi.js +1 -1
- package/dist/capture/MonitoringMode.d.ts +2 -0
- package/dist/capture/MonitoringMode.d.ts.map +1 -0
- package/dist/capture/MonitoringMode.js +1 -0
- package/dist/capture/RecordAutomation.d.ts +6 -0
- package/dist/capture/RecordAutomation.d.ts.map +1 -0
- package/dist/capture/RecordAutomation.js +139 -0
- package/dist/capture/Recording.d.ts +3 -0
- package/dist/capture/Recording.d.ts.map +1 -1
- package/dist/capture/Recording.js +16 -36
- package/dist/capture/index.d.ts +2 -0
- package/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/index.js +2 -0
- package/dist/dawproject/DawProjectImporter.d.ts.map +1 -1
- package/dist/dawproject/DawProjectImporter.js +4 -0
- package/dist/offline-engine.js +1 -1
- package/dist/offline-engine.js.map +4 -4
- package/dist/processors.js +9 -9
- package/dist/processors.js.map +4 -4
- package/dist/project/Project.d.ts +2 -0
- package/dist/project/Project.d.ts.map +1 -1
- package/dist/project/Project.js +32 -12
- package/dist/project/ProjectApi.d.ts +3 -1
- package/dist/project/ProjectApi.d.ts.map +1 -1
- package/dist/project/ProjectApi.js +30 -17
- package/dist/project/ProjectMigration.d.ts.map +1 -1
- package/dist/project/ProjectMigration.js +3 -2
- package/dist/project/migration/MigrateNeuralAmpDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateNeuralAmpDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateNeuralAmpDeviceBox.js +29 -0
- package/dist/project/migration/index.d.ts +1 -0
- package/dist/project/migration/index.d.ts.map +1 -1
- package/dist/project/migration/index.js +1 -0
- package/dist/ui/clipboard/ClipboardManager.d.ts.map +1 -1
- package/dist/ui/clipboard/ClipboardManager.js +54 -8
- package/dist/ui/clipboard/ClipboardUtils.js +3 -3
- package/dist/ui/clipboard/types/AudioUnitsClipboardHandler.d.ts.map +1 -1
- package/dist/ui/clipboard/types/AudioUnitsClipboardHandler.js +6 -0
- package/dist/ui/clipboard/types/DevicesClipboardHandler.js +1 -1
- package/dist/ui/clipboard/types/RegionsClipboardHandler.d.ts.map +1 -1
- package/dist/ui/clipboard/types/RegionsClipboardHandler.js +4 -0
- package/dist/ui/menu/MenuItems.d.ts +2 -2
- package/dist/ui/menu/MenuItems.d.ts.map +1 -1
- package/dist/ui/timeline/RegionClipResolver.d.ts +2 -2
- package/dist/ui/timeline/RegionClipResolver.d.ts.map +1 -1
- package/dist/ui/timeline/RegionClipResolver.js +40 -37
- package/dist/ui/timeline/RegionClipResolver.test.js +400 -0
- package/dist/workers-main.js +1 -1
- package/dist/workers-main.js.map +3 -3
- package/dist/ysync/YService.d.ts.map +1 -1
- package/dist/ysync/YService.js +1 -2
- package/package.json +15 -15
package/dist/AssetService.js
CHANGED
|
@@ -32,7 +32,7 @@ export class AssetService {
|
|
|
32
32
|
}
|
|
33
33
|
const { error, status, value: files } = await Promises.tryCatch(Files.open({ ...this.filePickerOptions, multiple: false }));
|
|
34
34
|
if (status === "rejected") {
|
|
35
|
-
if (Errors.isAbort(error)) {
|
|
35
|
+
if (Errors.isAbort(error) || Errors.isNotAllowed(error)) {
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
@@ -54,7 +54,7 @@ export class AssetService {
|
|
|
54
54
|
async browseFiles(multiple, filePickerSettings) {
|
|
55
55
|
const { error, status, value: files } = await Promises.tryCatch(Files.open({ ...filePickerSettings, multiple }));
|
|
56
56
|
if (status === "rejected") {
|
|
57
|
-
if (Errors.isAbort(error)) {
|
|
57
|
+
if (Errors.isAbort(error) || Errors.isNotAllowed(error)) {
|
|
58
58
|
return [];
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
@@ -34,6 +34,7 @@ export declare namespace EffectFactories {
|
|
|
34
34
|
Crusher: EffectFactory;
|
|
35
35
|
Fold: EffectFactory;
|
|
36
36
|
Tidal: EffectFactory;
|
|
37
|
+
NeuralAmp: EffectFactory;
|
|
37
38
|
Maximizer: EffectFactory;
|
|
38
39
|
};
|
|
39
40
|
const MidiList: ReadonlyArray<Readonly<EffectFactory>>;
|
|
@@ -49,6 +50,7 @@ export declare namespace EffectFactories {
|
|
|
49
50
|
Crusher: EffectFactory;
|
|
50
51
|
Fold: EffectFactory;
|
|
51
52
|
Tidal: EffectFactory;
|
|
53
|
+
NeuralAmp: EffectFactory;
|
|
52
54
|
Maximizer: EffectFactory;
|
|
53
55
|
Arpeggio: EffectFactory;
|
|
54
56
|
Pitch: EffectFactory;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EffectFactories.d.ts","sourceRoot":"","sources":["../src/EffectFactories.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAG7C,yBAAiB,eAAe,CAAC;IACtB,MAAM,QAAQ,EAAE,aAatB,CAAA;IAEM,MAAM,KAAK,EAAE,aAanB,CAAA;IAEM,MAAM,QAAQ,EAAE,aAatB,CAAA;IAEM,MAAM,SAAS,EAAE,aA8BvB,CAAA;IAEM,MAAM,UAAU,EAAE,aAcxB,CAAA;IAEM,MAAM,KAAK,EAAE,aAcnB,CAAA;IAEM,MAAM,cAAc,EAAE,aAc5B,CAAA;IAEM,MAAM,SAAS,EAAE,aAavB,CAAA;IAEM,MAAM,UAAU,EAAE,aAcxB,CAAA;IAEM,MAAM,IAAI,EAAE,aAalB,CAAA;IAEM,MAAM,MAAM,EAAE,aAcpB,CAAA;IAEM,MAAM,OAAO,EAAE,aAarB,CAAA;IAEM,MAAM,IAAI,EAAE,aAalB,CAAA;IAEM,MAAM,KAAK,EAAE,aAcnB,CAAA;IAEM,MAAM,MAAM,EAAE,aAapB,CAAA;IAEM,MAAM,SAAS,EAAE,aAavB,CAAA;IAEM,MAAM,OAAO,EAAE,aAqDrB,CAAA;IAEM,MAAM,SAAS;;;;;KAKrB,CAAA;
|
|
1
|
+
{"version":3,"file":"EffectFactories.d.ts","sourceRoot":"","sources":["../src/EffectFactories.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAG7C,yBAAiB,eAAe,CAAC;IACtB,MAAM,QAAQ,EAAE,aAatB,CAAA;IAEM,MAAM,KAAK,EAAE,aAanB,CAAA;IAEM,MAAM,QAAQ,EAAE,aAatB,CAAA;IAEM,MAAM,SAAS,EAAE,aA8BvB,CAAA;IAEM,MAAM,UAAU,EAAE,aAcxB,CAAA;IAEM,MAAM,KAAK,EAAE,aAcnB,CAAA;IAEM,MAAM,cAAc,EAAE,aAc5B,CAAA;IAEM,MAAM,SAAS,EAAE,aAavB,CAAA;IAEM,MAAM,UAAU,EAAE,aAcxB,CAAA;IAEM,MAAM,IAAI,EAAE,aAalB,CAAA;IAEM,MAAM,MAAM,EAAE,aAcpB,CAAA;IAEM,MAAM,OAAO,EAAE,aAarB,CAAA;IAEM,MAAM,IAAI,EAAE,aAalB,CAAA;IAEM,MAAM,KAAK,EAAE,aAcnB,CAAA;IAEM,MAAM,MAAM,EAAE,aAapB,CAAA;IAEM,MAAM,SAAS,EAAE,aAavB,CAAA;IAEM,MAAM,OAAO,EAAE,aAqDrB,CAAA;IAEM,MAAM,SAAS;;;;;KAKrB,CAAA;IAIM,MAAM,UAAU;;;;;;;;;;;;;KAatB,CAAA;IAIM,MAAM,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAChC,CAAA;IACrB,MAAM,SAAS,EAAE,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAChC,CAAA;IACtB,MAAM,WAAW;;;;;;;;;;;;;;;;;KAAgC,CAAA;IACxD,KAAY,cAAc,GAAG,MAAM,OAAO,SAAS,CAAA;IACnD,KAAY,eAAe,GAAG,MAAM,OAAO,UAAU,CAAA;CACxD"}
|
package/dist/EffectFactories.js
CHANGED
|
@@ -270,6 +270,7 @@ export var EffectFactories;
|
|
|
270
270
|
Velocity: EffectFactories.Velocity,
|
|
271
271
|
Zeitgeist: EffectFactories.Zeitgeist
|
|
272
272
|
};
|
|
273
|
+
const includeNeuralAmp = false;
|
|
273
274
|
EffectFactories.AudioNamed = {
|
|
274
275
|
StereoTool: EffectFactories.StereoTool,
|
|
275
276
|
Compressor: EffectFactories.Compressor,
|
|
@@ -281,8 +282,12 @@ export var EffectFactories;
|
|
|
281
282
|
Crusher: EffectFactories.Crusher,
|
|
282
283
|
Fold: EffectFactories.Fold,
|
|
283
284
|
Tidal: EffectFactories.Tidal,
|
|
285
|
+
NeuralAmp: EffectFactories.NeuralAmp,
|
|
284
286
|
Maximizer: EffectFactories.Maximizer
|
|
285
287
|
};
|
|
288
|
+
if (!includeNeuralAmp) {
|
|
289
|
+
delete EffectFactories.AudioNamed.NeuralAmp;
|
|
290
|
+
}
|
|
286
291
|
EffectFactories.MidiList = Object.values(EffectFactories.MidiNamed);
|
|
287
292
|
EffectFactories.AudioList = Object.values(EffectFactories.AudioNamed);
|
|
288
293
|
EffectFactories.MergedNamed = { ...EffectFactories.MidiNamed, ...EffectFactories.AudioNamed };
|
package/dist/Engine.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface Engine extends Terminable {
|
|
|
21
21
|
scheduleClipPlay(clipIds: ReadonlyArray<UUID.Bytes>): void;
|
|
22
22
|
scheduleClipStop(trackIds: ReadonlyArray<UUID.Bytes>): void;
|
|
23
23
|
subscribeClipNotification(observer: Observer<ClipNotification>): Subscription;
|
|
24
|
+
registerMonitoringSource(uuid: UUID.Bytes, node: AudioNode, numChannels: 1 | 2): void;
|
|
25
|
+
unregisterMonitoringSource(uuid: UUID.Bytes): void;
|
|
24
26
|
get position(): ObservableValue<ppqn>;
|
|
25
27
|
get bpm(): ObservableValue<bpm>;
|
|
26
28
|
get isPlaying(): ObservableValue<boolean>;
|
|
@@ -29,6 +31,7 @@ export interface Engine extends Terminable {
|
|
|
29
31
|
get playbackTimestamp(): ObservableValue<ppqn>;
|
|
30
32
|
get countInBeatsRemaining(): ObservableValue<number>;
|
|
31
33
|
get markerState(): ObservableValue<Nullable<[UUID.Bytes, int]>>;
|
|
34
|
+
get cpuLoad(): ObservableValue<number>;
|
|
32
35
|
get project(): Project;
|
|
33
36
|
get preferences(): EnginePreferences;
|
|
34
37
|
get perfBuffer(): Float32Array;
|
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,GAAG,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACzG,OAAO,EAAC,SAAS,EAAE,GAAG,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAC,gBAAgB,EAAE,iBAAiB,EAAE,UAAU,EAAC,MAAM,0BAA0B,CAAA;AACxF,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAEjC,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,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7C,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,KAAK,IAAI,IAAI,CAAA;IACb,IAAI,IAAI,IAAI,CAAA;IACZ,cAAc,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IACnD,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,KAAK,GAAG,IAAI,CAAA;IACxC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IAC1D,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IAC3D,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../src/Engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACzG,OAAO,EAAC,SAAS,EAAE,GAAG,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAC,gBAAgB,EAAE,iBAAiB,EAAE,UAAU,EAAC,MAAM,0BAA0B,CAAA;AACxF,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAEjC,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,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7C,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,KAAK,IAAI,IAAI,CAAA;IACb,IAAI,IAAI,IAAI,CAAA;IACZ,cAAc,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IACnD,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,KAAK,GAAG,IAAI,CAAA;IACxC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IAC1D,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IAC3D,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,YAAY,CAAA;IAC7E,wBAAwB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IACrF,0BAA0B,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;IAElD,IAAI,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,CAAA;IACrC,IAAI,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,CAAA;IAC/B,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,iBAAiB,IAAI,eAAe,CAAC,IAAI,CAAC,CAAA;IAC9C,IAAI,qBAAqB,IAAI,eAAe,CAAC,MAAM,CAAC,CAAA;IACpD,IAAI,WAAW,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;IAC/D,IAAI,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAA;IACtC,IAAI,OAAO,IAAI,OAAO,CAAA;IACtB,IAAI,WAAW,IAAI,iBAAiB,CAAA;IACpC,IAAI,UAAU,IAAI,YAAY,CAAA;IAC9B,IAAI,SAAS,IAAI,MAAM,CAAA;CAC1B"}
|
package/dist/EngineFacade.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export declare class EngineFacade implements Engine {
|
|
|
23
23
|
get playbackTimestamp(): ObservableValue<ppqn>;
|
|
24
24
|
get countInBeatsRemaining(): ObservableValue<int>;
|
|
25
25
|
get markerState(): DefaultObservableValue<Nullable<[UUID.Bytes, int]>>;
|
|
26
|
+
get cpuLoad(): ObservableValue<number>;
|
|
26
27
|
get project(): Project;
|
|
27
28
|
get sampleRate(): number;
|
|
28
29
|
get preferences(): EnginePreferences;
|
|
@@ -40,6 +41,8 @@ export declare class EngineFacade implements Engine {
|
|
|
40
41
|
noteSignal(signal: NoteSignal): void;
|
|
41
42
|
scheduleClipPlay(clipIds: ReadonlyArray<UUID.Bytes>): void;
|
|
42
43
|
scheduleClipStop(trackIds: ReadonlyArray<UUID.Bytes>): void;
|
|
44
|
+
registerMonitoringSource(uuid: UUID.Bytes, node: AudioNode, numChannels: 1 | 2): void;
|
|
45
|
+
unregisterMonitoringSource(uuid: UUID.Bytes): void;
|
|
43
46
|
terminate(): void;
|
|
44
47
|
}
|
|
45
48
|
//# sourceMappingURL=EngineFacade.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EngineFacade.d.ts","sourceRoot":"","sources":["../src/EngineFacade.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EACtB,GAAG,EACH,QAAQ,EACR,eAAe,EACf,QAAQ,EAER,YAAY,EAEZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,SAAS,EAAE,GAAG,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACrD,OAAO,EACH,gBAAgB,EAChB,iBAAiB,EAGjB,UAAU,EAEb,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAGjC,qBAAa,YAAa,YAAW,MAAM;;;
|
|
1
|
+
{"version":3,"file":"EngineFacade.d.ts","sourceRoot":"","sources":["../src/EngineFacade.ts"],"names":[],"mappings":"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"}
|
package/dist/EngineFacade.js
CHANGED
|
@@ -12,6 +12,7 @@ export class EngineFacade {
|
|
|
12
12
|
#isRecording = new DefaultObservableValue(false);
|
|
13
13
|
#isCountingIn = new DefaultObservableValue(false);
|
|
14
14
|
#markerState = new DefaultObservableValue(null);
|
|
15
|
+
#cpuLoad = new DefaultObservableValue(0);
|
|
15
16
|
#preferencesFacade;
|
|
16
17
|
#worklet = Option.None;
|
|
17
18
|
constructor() {
|
|
@@ -21,7 +22,7 @@ export class EngineFacade {
|
|
|
21
22
|
this.#worklet = Option.wrap(worklet);
|
|
22
23
|
this.#preferencesFacade.setHost(worklet.preferences);
|
|
23
24
|
this.#lifecycle.terminate();
|
|
24
|
-
this.#lifecycle.ownAll(worklet.playbackTimestamp.catchupAndSubscribe(owner => this.#playbackTimestamp.setValue(owner.getValue())), worklet.countInBeatsRemaining.catchupAndSubscribe(owner => this.#countInBeatsRemaining.setValue(owner.getValue())), worklet.position.catchupAndSubscribe(owner => this.#position.setValue(owner.getValue())), worklet.bpm.catchupAndSubscribe(owner => this.#bpm.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.markerState.catchupAndSubscribe(owner => this.#markerState.setValue(owner.getValue())));
|
|
25
|
+
this.#lifecycle.ownAll(worklet.playbackTimestamp.catchupAndSubscribe(owner => this.#playbackTimestamp.setValue(owner.getValue())), worklet.countInBeatsRemaining.catchupAndSubscribe(owner => this.#countInBeatsRemaining.setValue(owner.getValue())), worklet.position.catchupAndSubscribe(owner => this.#position.setValue(owner.getValue())), worklet.bpm.catchupAndSubscribe(owner => this.#bpm.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.markerState.catchupAndSubscribe(owner => this.#markerState.setValue(owner.getValue())), worklet.cpuLoad.catchupAndSubscribe(owner => this.#cpuLoad.setValue(owner.getValue())));
|
|
25
26
|
}
|
|
26
27
|
assertWorklet() { this.#worklet.unwrap("No worklet available"); }
|
|
27
28
|
releaseWorklet() {
|
|
@@ -30,7 +31,17 @@ export class EngineFacade {
|
|
|
30
31
|
this.#lifecycle.terminate();
|
|
31
32
|
this.#worklet = Option.None;
|
|
32
33
|
}
|
|
33
|
-
play() {
|
|
34
|
+
play() {
|
|
35
|
+
this.#worklet.ifSome(worklet => {
|
|
36
|
+
const context = worklet.context;
|
|
37
|
+
if (context.state === "suspended") {
|
|
38
|
+
context.resume().then(() => worklet.play());
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
worklet.play();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
34
45
|
stop(reset = false) { this.#worklet.ifSome(worklet => worklet.stop(reset)); }
|
|
35
46
|
setPosition(position) { this.#worklet.ifSome(worklet => worklet.setPosition(position)); }
|
|
36
47
|
prepareRecordingState(countIn) { this.#worklet.ifSome(worklet => worklet.prepareRecordingState(countIn)); }
|
|
@@ -43,6 +54,7 @@ export class EngineFacade {
|
|
|
43
54
|
get playbackTimestamp() { return this.#playbackTimestamp; }
|
|
44
55
|
get countInBeatsRemaining() { return this.#countInBeatsRemaining; }
|
|
45
56
|
get markerState() { return this.#markerState; }
|
|
57
|
+
get cpuLoad() { return this.#cpuLoad; }
|
|
46
58
|
get project() { return this.#worklet.unwrap("No worklet to get project").project; }
|
|
47
59
|
get sampleRate() { return this.#worklet.isEmpty() ? 44_100 : this.#worklet.unwrap().context.sampleRate; }
|
|
48
60
|
get preferences() { return this.#preferencesFacade; }
|
|
@@ -76,6 +88,12 @@ export class EngineFacade {
|
|
|
76
88
|
scheduleClipStop(trackIds) {
|
|
77
89
|
this.#worklet.unwrap("No worklet to scheduleClipStop").scheduleClipStop(trackIds);
|
|
78
90
|
}
|
|
91
|
+
registerMonitoringSource(uuid, node, numChannels) {
|
|
92
|
+
this.#worklet.ifSome(worklet => worklet.registerMonitoringSource(uuid, node, numChannels));
|
|
93
|
+
}
|
|
94
|
+
unregisterMonitoringSource(uuid) {
|
|
95
|
+
this.#worklet.ifSome(worklet => worklet.unregisterMonitoringSource(uuid));
|
|
96
|
+
}
|
|
79
97
|
terminate() {
|
|
80
98
|
this.releaseWorklet();
|
|
81
99
|
this.#terminator.terminate();
|
package/dist/EngineWorklet.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare class EngineWorklet extends AudioWorkletNode implements Engine {
|
|
|
27
27
|
get markerState(): ObservableValue<Nullable<[UUID.Bytes, int]>>;
|
|
28
28
|
get project(): Project;
|
|
29
29
|
get preferences(): PreferencesHost<EngineSettings>;
|
|
30
|
+
get cpuLoad(): ObservableValue<number>;
|
|
30
31
|
get perfBuffer(): Float32Array;
|
|
31
32
|
get perfIndex(): number;
|
|
32
33
|
isReady(): Promise<void>;
|
|
@@ -37,6 +38,8 @@ export declare class EngineWorklet extends AudioWorkletNode implements Engine {
|
|
|
37
38
|
scheduleClipPlay(clipIds: ReadonlyArray<UUID.Bytes>): void;
|
|
38
39
|
scheduleClipStop(trackIds: ReadonlyArray<UUID.Bytes>): void;
|
|
39
40
|
subscribeClipNotification(observer: Observer<ClipNotification>): Subscription;
|
|
41
|
+
registerMonitoringSource(uuid: UUID.Bytes, node: AudioNode, numChannels: 1 | 2): void;
|
|
42
|
+
unregisterMonitoringSource(uuid: UUID.Bytes): void;
|
|
40
43
|
terminate(): void;
|
|
41
44
|
}
|
|
42
45
|
//# sourceMappingURL=EngineWorklet.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EngineWorklet.d.ts","sourceRoot":"","sources":["../src/EngineWorklet.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,GAAG,
|
|
1
|
+
{"version":3,"file":"EngineWorklet.d.ts","sourceRoot":"","sources":["../src/EngineWorklet.ts"],"names":[],"mappings":"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"}
|
package/dist/EngineWorklet.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Arrays, DefaultObservableValue, Notifier, Option, SyncStream, Terminator, UUID } from "@opendaw/lib-std";
|
|
1
|
+
import { Arrays, DefaultObservableValue, isDefined, Notifier, Option, SyncStream, Terminator, UUID } from "@opendaw/lib-std";
|
|
2
|
+
import { RenderQuantum } from "@opendaw/lib-dsp";
|
|
3
|
+
import { Communicator, Messenger } from "@opendaw/lib-runtime";
|
|
4
|
+
import { EngineSettingsSchema, EngineStateSchema, ExportStemsConfiguration, PERF_BUFFER_SIZE, PreferencesHost } from "@opendaw/studio-adapters";
|
|
2
5
|
import { SyncSource } from "@opendaw/lib-box";
|
|
3
6
|
import { AnimationFrame } from "@opendaw/lib-dom";
|
|
4
|
-
import { Communicator, Messenger } from "@opendaw/lib-runtime";
|
|
5
|
-
import { EngineSettingsSchema, EngineStateSchema, ExportStemsConfiguration, PreferencesHost } from "@opendaw/studio-adapters";
|
|
6
7
|
import { MIDIReceiver } from "./midi";
|
|
7
8
|
import { HRClockWorker } from "./HRClockWorker";
|
|
8
9
|
export class EngineWorklet extends AudioWorkletNode {
|
|
@@ -19,6 +20,7 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
|
19
20
|
#countInBeatsRemaining = new DefaultObservableValue(0);
|
|
20
21
|
#preferences;
|
|
21
22
|
#markerState = new DefaultObservableValue(null);
|
|
23
|
+
#cpuLoad = new DefaultObservableValue(0);
|
|
22
24
|
#controlFlags;
|
|
23
25
|
#notifyClipNotification;
|
|
24
26
|
#notifyNoteSignals;
|
|
@@ -27,8 +29,15 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
|
27
29
|
#isReady;
|
|
28
30
|
#perfBuffer = new Float32Array(0);
|
|
29
31
|
#perfIndex = 0;
|
|
32
|
+
#lastPerfReadIndex = 0;
|
|
33
|
+
#consecutiveOverloadCount = 0;
|
|
34
|
+
#lastCpuLoadUpdate = 0;
|
|
35
|
+
#maxMsSinceLastUpdate = 0;
|
|
36
|
+
#channelMerger = null;
|
|
37
|
+
#monitoringSources = new Map();
|
|
30
38
|
constructor(context, project, exportConfiguration, options) {
|
|
31
39
|
const numberOfChannels = ExportStemsConfiguration.countStems(Option.wrap(exportConfiguration)) * 2;
|
|
40
|
+
const budgetMs = (RenderQuantum / context.sampleRate) * 1000;
|
|
32
41
|
const reader = SyncStream.reader(EngineStateSchema(), state => {
|
|
33
42
|
this.#isPlaying.setValue(state.isPlaying);
|
|
34
43
|
this.#isRecording.setValue(state.isRecording);
|
|
@@ -38,11 +47,12 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
|
38
47
|
this.#bpm.setValue(state.bpm);
|
|
39
48
|
this.#perfBuffer = state.perfBuffer;
|
|
40
49
|
this.#perfIndex = state.perfIndex;
|
|
50
|
+
this.#updateCpuLoad(budgetMs, project);
|
|
41
51
|
this.#position.setValue(state.position); // This must be the last to handle the state values before
|
|
42
52
|
});
|
|
43
53
|
const controlFlagsSAB = new SharedArrayBuffer(4); // 4 bytes minimum
|
|
44
54
|
super(context, "engine-processor", {
|
|
45
|
-
numberOfInputs:
|
|
55
|
+
numberOfInputs: 1,
|
|
46
56
|
numberOfOutputs: 1,
|
|
47
57
|
outputChannelCount: [numberOfChannels],
|
|
48
58
|
processorOptions: {
|
|
@@ -92,6 +102,9 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
|
92
102
|
setupMIDI(port, buffer) {
|
|
93
103
|
dispatcher.dispatchAndForget(this.setupMIDI, port, buffer);
|
|
94
104
|
}
|
|
105
|
+
updateMonitoringMap(map) {
|
|
106
|
+
dispatcher.dispatchAndForget(this.updateMonitoringMap, map);
|
|
107
|
+
}
|
|
95
108
|
terminate() { dispatcher.dispatchAndForget(this.terminate); }
|
|
96
109
|
}));
|
|
97
110
|
const { port, sab } = this.#terminator.own(MIDIReceiver.create(() => context instanceof AudioContext ? context.outputLatency * 1000 : 20, (deviceId, data, relativeTimeInMs) => this.#project.receivedMIDIFromEngine(deviceId, data, relativeTimeInMs)));
|
|
@@ -152,20 +165,25 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
|
152
165
|
this.#preferences = this.#terminator.own(new PreferencesHost(EngineSettingsSchema.parse({})));
|
|
153
166
|
this.#terminator.ownAll(AnimationFrame.add(() => reader.tryRead()), project.liveStreamReceiver.connect(messenger.channel("engine-live-data")), this.#preferences.syncWith(messenger.channel("engine-preferences")), new SyncSource(project.boxGraph, messenger.channel("engine-sync"), false));
|
|
154
167
|
}
|
|
155
|
-
play() {
|
|
156
|
-
|
|
168
|
+
play() {
|
|
169
|
+
this.wake();
|
|
170
|
+
this.#commands.play();
|
|
171
|
+
}
|
|
172
|
+
stop(reset = false) {
|
|
173
|
+
this.#isPlaying.setValue(false);
|
|
174
|
+
this.#commands.stop(reset);
|
|
175
|
+
}
|
|
157
176
|
setPosition(position) { this.#commands.setPosition(position); }
|
|
158
177
|
prepareRecordingState(countIn) { this.#commands.prepareRecordingState(countIn); }
|
|
159
178
|
stopRecording() { this.#commands.stopRecording(); }
|
|
160
179
|
panic() { this.#commands.panic(); }
|
|
161
180
|
sleep() {
|
|
162
181
|
Atomics.store(this.#controlFlags, 0, 1);
|
|
182
|
+
this.#isPlaying.setValue(false);
|
|
163
183
|
this.#commands.stop(true);
|
|
164
184
|
}
|
|
165
185
|
wake() { Atomics.store(this.#controlFlags, 0, 0); }
|
|
166
|
-
loadClickSound(index, data) {
|
|
167
|
-
this.#commands.loadClickSound(index, data);
|
|
168
|
-
}
|
|
186
|
+
loadClickSound(index, data) { this.#commands.loadClickSound(index, data); }
|
|
169
187
|
get isPlaying() { return this.#isPlaying; }
|
|
170
188
|
get isRecording() { return this.#isRecording; }
|
|
171
189
|
get isCountingIn() { return this.#isCountingIn; }
|
|
@@ -176,6 +194,7 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
|
176
194
|
get markerState() { return this.#markerState; }
|
|
177
195
|
get project() { return this.#project; }
|
|
178
196
|
get preferences() { return this.#preferences; }
|
|
197
|
+
get cpuLoad() { return this.#cpuLoad; }
|
|
179
198
|
get perfBuffer() { return this.#perfBuffer; }
|
|
180
199
|
get perfIndex() { return this.#perfIndex; }
|
|
181
200
|
isReady() { return this.#isReady; }
|
|
@@ -197,6 +216,75 @@ export class EngineWorklet extends AudioWorkletNode {
|
|
|
197
216
|
});
|
|
198
217
|
return this.#notifyClipNotification.subscribe(observer);
|
|
199
218
|
}
|
|
219
|
+
registerMonitoringSource(uuid, node, numChannels) {
|
|
220
|
+
this.#monitoringSources.set(UUID.toString(uuid), { node, numChannels });
|
|
221
|
+
this.#rebuildMonitoringMerger();
|
|
222
|
+
}
|
|
223
|
+
unregisterMonitoringSource(uuid) {
|
|
224
|
+
const key = UUID.toString(uuid);
|
|
225
|
+
const entry = this.#monitoringSources.get(key);
|
|
226
|
+
if (isDefined(entry)) {
|
|
227
|
+
entry.node.disconnect();
|
|
228
|
+
this.#monitoringSources.delete(key);
|
|
229
|
+
}
|
|
230
|
+
this.#rebuildMonitoringMerger();
|
|
231
|
+
}
|
|
232
|
+
#rebuildMonitoringMerger() {
|
|
233
|
+
if (isDefined(this.#channelMerger)) {
|
|
234
|
+
this.#channelMerger.disconnect();
|
|
235
|
+
this.#channelMerger = null;
|
|
236
|
+
}
|
|
237
|
+
if (this.#monitoringSources.size === 0) {
|
|
238
|
+
this.#commands.updateMonitoringMap([]);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
let totalChannels = 0;
|
|
242
|
+
for (const { numChannels } of this.#monitoringSources.values()) {
|
|
243
|
+
totalChannels += numChannels;
|
|
244
|
+
}
|
|
245
|
+
this.#channelMerger = this.context.createChannelMerger(totalChannels);
|
|
246
|
+
this.#channelMerger.connect(this);
|
|
247
|
+
const map = [];
|
|
248
|
+
let channel = 0;
|
|
249
|
+
for (const [uuidString, { node, numChannels }] of this.#monitoringSources) {
|
|
250
|
+
const uuid = UUID.parse(uuidString);
|
|
251
|
+
const splitter = this.context.createChannelSplitter(numChannels);
|
|
252
|
+
node.connect(splitter);
|
|
253
|
+
const channels = [];
|
|
254
|
+
for (let i = 0; i < numChannels; i++) {
|
|
255
|
+
splitter.connect(this.#channelMerger, i, channel);
|
|
256
|
+
channels.push(channel);
|
|
257
|
+
channel++;
|
|
258
|
+
}
|
|
259
|
+
map.push({ uuid, channels });
|
|
260
|
+
}
|
|
261
|
+
this.#commands.updateMonitoringMap(map);
|
|
262
|
+
}
|
|
263
|
+
#updateCpuLoad(budgetMs, project) {
|
|
264
|
+
while (this.#lastPerfReadIndex !== this.#perfIndex) {
|
|
265
|
+
const ms = this.#perfBuffer[this.#lastPerfReadIndex];
|
|
266
|
+
if (ms > this.#maxMsSinceLastUpdate) {
|
|
267
|
+
this.#maxMsSinceLastUpdate = ms;
|
|
268
|
+
}
|
|
269
|
+
if (ms >= budgetMs) {
|
|
270
|
+
this.#consecutiveOverloadCount++;
|
|
271
|
+
if (this.#consecutiveOverloadCount >= 30) {
|
|
272
|
+
project.handleCpuOverload();
|
|
273
|
+
this.#consecutiveOverloadCount = 0;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
this.#consecutiveOverloadCount = 0;
|
|
278
|
+
}
|
|
279
|
+
this.#lastPerfReadIndex = (this.#lastPerfReadIndex + 1) % PERF_BUFFER_SIZE;
|
|
280
|
+
}
|
|
281
|
+
const now = performance.now();
|
|
282
|
+
if (now - this.#lastCpuLoadUpdate >= 1000) {
|
|
283
|
+
this.#cpuLoad.setValue(Math.round((this.#maxMsSinceLastUpdate / budgetMs) * 100));
|
|
284
|
+
this.#maxMsSinceLastUpdate = 0;
|
|
285
|
+
this.#lastCpuLoadUpdate = now;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
200
288
|
terminate() {
|
|
201
289
|
this.#commands.terminate();
|
|
202
290
|
this.#terminator.terminate();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { int, Option, Progress } from "@opendaw/lib-std";
|
|
2
|
-
import { AudioData } from "@opendaw/lib-dsp";
|
|
2
|
+
import { AudioData, ppqn } from "@opendaw/lib-dsp";
|
|
3
3
|
import { ExportStemsConfiguration, OfflineEngineRenderConfig } from "@opendaw/studio-adapters";
|
|
4
4
|
import { Project } from "./project";
|
|
5
5
|
export declare class OfflineEngineRenderer {
|
|
@@ -14,6 +14,8 @@ export declare class OfflineEngineRenderer {
|
|
|
14
14
|
get totalFrames(): int;
|
|
15
15
|
play(): void;
|
|
16
16
|
stop(): void;
|
|
17
|
+
setPosition(position: ppqn): void;
|
|
18
|
+
waitForLoading(): Promise<void>;
|
|
17
19
|
terminate(): void;
|
|
18
20
|
step(samples: int): Promise<Float32Array[]>;
|
|
19
21
|
render(config: OfflineEngineRenderConfig, progress: Progress.Handler, abortSignal?: AbortSignal): Promise<AudioData>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OfflineEngineRenderer.d.ts","sourceRoot":"","sources":["../src/OfflineEngineRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,GAAG,EAAa,MAAM,EAAS,QAAQ,EAA6B,MAAM,kBAAkB,CAAA;AAC5G,OAAO,EAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"OfflineEngineRenderer.d.ts","sourceRoot":"","sources":["../src/OfflineEngineRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,GAAG,EAAa,MAAM,EAAS,QAAQ,EAA6B,MAAM,kBAAkB,CAAA;AAC5G,OAAO,EAAC,SAAS,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAEhD,OAAO,EAIH,wBAAwB,EAKxB,yBAAyB,EAC5B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAOjC,qBAAa,qBAAqB;;IAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKjC,MAAM,CAAC,YAAY,IAAI,MAAM;WAIhB,MAAM,CAAC,MAAM,EAAE,OAAO,EACf,sBAAsB,EAAE,MAAM,CAAC,wBAAwB,CAAC,EACxD,UAAU,GAAE,GAAY,GACzC,OAAO,CAAC,qBAAqB,CAAC;WAoHpB,KAAK,CAAC,MAAM,EAAE,OAAO,EACf,sBAAsB,EAAE,MAAM,CAAC,wBAAwB,CAAC,EACxD,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAC1B,WAAW,CAAC,EAAE,WAAW,EACzB,UAAU,GAAE,GAAY,GACxC,OAAO,CAAC,SAAS,CAAC;IAwBrB,OAAO;IAkBP,IAAI,UAAU,IAAI,GAAG,CAA0B;IAC/C,IAAI,gBAAgB,IAAI,GAAG,CAAgC;IAC3D,IAAI,WAAW,IAAI,GAAG,CAA2B;IAEjD,IAAI,IAAI,IAAI;IAIZ,IAAI,IAAI,IAAI;IAKZ,WAAW,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI;IAI3B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrC,SAAS,IAAI,IAAI;IAKX,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAM3C,MAAM,CACR,MAAM,EAAE,yBAAyB,EACjC,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAC1B,WAAW,CAAC,EAAE,WAAW,GAC1B,OAAO,CAAC,SAAS,CAAC;CAqCxB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Errors, isDefined, Option, panic, Terminator, TimeSpan } from "@opendaw/lib-std";
|
|
2
2
|
import { AudioData } from "@opendaw/lib-dsp";
|
|
3
3
|
import { Communicator, Messenger, Wait } from "@opendaw/lib-runtime";
|
|
4
|
-
import { ExportStemsConfiguration } from "@opendaw/studio-adapters";
|
|
4
|
+
import { EngineStateSchema, ExportStemsConfiguration } from "@opendaw/studio-adapters";
|
|
5
5
|
import { AudioWorklets } from "./AudioWorklets";
|
|
6
6
|
import { MIDIReceiver } from "./midi";
|
|
7
7
|
let workerUrl = Option.None;
|
|
@@ -35,7 +35,7 @@ export class OfflineEngineRenderer {
|
|
|
35
35
|
});
|
|
36
36
|
const channel = new MessageChannel();
|
|
37
37
|
const progressChannel = new MessageChannel();
|
|
38
|
-
const syncStreamBuffer = new SharedArrayBuffer(
|
|
38
|
+
const syncStreamBuffer = new SharedArrayBuffer(EngineStateSchema().bytesTotal + 1);
|
|
39
39
|
const controlFlagsBuffer = new SharedArrayBuffer(4);
|
|
40
40
|
const terminator = new Terminator();
|
|
41
41
|
const engineMessenger = Messenger.for(channel.port2);
|
|
@@ -90,6 +90,7 @@ export class OfflineEngineRenderer {
|
|
|
90
90
|
scheduleClipPlay(clipIds) { dispatcher.dispatchAndForget(this.scheduleClipPlay, clipIds); }
|
|
91
91
|
scheduleClipStop(trackIds) { dispatcher.dispatchAndForget(this.scheduleClipStop, trackIds); }
|
|
92
92
|
setupMIDI(port, buffer) { dispatcher.dispatchAndForget(this.setupMIDI, port, buffer); }
|
|
93
|
+
updateMonitoringMap(map) { dispatcher.dispatchAndForget(this.updateMonitoringMap, map); }
|
|
93
94
|
loadClickSound(index, data) { dispatcher.dispatchAndForget(this.loadClickSound, index, data); }
|
|
94
95
|
terminate() { dispatcher.dispatchAndForget(this.terminate); }
|
|
95
96
|
});
|
|
@@ -149,6 +150,14 @@ export class OfflineEngineRenderer {
|
|
|
149
150
|
this.#engineCommands.stop(true);
|
|
150
151
|
this.#protocol.stop();
|
|
151
152
|
}
|
|
153
|
+
setPosition(position) {
|
|
154
|
+
this.#engineCommands.setPosition(position);
|
|
155
|
+
}
|
|
156
|
+
async waitForLoading() {
|
|
157
|
+
while (!await this.#engineCommands.queryLoadingComplete()) {
|
|
158
|
+
await Wait.timeSpan(TimeSpan.millis(100));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
152
161
|
terminate() {
|
|
153
162
|
this.#terminator.terminate();
|
|
154
163
|
this.#worker.terminate();
|
|
@@ -14,6 +14,7 @@ export declare const StudioPreferences: import("@opendaw/lib-fusion").Preference
|
|
|
14
14
|
engine: {
|
|
15
15
|
"note-audition-while-editing": boolean;
|
|
16
16
|
"auto-create-output-compressor": boolean;
|
|
17
|
+
"stop-playback-when-overloading": boolean;
|
|
17
18
|
};
|
|
18
19
|
pointer: {
|
|
19
20
|
"dragging-use-pointer-lock": boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StudioPreferences.d.ts","sourceRoot":"","sources":["../src/StudioPreferences.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"StudioPreferences.d.ts","sourceRoot":"","sources":["../src/StudioPreferences.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAwD,CAAA"}
|
package/dist/StudioSettings.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export declare const StudioSettingsSchema: z.ZodObject<{
|
|
|
17
17
|
engine: z.ZodDefault<z.ZodObject<{
|
|
18
18
|
"note-audition-while-editing": z.ZodBoolean;
|
|
19
19
|
"auto-create-output-compressor": z.ZodBoolean;
|
|
20
|
+
"stop-playback-when-overloading": z.ZodBoolean;
|
|
20
21
|
}, z.core.$strip>>;
|
|
21
22
|
pointer: z.ZodDefault<z.ZodObject<{
|
|
22
23
|
"dragging-use-pointer-lock": z.ZodBoolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StudioSettings.d.ts","sourceRoot":"","sources":["../src/StudioSettings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAA;AAGrB,eAAO,MAAM,UAAU,8BAA+B,CAAA;AACtD,eAAO,MAAM,kCAAkC,qDAAsD,CAAA;AAErG,eAAO,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"StudioSettings.d.ts","sourceRoot":"","sources":["../src/StudioSettings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAA;AAGrB,eAAO,MAAM,UAAU,8BAA+B,CAAA;AACtD,eAAO,MAAM,kCAAkC,qDAAsD,CAAA;AAErG,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+D/B,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA"}
|
package/dist/StudioSettings.js
CHANGED
|
@@ -22,10 +22,12 @@ export const StudioSettingsSchema = z.object({
|
|
|
22
22
|
}).default({ musical: true, absolute: false, details: false, fps: 25 }),
|
|
23
23
|
"engine": z.object({
|
|
24
24
|
"note-audition-while-editing": z.boolean(),
|
|
25
|
-
"auto-create-output-compressor": z.boolean()
|
|
25
|
+
"auto-create-output-compressor": z.boolean(),
|
|
26
|
+
"stop-playback-when-overloading": z.boolean()
|
|
26
27
|
}).default({
|
|
27
28
|
"note-audition-while-editing": true,
|
|
28
|
-
"auto-create-output-compressor": true
|
|
29
|
+
"auto-create-output-compressor": true,
|
|
30
|
+
"stop-playback-when-overloading": true
|
|
29
31
|
}),
|
|
30
32
|
"pointer": z.object({
|
|
31
33
|
"dragging-use-pointer-lock": z.boolean(),
|
|
@@ -2,11 +2,13 @@ import { MutableObservableOption, Option, Terminable } from "@opendaw/lib-std";
|
|
|
2
2
|
import { AudioUnitBox, CaptureAudioBox } from "@opendaw/studio-boxes";
|
|
3
3
|
import { Capture } from "./Capture";
|
|
4
4
|
import { CaptureDevices } from "./CaptureDevices";
|
|
5
|
+
import { MonitoringMode } from "./MonitoringMode";
|
|
5
6
|
export declare class CaptureAudio extends Capture<CaptureAudioBox> {
|
|
6
7
|
#private;
|
|
7
8
|
constructor(manager: CaptureDevices, audioUnitBox: AudioUnitBox, captureAudioBox: CaptureAudioBox);
|
|
8
9
|
get isMonitoring(): boolean;
|
|
9
|
-
|
|
10
|
+
get monitoringMode(): MonitoringMode;
|
|
11
|
+
set monitoringMode(value: MonitoringMode);
|
|
10
12
|
get gainDb(): number;
|
|
11
13
|
get requestChannels(): Option<1 | 2>;
|
|
12
14
|
set requestChannels(value: 1 | 2);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaptureAudio.d.ts","sourceRoot":"","sources":["../../src/capture/CaptureAudio.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,uBAAuB,EAEvB,MAAM,EAEN,UAAU,EACb,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAC,YAAY,EAAE,eAAe,EAAC,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"CaptureAudio.d.ts","sourceRoot":"","sources":["../../src/capture/CaptureAudio.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,uBAAuB,EAEvB,MAAM,EAEN,UAAU,EACb,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAC,YAAY,EAAE,eAAe,EAAC,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAK/C,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAE/C,qBAAa,YAAa,SAAQ,OAAO,CAAC,eAAe,CAAC;;gBAe1C,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe;IAwCjG,IAAI,YAAY,IAAI,OAAO,CAAwC;IACnE,IAAI,cAAc,IAAI,cAAc,CAA8B;IAClE,IAAI,cAAc,CAAC,KAAK,EAAE,cAAc,EAQvC;IACD,IAAI,MAAM,IAAI,MAAM,CAAsB;IAC1C,IAAI,eAAe,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAA+B;IACnE,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAmD;IACnF,IAAI,MAAM,IAAI,uBAAuB,CAAC,WAAW,CAAC,CAAsB;IACxE,IAAI,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC,CAEnC;IACD,IAAI,KAAK,IAAI,MAAM,CAAsE;IACzF,IAAI,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,CAA+D;IAChG,IAAI,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAE/C;IACD,IAAI,UAAU,IAAI,MAAM,CAAC,SAAS,CAAC,CAAiD;IACpF,IAAI,qBAAqB,IAAI,MAAM,CAA6C;IAE1E,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BvC,cAAc,IAAI,UAAU;CAsH/B"}
|
|
@@ -8,7 +8,7 @@ import { RenderQuantum } from "../RenderQuantum";
|
|
|
8
8
|
export class CaptureAudio extends Capture {
|
|
9
9
|
#stream;
|
|
10
10
|
#streamGenerator;
|
|
11
|
-
#
|
|
11
|
+
#monitoringMode = "off";
|
|
12
12
|
#requestChannels = Option.None;
|
|
13
13
|
#gainDb = 0.0;
|
|
14
14
|
#audioChain = null;
|
|
@@ -21,6 +21,12 @@ export class CaptureAudio extends Capture {
|
|
|
21
21
|
const channels = owner.getValue();
|
|
22
22
|
this.#requestChannels = channels === 1 || channels === 2 ? Option.wrap(channels) : Option.None;
|
|
23
23
|
this.#stream.ifSome(stream => this.#rebuildAudioChain(stream));
|
|
24
|
+
// Re-register monitoring if in effects mode (channel count may have changed)
|
|
25
|
+
if (this.#monitoringMode === "effects" && isDefined(this.#audioChain)) {
|
|
26
|
+
const engine = this.manager.project.engine;
|
|
27
|
+
engine.unregisterMonitoringSource(this.audioUnitBox.address.uuid);
|
|
28
|
+
engine.registerMonitoringSource(this.audioUnitBox.address.uuid, this.#audioChain.gainNode, this.#audioChain.channelCount);
|
|
29
|
+
}
|
|
24
30
|
}), captureAudioBox.gainDb.catchupAndSubscribe(owner => {
|
|
25
31
|
this.#gainDb = owner.getValue();
|
|
26
32
|
if (isDefined(this.#audioChain)) {
|
|
@@ -40,19 +46,18 @@ export class CaptureAudio extends Capture {
|
|
|
40
46
|
}
|
|
41
47
|
}));
|
|
42
48
|
}
|
|
43
|
-
get isMonitoring() { return this.#
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
get isMonitoring() { return this.#monitoringMode !== "off"; }
|
|
50
|
+
get monitoringMode() { return this.#monitoringMode; }
|
|
51
|
+
set monitoringMode(value) {
|
|
52
|
+
if (this.#monitoringMode === value) {
|
|
46
53
|
return;
|
|
47
54
|
}
|
|
48
|
-
this.#
|
|
49
|
-
|
|
55
|
+
this.#disconnectMonitoring();
|
|
56
|
+
this.#monitoringMode = value;
|
|
57
|
+
if (this.#monitoringMode !== "off") {
|
|
50
58
|
this.armed.setValue(true);
|
|
51
|
-
this.#connectMonitoring();
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
this.#disconnectMonitoring();
|
|
55
59
|
}
|
|
60
|
+
this.#connectMonitoring();
|
|
56
61
|
}
|
|
57
62
|
get gainDb() { return this.#gainDb; }
|
|
58
63
|
get requestChannels() { return this.#requestChannels; }
|
|
@@ -154,7 +159,7 @@ export class CaptureAudio extends Capture {
|
|
|
154
159
|
this.#stream.clear(stream => stream.getAudioTracks().forEach(track => track.stop()));
|
|
155
160
|
}
|
|
156
161
|
#rebuildAudioChain(stream) {
|
|
157
|
-
const
|
|
162
|
+
const wasMonitoringMode = this.#monitoringMode !== "off" && isDefined(this.#audioChain) ? this.#monitoringMode : "off";
|
|
158
163
|
this.#destroyAudioChain();
|
|
159
164
|
const { audioContext } = this.manager.project.env;
|
|
160
165
|
const sourceNode = audioContext.createMediaStreamSource(stream);
|
|
@@ -166,7 +171,7 @@ export class CaptureAudio extends Capture {
|
|
|
166
171
|
gainNode.channelCountMode = "explicit";
|
|
167
172
|
sourceNode.connect(gainNode);
|
|
168
173
|
this.#audioChain = { sourceNode, gainNode, channelCount };
|
|
169
|
-
if (
|
|
174
|
+
if (wasMonitoringMode !== "off" || this.#monitoringMode !== "off") {
|
|
170
175
|
this.#connectMonitoring();
|
|
171
176
|
}
|
|
172
177
|
}
|
|
@@ -179,15 +184,35 @@ export class CaptureAudio extends Capture {
|
|
|
179
184
|
}
|
|
180
185
|
}
|
|
181
186
|
#connectMonitoring() {
|
|
182
|
-
if (isDefined(this.#audioChain)) {
|
|
183
|
-
|
|
184
|
-
|
|
187
|
+
if (!isDefined(this.#audioChain)) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
switch (this.#monitoringMode) {
|
|
191
|
+
case "off":
|
|
192
|
+
break;
|
|
193
|
+
case "direct":
|
|
194
|
+
this.#audioChain.gainNode.connect(this.manager.project.env.audioContext.destination);
|
|
195
|
+
break;
|
|
196
|
+
case "effects":
|
|
197
|
+
const engine = this.manager.project.engine;
|
|
198
|
+
engine.registerMonitoringSource(this.audioUnitBox.address.uuid, this.#audioChain.gainNode, this.#audioChain.channelCount);
|
|
199
|
+
break;
|
|
185
200
|
}
|
|
186
201
|
}
|
|
187
202
|
#disconnectMonitoring() {
|
|
188
|
-
if (isDefined(this.#audioChain)) {
|
|
189
|
-
|
|
190
|
-
|
|
203
|
+
if (!isDefined(this.#audioChain)) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
switch (this.#monitoringMode) {
|
|
207
|
+
case "off":
|
|
208
|
+
break;
|
|
209
|
+
case "direct":
|
|
210
|
+
this.#audioChain.gainNode.disconnect(this.manager.project.env.audioContext.destination);
|
|
211
|
+
break;
|
|
212
|
+
case "effects":
|
|
213
|
+
this.#audioChain.gainNode.disconnect();
|
|
214
|
+
this.manager.project.engine.unregisterMonitoringSource(this.audioUnitBox.address.uuid);
|
|
215
|
+
break;
|
|
191
216
|
}
|
|
192
217
|
}
|
|
193
218
|
}
|