@opendaw/studio-core 0.0.100 → 0.0.102
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 +44 -24
- package/dist/Engine.d.ts +5 -0
- package/dist/Engine.d.ts.map +1 -1
- package/dist/EngineFacade.d.ts +5 -0
- package/dist/EngineFacade.d.ts.map +1 -1
- package/dist/EngineFacade.js +23 -2
- package/dist/EngineWorklet.d.ts +5 -0
- package/dist/EngineWorklet.d.ts.map +1 -1
- package/dist/EngineWorklet.js +107 -11
- package/dist/HRClockWorker.d.ts +7 -0
- package/dist/HRClockWorker.d.ts.map +1 -0
- package/dist/HRClockWorker.js +54 -0
- package/dist/OfflineEngineRenderer.d.ts.map +1 -1
- package/dist/OfflineEngineRenderer.js +6 -2
- package/dist/RecordingWorklet.d.ts +2 -1
- package/dist/RecordingWorklet.d.ts.map +1 -1
- package/dist/RecordingWorklet.js +9 -1
- package/dist/Storage.d.ts.map +1 -1
- package/dist/Storage.js +1 -0
- package/dist/StudioPreferences.d.ts +9 -0
- package/dist/StudioPreferences.d.ts.map +1 -1
- package/dist/StudioSettings.d.ts +14 -0
- package/dist/StudioSettings.d.ts.map +1 -1
- package/dist/StudioSettings.js +19 -2
- package/dist/capture/CaptureAudio.d.ts +3 -1
- package/dist/capture/CaptureAudio.d.ts.map +1 -1
- package/dist/capture/CaptureAudio.js +51 -29
- 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/RecordAudio.d.ts.map +1 -1
- package/dist/capture/RecordAudio.js +1 -0
- package/dist/capture/index.d.ts +1 -0
- package/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/index.js +1 -0
- package/dist/dawproject/DawProjectImporter.d.ts.map +1 -1
- package/dist/dawproject/DawProjectImporter.js +4 -0
- package/dist/processors.js +24 -24
- package/dist/processors.js.map +4 -4
- package/dist/project/Project.d.ts +7 -1
- package/dist/project/Project.d.ts.map +1 -1
- package/dist/project/Project.js +58 -8
- package/dist/project/ProjectApi.d.ts +1 -1
- package/dist/project/ProjectApi.d.ts.map +1 -1
- package/dist/project/ProjectApi.js +17 -3
- package/dist/project/ProjectMigration.d.ts.map +1 -1
- package/dist/project/ProjectMigration.js +3 -2
- package/dist/project/audio/AudioContentFactory.d.ts +5 -0
- package/dist/project/audio/AudioContentFactory.d.ts.map +1 -1
- package/dist/project/audio/AudioContentFactory.js +13 -0
- 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/{generic → clipboard}/ClipboardManager.d.ts +3 -3
- package/dist/ui/clipboard/ClipboardManager.d.ts.map +1 -0
- package/dist/ui/clipboard/ClipboardManager.js +147 -0
- package/dist/ui/clipboard/ClipboardUtils.d.ts +12 -0
- package/dist/ui/clipboard/ClipboardUtils.d.ts.map +1 -0
- package/dist/ui/clipboard/ClipboardUtils.js +94 -0
- package/dist/ui/{generic → clipboard}/ContextMenu.d.ts +1 -1
- package/dist/ui/clipboard/ContextMenu.d.ts.map +1 -0
- package/dist/ui/{generic → clipboard}/ContextMenu.js +1 -1
- package/dist/ui/clipboard/types/AudioUnitsClipboardHandler.d.ts +18 -0
- package/dist/ui/clipboard/types/AudioUnitsClipboardHandler.d.ts.map +1 -0
- package/dist/ui/clipboard/types/AudioUnitsClipboardHandler.js +215 -0
- package/dist/ui/clipboard/types/DevicesClipboardHandler.d.ts +18 -0
- package/dist/ui/clipboard/types/DevicesClipboardHandler.d.ts.map +1 -0
- package/dist/ui/clipboard/types/DevicesClipboardHandler.js +188 -0
- package/dist/ui/clipboard/types/NotesClipboardHandler.d.ts +21 -0
- package/dist/ui/clipboard/types/NotesClipboardHandler.d.ts.map +1 -0
- package/dist/ui/clipboard/types/NotesClipboardHandler.js +72 -0
- package/dist/ui/clipboard/types/RegionsClipboardHandler.d.ts +24 -0
- package/dist/ui/clipboard/types/RegionsClipboardHandler.d.ts.map +1 -0
- package/dist/ui/clipboard/types/RegionsClipboardHandler.js +137 -0
- package/dist/ui/clipboard/types/ValuesClipboardHandler.d.ts +22 -0
- package/dist/ui/clipboard/types/ValuesClipboardHandler.d.ts.map +1 -0
- package/dist/ui/clipboard/types/ValuesClipboardHandler.js +135 -0
- package/dist/ui/index.d.ts +14 -3
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +14 -3
- package/dist/ui/menu/MenuItems.d.ts.map +1 -0
- package/dist/ui/timeline/RegionClipResolver.d.ts +5 -1
- package/dist/ui/timeline/RegionClipResolver.d.ts.map +1 -1
- package/dist/ui/timeline/RegionClipResolver.js +5 -1
- package/dist/ui/timeline/RegionKeepExistingResolver.d.ts +34 -0
- package/dist/ui/timeline/RegionKeepExistingResolver.d.ts.map +1 -0
- package/dist/ui/timeline/RegionKeepExistingResolver.js +171 -0
- package/dist/ui/timeline/RegionOverlapResolver.d.ts +33 -0
- package/dist/ui/timeline/RegionOverlapResolver.d.ts.map +1 -0
- package/dist/ui/timeline/RegionOverlapResolver.js +79 -0
- package/dist/ui/timeline/RegionPushExistingResolver.d.ts +31 -0
- package/dist/ui/timeline/RegionPushExistingResolver.d.ts.map +1 -0
- package/dist/ui/timeline/RegionPushExistingResolver.js +159 -0
- package/dist/ui/timeline/TimelineFocus.d.ts +14 -0
- package/dist/ui/timeline/TimelineFocus.d.ts.map +1 -0
- package/dist/ui/timeline/TimelineFocus.js +45 -0
- package/dist/ui/timeline/TrackResolver.d.ts +11 -0
- package/dist/ui/timeline/TrackResolver.d.ts.map +1 -0
- package/dist/ui/timeline/TrackResolver.js +5 -0
- package/dist/workers-main.js +1 -1
- package/dist/workers-main.js.map +3 -3
- package/package.json +62 -62
- package/dist/ui/generic/ClipboardManager.d.ts.map +0 -1
- package/dist/ui/generic/ClipboardManager.js +0 -77
- package/dist/ui/generic/ContextMenu.d.ts.map +0 -1
- package/dist/ui/generic/MenuItems.d.ts.map +0 -1
- /package/dist/ui/{generic → menu}/MenuItems.d.ts +0 -0
- /package/dist/ui/{generic → menu}/MenuItems.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Func, Procedure, Terminable, TerminableOwner, Terminator, UUID } from "@opendaw/lib-std";
|
|
2
2
|
import { BoxEditing, BoxGraph } from "@opendaw/lib-box";
|
|
3
3
|
import { AudioBusBox, AudioUnitBox, BoxIO, RootBox, TimelineBox, UserInterfaceBox } from "@opendaw/studio-boxes";
|
|
4
|
-
import { BoxAdapters, BoxAdaptersContext, ClipSequencing, ParameterFieldAdapters, ProcessorOptions, ProjectSkeleton, RootBoxAdapter, SampleLoaderManager, SoundfontLoaderManager, TimelineBoxAdapter, UserEditingManager, VertexSelection } from "@opendaw/studio-adapters";
|
|
4
|
+
import { BoxAdapters, BoxAdaptersContext, ClipSequencing, DeviceBoxAdapter, FilteredSelection, ParameterFieldAdapters, ProcessorOptions, ProjectSkeleton, RootBoxAdapter, SampleLoaderManager, SoundfontLoaderManager, TimelineBoxAdapter, UserEditingManager, VertexSelection } from "@opendaw/studio-adapters";
|
|
5
5
|
import { LiveStreamBroadcaster, LiveStreamReceiver } from "@opendaw/lib-fusion";
|
|
6
6
|
import { ProjectEnv } from "./ProjectEnv";
|
|
7
7
|
import { Mixer } from "../Mixer";
|
|
@@ -11,6 +11,7 @@ import { EngineFacade } from "../EngineFacade";
|
|
|
11
11
|
import { EngineWorklet } from "../EngineWorklet";
|
|
12
12
|
import { MIDILearning } from "../midi";
|
|
13
13
|
import { ppqn, TempoMap } from "@opendaw/lib-dsp";
|
|
14
|
+
import { RegionOverlapResolver, TimelineFocus } from "../ui";
|
|
14
15
|
export type RestartWorklet = {
|
|
15
16
|
unload: Func<unknown, Promise<unknown>>;
|
|
16
17
|
load: Procedure<EngineWorklet>;
|
|
@@ -34,6 +35,7 @@ export declare class Project implements BoxAdaptersContext, Terminable, Terminab
|
|
|
34
35
|
readonly captureDevices: CaptureDevices;
|
|
35
36
|
readonly editing: BoxEditing;
|
|
36
37
|
readonly selection: VertexSelection;
|
|
38
|
+
readonly deviceSelection: FilteredSelection<DeviceBoxAdapter>;
|
|
37
39
|
readonly boxAdapters: BoxAdapters;
|
|
38
40
|
readonly userEditingManager: UserEditingManager;
|
|
39
41
|
readonly parameterFieldAdapters: ParameterFieldAdapters;
|
|
@@ -41,9 +43,12 @@ export declare class Project implements BoxAdaptersContext, Terminable, Terminab
|
|
|
41
43
|
readonly midiLearning: MIDILearning;
|
|
42
44
|
readonly mixer: Mixer;
|
|
43
45
|
readonly tempoMap: TempoMap;
|
|
46
|
+
readonly overlapResolver: RegionOverlapResolver;
|
|
47
|
+
readonly timelineFocus: TimelineFocus;
|
|
44
48
|
readonly engine: EngineFacade;
|
|
45
49
|
private constructor();
|
|
46
50
|
startAudioWorklet(restart?: RestartWorklet, options?: ProcessorOptions): EngineWorklet;
|
|
51
|
+
handleCpuOverload(): void;
|
|
47
52
|
startRecording(countIn?: boolean): void;
|
|
48
53
|
follow(box: UserInterfaceBox): void;
|
|
49
54
|
own<T extends Terminable>(terminable: T): T;
|
|
@@ -66,6 +71,7 @@ export declare class Project implements BoxAdaptersContext, Terminable, Terminab
|
|
|
66
71
|
copy(env?: Partial<ProjectEnv>): Project;
|
|
67
72
|
invalid(): boolean;
|
|
68
73
|
lastRegionAction(): ppqn;
|
|
74
|
+
trackUserCreatedSample(uuid: UUID.Bytes): void;
|
|
69
75
|
terminate(): void;
|
|
70
76
|
}
|
|
71
77
|
//# sourceMappingURL=Project.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Project.d.ts","sourceRoot":"","sources":["../../src/project/Project.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,IAAI,EAGJ,SAAS,
|
|
1
|
+
{"version":3,"file":"Project.d.ts","sourceRoot":"","sources":["../../src/project/Project.ts"],"names":[],"mappings":"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"}
|
package/dist/project/Project.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Arrays, isDefined, panic, safeExecute, Terminator, UUID } from "@opendaw/lib-std";
|
|
1
|
+
import { Arrays, isDefined, panic, RuntimeNotifier, safeExecute, Terminator, UUID } from "@opendaw/lib-std";
|
|
2
2
|
import { BoxEditing, DeleteUpdate, NewUpdate } from "@opendaw/lib-box";
|
|
3
3
|
import { AudioFileBox, AudioRegionBox } from "@opendaw/studio-boxes";
|
|
4
|
-
import { BoxAdapters, ParameterFieldAdapters, ProjectSkeleton, RootBoxAdapter, TimelineBoxAdapter, UnionBoxTypes, UserEditingManager, VaryingTempoMap, VertexSelection } from "@opendaw/studio-adapters";
|
|
4
|
+
import { BoxAdapters, DeviceBoxUtils, Devices, isVertexOfBox, ParameterFieldAdapters, ProjectSkeleton, RootBoxAdapter, TimelineBoxAdapter, UnionBoxTypes, UserEditingManager, VaryingTempoMap, VertexSelection } from "@opendaw/studio-adapters";
|
|
5
5
|
import { LiveStreamReceiver } from "@opendaw/lib-fusion";
|
|
6
6
|
import { Mixer } from "../Mixer";
|
|
7
7
|
import { ProjectApi } from "./ProjectApi";
|
|
@@ -13,6 +13,8 @@ import { ProjectValidation } from "./ProjectValidation";
|
|
|
13
13
|
import { TimeBase } from "@opendaw/lib-dsp";
|
|
14
14
|
import { MidiData } from "@opendaw/lib-midi";
|
|
15
15
|
import { StudioPreferences } from "../StudioPreferences";
|
|
16
|
+
import { RegionOverlapResolver, TimelineFocus } from "../ui";
|
|
17
|
+
import { SampleStorage } from "../samples";
|
|
16
18
|
// Main Entry Point for a Project
|
|
17
19
|
export class Project {
|
|
18
20
|
static new(env, options) {
|
|
@@ -47,6 +49,7 @@ export class Project {
|
|
|
47
49
|
}
|
|
48
50
|
#terminator = new Terminator();
|
|
49
51
|
#sampleRegistrations;
|
|
52
|
+
#userCreatedSamples = UUID.newSet(uuid => uuid);
|
|
50
53
|
#env;
|
|
51
54
|
boxGraph;
|
|
52
55
|
rootBox;
|
|
@@ -58,6 +61,7 @@ export class Project {
|
|
|
58
61
|
captureDevices;
|
|
59
62
|
editing;
|
|
60
63
|
selection;
|
|
64
|
+
deviceSelection;
|
|
61
65
|
boxAdapters;
|
|
62
66
|
userEditingManager;
|
|
63
67
|
parameterFieldAdapters;
|
|
@@ -65,7 +69,11 @@ export class Project {
|
|
|
65
69
|
midiLearning;
|
|
66
70
|
mixer;
|
|
67
71
|
tempoMap;
|
|
72
|
+
overlapResolver;
|
|
73
|
+
timelineFocus;
|
|
68
74
|
engine = new EngineFacade();
|
|
75
|
+
#rootBoxAdapter;
|
|
76
|
+
#timelineBoxAdapter;
|
|
69
77
|
constructor(env, boxGraph, { rootBox, userInterfaceBoxes, primaryAudioBus, primaryAudioOutputUnit, timelineBox }) {
|
|
70
78
|
this.#env = env;
|
|
71
79
|
this.boxGraph = boxGraph;
|
|
@@ -79,12 +87,20 @@ export class Project {
|
|
|
79
87
|
this.selection = new VertexSelection(this.editing, this.boxGraph);
|
|
80
88
|
this.parameterFieldAdapters = new ParameterFieldAdapters();
|
|
81
89
|
this.boxAdapters = this.#terminator.own(new BoxAdapters(this));
|
|
82
|
-
this.
|
|
90
|
+
this.deviceSelection = this.#terminator.own(this.selection.createFilteredSelection(isVertexOfBox(DeviceBoxUtils.isDeviceBox), {
|
|
91
|
+
fx: (adapter) => adapter.box,
|
|
92
|
+
fy: vertex => this.boxAdapters.adapterFor(vertex.box, Devices.isAny)
|
|
93
|
+
}));
|
|
94
|
+
this.#timelineBoxAdapter = this.boxAdapters.adapterFor(this.timelineBox, TimelineBoxAdapter);
|
|
95
|
+
this.tempoMap = this.#terminator.own(new VaryingTempoMap(this.#timelineBoxAdapter));
|
|
83
96
|
this.userEditingManager = new UserEditingManager(this.editing);
|
|
84
97
|
this.liveStreamReceiver = this.#terminator.own(new LiveStreamReceiver());
|
|
85
98
|
this.midiLearning = this.#terminator.own(new MIDILearning(this));
|
|
86
99
|
this.captureDevices = this.#terminator.own(new CaptureDevices(this));
|
|
87
|
-
this
|
|
100
|
+
this.#rootBoxAdapter = this.boxAdapters.adapterFor(this.rootBox, RootBoxAdapter);
|
|
101
|
+
this.mixer = new Mixer(this.#rootBoxAdapter.audioUnits);
|
|
102
|
+
this.overlapResolver = new RegionOverlapResolver(this.editing, this.api, this.boxAdapters);
|
|
103
|
+
this.timelineFocus = this.#terminator.own(new TimelineFocus());
|
|
88
104
|
console.debug(`Project was created on ${this.rootBoxAdapter.created.toString()}`);
|
|
89
105
|
this.#sampleRegistrations = UUID.newSet(({ uuid }) => uuid);
|
|
90
106
|
for (const box of this.boxGraph.boxes()) {
|
|
@@ -99,6 +115,7 @@ export class Project {
|
|
|
99
115
|
}
|
|
100
116
|
else if (update instanceof DeleteUpdate && update.name === AudioFileBox.ClassName) {
|
|
101
117
|
this.#unregisterSample(update.uuid);
|
|
118
|
+
this.#deleteUserCreatedSample(update.uuid);
|
|
102
119
|
}
|
|
103
120
|
}
|
|
104
121
|
}));
|
|
@@ -122,6 +139,16 @@ export class Project {
|
|
|
122
139
|
this.engine.setWorklet(worklet);
|
|
123
140
|
return worklet;
|
|
124
141
|
}
|
|
142
|
+
handleCpuOverload() {
|
|
143
|
+
if (!StudioPreferences.settings.engine["stop-playback-when-overloading"]) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
this.engine.sleep();
|
|
147
|
+
RuntimeNotifier.info({
|
|
148
|
+
headline: "CPU Overload Detected",
|
|
149
|
+
message: "Playback has been stopped. Try removing heavy plugins or effects."
|
|
150
|
+
}).finally();
|
|
151
|
+
}
|
|
125
152
|
startRecording(countIn = true) {
|
|
126
153
|
this.engine.assertWorklet();
|
|
127
154
|
if (Recording.isRecording) {
|
|
@@ -138,8 +165,8 @@ export class Project {
|
|
|
138
165
|
ownAll(...terminables) { return this.#terminator.ownAll(...terminables); }
|
|
139
166
|
spawn() { return this.#terminator.spawn(); }
|
|
140
167
|
get env() { return this.#env; }
|
|
141
|
-
get rootBoxAdapter() { return this
|
|
142
|
-
get timelineBoxAdapter() { return this
|
|
168
|
+
get rootBoxAdapter() { return this.#rootBoxAdapter; }
|
|
169
|
+
get timelineBoxAdapter() { return this.#timelineBoxAdapter; }
|
|
143
170
|
get sampleManager() { return this.#env.sampleManager; }
|
|
144
171
|
get soundfontManager() { return this.#env.soundfontManager; }
|
|
145
172
|
get clipSequencing() { return panic("Only available in audio context"); }
|
|
@@ -204,8 +231,8 @@ export class Project {
|
|
|
204
231
|
return Project.load({ ...this.#env, ...env }, this.toArrayBuffer());
|
|
205
232
|
}
|
|
206
233
|
invalid() {
|
|
207
|
-
|
|
208
|
-
|
|
234
|
+
const now = performance.now();
|
|
235
|
+
const result = this.boxGraph.boxes().some(box => box.accept({
|
|
209
236
|
visitTrackBox: (box) => {
|
|
210
237
|
for (const [current, next] of Arrays.iterateAdjacent(box.regions.pointerHub.incoming()
|
|
211
238
|
.map(({ box }) => UnionBoxTypes.asRegionBox(box))
|
|
@@ -220,6 +247,10 @@ export class Project {
|
|
|
220
247
|
return false;
|
|
221
248
|
}
|
|
222
249
|
}) ?? false);
|
|
250
|
+
if (performance.now() - now > 5) {
|
|
251
|
+
console.warn("Evaluation of invalid project takes more than 5ms");
|
|
252
|
+
}
|
|
253
|
+
return result;
|
|
223
254
|
}
|
|
224
255
|
lastRegionAction() {
|
|
225
256
|
return this.rootBoxAdapter.audioUnits.adapters()
|
|
@@ -227,6 +258,9 @@ export class Project {
|
|
|
227
258
|
.map(trackAdapter => trackAdapter.regions.collection.asArray().at(-1)))
|
|
228
259
|
.filter(isDefined).reduce((position, region) => Math.max(position, region.complete), 0);
|
|
229
260
|
}
|
|
261
|
+
trackUserCreatedSample(uuid) {
|
|
262
|
+
this.#userCreatedSamples.add(uuid);
|
|
263
|
+
}
|
|
230
264
|
terminate() {
|
|
231
265
|
this.#sampleRegistrations.forEach(({ terminable }) => terminable.terminate());
|
|
232
266
|
this.#sampleRegistrations.clear();
|
|
@@ -239,4 +273,20 @@ export class Project {
|
|
|
239
273
|
#unregisterSample(uuid) {
|
|
240
274
|
this.#sampleRegistrations.removeByKey(uuid).terminable.terminate();
|
|
241
275
|
}
|
|
276
|
+
async #deleteUserCreatedSample(uuid) {
|
|
277
|
+
if (!this.#userCreatedSamples.hasKey(uuid)) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
this.#userCreatedSamples.removeByKey(uuid);
|
|
281
|
+
const autoDelete = StudioPreferences.settings.storage["auto-delete-orphaned-samples"];
|
|
282
|
+
if (!autoDelete && !await RuntimeNotifier.approve({
|
|
283
|
+
headline: "Delete Sample?",
|
|
284
|
+
message: "The sample is no longer used. Delete it from storage? This cannot be undone!",
|
|
285
|
+
approveText: "Delete",
|
|
286
|
+
cancelText: "Keep"
|
|
287
|
+
})) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
SampleStorage.get().deleteItem(uuid).catch((reason) => console.warn("Failed to delete sample from storage", reason));
|
|
291
|
+
}
|
|
242
292
|
}
|
|
@@ -59,7 +59,7 @@ export declare class ProjectApi {
|
|
|
59
59
|
createNotStretchedClip(props: AudioContentFactory.NotStretchedProps & AudioContentFactory.Clip): AudioClipBox;
|
|
60
60
|
createNotStretchedRegion(props: AudioContentFactory.NotStretchedProps & AudioContentFactory.Region): AudioRegionBox;
|
|
61
61
|
createNoteClip(trackBox: TrackBox, clipIndex: int, { name, hue }?: ClipRegionOptions): NoteClipBox;
|
|
62
|
-
duplicateRegion<R extends AnyRegionBoxAdapter>(region: R): R
|
|
62
|
+
duplicateRegion<R extends AnyRegionBoxAdapter>(region: R): Option<R>;
|
|
63
63
|
quantiseNotes(collection: NoteEventCollectionBox, { positionQuantisation, durationQuantisation }: QuantiseNotesOptions): void;
|
|
64
64
|
createValueClip(trackBox: TrackBox, clipIndex: int, { name, hue }?: ClipRegionOptions): ValueClipBox;
|
|
65
65
|
createNoteRegion({ trackBox, position, duration, loopOffset, loopDuration, eventOffset, eventCollection, mute, name, hue }: NoteRegionParams): NoteRegionBox;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectApi.d.ts","sourceRoot":"","sources":["../../src/project/ProjectApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,OAAO,EAGP,KAAK,EACL,GAAG,EAIH,QAAQ,EACR,MAAM,EAIN,YAAY,EAEf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,IAAI,EAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAW,KAAK,EAAc,YAAY,EAAC,MAAM,kBAAkB,CAAA;AAC1E,OAAO,EAAgB,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EACH,YAAY,EACZ,cAAc,EACd,YAAY,EAGZ,WAAW,EACX,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,QAAQ,EACR,YAAY,EAEZ,cAAc,EACjB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACH,mBAAmB,EACnB,mBAAmB,EAInB,iBAAiB,EACjB,gCAAgC,EAChC,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EAGpB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAA;AACtC,OAAO,EAAC,mBAAmB,EAAC,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"ProjectApi.d.ts","sourceRoot":"","sources":["../../src/project/ProjectApi.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,6 @@ import { AudioUnitType } from "@opendaw/studio-enums";
|
|
|
5
5
|
import { AudioUnitBox, CaptureAudioBox, CaptureMidiBox, NoteClipBox, NoteEventBox, NoteEventCollectionBox, NoteRegionBox, TrackBox, ValueClipBox, ValueEventCollectionBox, ValueRegionBox } from "@opendaw/studio-boxes";
|
|
6
6
|
import { AudioUnitFactory, ColorCodes, ProjectQueries, TrackType } from "@opendaw/studio-adapters";
|
|
7
7
|
import { AudioContentFactory } from "./audio";
|
|
8
|
-
import { RegionClipResolver } from "../ui";
|
|
9
8
|
// noinspection JSUnusedGlobalSymbols
|
|
10
9
|
export class ProjectApi {
|
|
11
10
|
#project;
|
|
@@ -111,10 +110,25 @@ export class ProjectApi {
|
|
|
111
110
|
});
|
|
112
111
|
}
|
|
113
112
|
duplicateRegion(region) {
|
|
113
|
+
if (region.trackBoxAdapter.isEmpty()) {
|
|
114
|
+
return Option.None;
|
|
115
|
+
}
|
|
116
|
+
const track = region.trackBoxAdapter.unwrap();
|
|
114
117
|
const clearFrom = region.position + region.duration;
|
|
115
118
|
const clearTo = region.complete + region.duration;
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
// Resolve target track (for keep-existing mode)
|
|
120
|
+
const targetTrack = this.#project.overlapResolver.resolveTargetTrack(track, clearFrom, clearTo);
|
|
121
|
+
// Capture overlap state before creating (for clip/push-existing modes)
|
|
122
|
+
const solver = this.#project.overlapResolver.fromRange(targetTrack, clearFrom, clearTo);
|
|
123
|
+
// Create the duplicate on target track
|
|
124
|
+
const duplicate = region.copyTo({
|
|
125
|
+
position: region.complete,
|
|
126
|
+
consolidate: true,
|
|
127
|
+
track: targetTrack !== track ? targetTrack.box.regions : undefined
|
|
128
|
+
});
|
|
129
|
+
// Apply overlap resolution
|
|
130
|
+
solver();
|
|
131
|
+
return Option.wrap(duplicate);
|
|
118
132
|
}
|
|
119
133
|
quantiseNotes(collection, { positionQuantisation, durationQuantisation }) {
|
|
120
134
|
if (isAbsent(positionQuantisation) && isAbsent(durationQuantisation)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectMigration.d.ts","sourceRoot":"","sources":["../../src/project/ProjectMigration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProjectMigration.d.ts","sourceRoot":"","sources":["../../src/project/ProjectMigration.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAA;AAExD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AAiBvC,qBAAa,gBAAgB;WACZ,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,EAAC,QAAQ,EAAE,cAAc,EAAC,EAAE,eAAe;CA8DpF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GrooveShuffleBox } from "@opendaw/studio-boxes";
|
|
2
2
|
import { asInstanceOf, UUID } from "@opendaw/lib-std";
|
|
3
|
-
import { migrateAudioClipBox, migrateAudioFileBox, migrateAudioRegionBox, migrateAudioUnitBox, migrateDelayDeviceBox, migrateMIDIOutputDeviceBox, migrateRevampDeviceBox, migrateTimelineBox, migrateValueEventBox, migrateValueEventCollection, migrateVaporisateurDeviceBox, migrateZeitgeistDeviceBox } from "./migration";
|
|
3
|
+
import { migrateAudioClipBox, migrateAudioFileBox, migrateAudioRegionBox, migrateAudioUnitBox, migrateDelayDeviceBox, migrateMIDIOutputDeviceBox, migrateNeuralAmpDeviceBox, migrateRevampDeviceBox, migrateTimelineBox, migrateValueEventBox, migrateValueEventCollection, migrateVaporisateurDeviceBox, migrateZeitgeistDeviceBox } from "./migration";
|
|
4
4
|
export class ProjectMigration {
|
|
5
5
|
static async migrate(env, { boxGraph, mandatoryBoxes }) {
|
|
6
6
|
const { rootBox, timelineBox: { bpm } } = mandatoryBoxes;
|
|
@@ -46,7 +46,8 @@ export class ProjectMigration {
|
|
|
46
46
|
// 1st pass (2nd pass might rely on those changes)
|
|
47
47
|
for (const box of boxGraph.boxes()) {
|
|
48
48
|
await box.accept({
|
|
49
|
-
visitAudioFileBox: (box) => migrateAudioFileBox(boxGraph, box, loadAudioData)
|
|
49
|
+
visitAudioFileBox: (box) => migrateAudioFileBox(boxGraph, box, loadAudioData),
|
|
50
|
+
visitNeuralAmpDeviceBox: (box) => migrateNeuralAmpDeviceBox(boxGraph, box)
|
|
50
51
|
});
|
|
51
52
|
}
|
|
52
53
|
// 2nd pass. We need to run on a copy, because we might add more boxes during the migration
|
|
@@ -29,6 +29,11 @@ export declare namespace AudioContentFactory {
|
|
|
29
29
|
} & Props;
|
|
30
30
|
type PitchStretchedProps = {} & Props;
|
|
31
31
|
type NotStretchedProps = {} & Props;
|
|
32
|
+
/**
|
|
33
|
+
* Calculates the duration of an audio region based on sample properties.
|
|
34
|
+
* Returns duration in PPQN for stretched regions, or in seconds for non-stretched.
|
|
35
|
+
*/
|
|
36
|
+
const calculateDuration: (sample: Sample) => ppqn;
|
|
32
37
|
const createTimeStretchedRegion: (props: TimeStretchedProps & Region) => AudioRegionBox;
|
|
33
38
|
const createPitchStretchedRegion: (props: PitchStretchedProps & Region) => AudioRegionBox;
|
|
34
39
|
const createNotStretchedRegion: (props: NotStretchedProps & Region) => AudioRegionBox;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioContentFactory.d.ts","sourceRoot":"","sources":["../../../src/project/audio/AudioContentFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAiB,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAa,MAAM,EAAY,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAC,GAAG,EAAuC,MAAM,kBAAkB,CAAA;AAC1E,OAAO,EACH,YAAY,EACZ,YAAY,EAEZ,cAAc,EAEd,QAAQ,EAEX,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAC,iBAAiB,EAAC,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAA;AAEvD,yBAAiB,mBAAmB,CAAC;IACjC,KAAY,KAAK,GAAG;QAChB,QAAQ,EAAE,QAAQ,CAAA;QAClB,WAAW,EAAE,QAAQ,CAAA;QACrB,YAAY,EAAE,YAAY,CAAA;QAC1B,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;QACxB,WAAW,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAA;QAC/C,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;KACpB,CAAA;IAED,KAAY,IAAI,GAAG,KAAK,GAAG;QAAE,KAAK,EAAE,GAAG,CAAA;KAAE,CAAA;IACzC,KAAY,MAAM,GAAG,KAAK,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAE9D,KAAY,kBAAkB,GAAG;QAC7B,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;QACrC,YAAY,CAAC,EAAE,MAAM,CAAA;KACxB,GAAG,KAAK,CAAA;IAET,KAAY,mBAAmB,GAAG,EAA0C,GAAG,KAAK,CAAA;IAEpF,KAAY,iBAAiB,GAAG,EAA0C,GAAG,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"AudioContentFactory.d.ts","sourceRoot":"","sources":["../../../src/project/audio/AudioContentFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAiB,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAa,MAAM,EAAY,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAC,GAAG,EAAuC,MAAM,kBAAkB,CAAA;AAC1E,OAAO,EACH,YAAY,EACZ,YAAY,EAEZ,cAAc,EAEd,QAAQ,EAEX,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAC,iBAAiB,EAAC,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAA;AAEvD,yBAAiB,mBAAmB,CAAC;IACjC,KAAY,KAAK,GAAG;QAChB,QAAQ,EAAE,QAAQ,CAAA;QAClB,WAAW,EAAE,QAAQ,CAAA;QACrB,YAAY,EAAE,YAAY,CAAA;QAC1B,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;QACxB,WAAW,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAA;QAC/C,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;KACpB,CAAA;IAED,KAAY,IAAI,GAAG,KAAK,GAAG;QAAE,KAAK,EAAE,GAAG,CAAA;KAAE,CAAA;IACzC,KAAY,MAAM,GAAG,KAAK,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAE9D,KAAY,kBAAkB,GAAG;QAC7B,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;QACrC,YAAY,CAAC,EAAE,MAAM,CAAA;KACxB,GAAG,KAAK,CAAA;IAET,KAAY,mBAAmB,GAAG,EAA0C,GAAG,KAAK,CAAA;IAEpF,KAAY,iBAAiB,GAAG,EAA0C,GAAG,KAAK,CAAA;IAElF;;;OAGG;IACI,MAAM,iBAAiB,GAAI,QAAQ,MAAM,KAAG,IAQlD,CAAA;IAIM,MAAM,yBAAyB,GAAI,OAAO,kBAAkB,GAAG,MAAM,KAAG,cAM9E,CAAA;IAEM,MAAM,0BAA0B,GAAI,OAAO,mBAAmB,GAAG,MAAM,KAAG,cAEhF,CAAA;IAEM,MAAM,wBAAwB,GAAI,OAAO,iBAAiB,GAAG,MAAM,KAAG,cAgB5E,CAAA;IAIM,MAAM,uBAAuB,GAAI,OAAO,kBAAkB,GAAG,IAAI,KAAG,YAM1E,CAAA;IAEM,MAAM,wBAAwB,GAAI,OAAO,mBAAmB,GAAG,IAAI,KAAG,YAG5E,CAAA;IAEM,MAAM,sBAAsB,GAAI,OAAO,iBAAiB,GAAG,IAAI,KAAG,YAcxE,CAAA;CA6DJ"}
|
|
@@ -6,6 +6,19 @@ import { TransientPlayMode } from "@opendaw/studio-enums";
|
|
|
6
6
|
import { AudioContentHelpers } from "./AudioContentHelpers";
|
|
7
7
|
export var AudioContentFactory;
|
|
8
8
|
(function (AudioContentFactory) {
|
|
9
|
+
/**
|
|
10
|
+
* Calculates the duration of an audio region based on sample properties.
|
|
11
|
+
* Returns duration in PPQN for stretched regions, or in seconds for non-stretched.
|
|
12
|
+
*/
|
|
13
|
+
AudioContentFactory.calculateDuration = (sample) => {
|
|
14
|
+
const { duration: durationInSeconds, bpm } = sample;
|
|
15
|
+
if (bpm === 0) {
|
|
16
|
+
// Non-stretched: duration is in seconds
|
|
17
|
+
return durationInSeconds;
|
|
18
|
+
}
|
|
19
|
+
// Stretched: duration is in PPQN
|
|
20
|
+
return quantizeCeil(PPQN.secondsToPulses(durationInSeconds, bpm), PPQN.SemiQuaver);
|
|
21
|
+
};
|
|
9
22
|
// --- Region Creation --- //
|
|
10
23
|
AudioContentFactory.createTimeStretchedRegion = (props) => {
|
|
11
24
|
const { boxGraph, playbackRate, transientPlayMode } = props;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { BoxGraph } from "@opendaw/lib-box";
|
|
2
|
+
import { BoxIO, NeuralAmpDeviceBox } from "@opendaw/studio-boxes";
|
|
3
|
+
export declare const migrateNeuralAmpDeviceBox: (boxGraph: BoxGraph<BoxIO.TypeMap>, box: NeuralAmpDeviceBox) => Promise<void>;
|
|
4
|
+
//# sourceMappingURL=MigrateNeuralAmpDeviceBox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigrateNeuralAmpDeviceBox.d.ts","sourceRoot":"","sources":["../../../src/project/migration/MigrateNeuralAmpDeviceBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAC,KAAK,EAAE,kBAAkB,EAAoB,MAAM,uBAAuB,CAAA;AAElF,eAAO,MAAM,yBAAyB,GAAU,UAAU,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,kBAAkB,KAAG,OAAO,CAAC,IAAI,CAsBxH,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { UUID } from "@opendaw/lib-std";
|
|
2
|
+
import { NeuralAmpModelBox } from "@opendaw/studio-boxes";
|
|
3
|
+
export const migrateNeuralAmpDeviceBox = async (boxGraph, box) => {
|
|
4
|
+
const oldJson = box.modelJson.getValue();
|
|
5
|
+
if (oldJson.length === 0) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
if (box.model.targetVertex.nonEmpty()) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const jsonBuffer = new TextEncoder().encode(oldJson);
|
|
12
|
+
const uuid = await UUID.sha256(jsonBuffer.buffer);
|
|
13
|
+
let modelBox = null;
|
|
14
|
+
for (const existing of boxGraph.boxes()) {
|
|
15
|
+
if (existing instanceof NeuralAmpModelBox && UUID.equals(existing.address.uuid, uuid)) {
|
|
16
|
+
modelBox = existing;
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
boxGraph.beginTransaction();
|
|
21
|
+
if (modelBox === null) {
|
|
22
|
+
modelBox = NeuralAmpModelBox.create(boxGraph, uuid);
|
|
23
|
+
modelBox.label.setValue("Imported Model");
|
|
24
|
+
modelBox.model.setValue(oldJson);
|
|
25
|
+
}
|
|
26
|
+
box.model.refer(modelBox);
|
|
27
|
+
boxGraph.endTransaction();
|
|
28
|
+
console.debug(`Migrated NeuralAmpDeviceBox to use NeuralAmpModelBox (${UUID.toString(uuid).slice(0, 8)})`);
|
|
29
|
+
};
|
|
@@ -4,6 +4,7 @@ export { migrateAudioRegionBox } from "./MigrateAudioRegionBox";
|
|
|
4
4
|
export { migrateAudioUnitBox } from "./MigrateAudioUnitBox";
|
|
5
5
|
export { migrateDelayDeviceBox } from "./MigrateDelayDeviceBox";
|
|
6
6
|
export { migrateMIDIOutputDeviceBox } from "./MigrateMIDIOutputDeviceBox";
|
|
7
|
+
export { migrateNeuralAmpDeviceBox } from "./MigrateNeuralAmpDeviceBox";
|
|
7
8
|
export { migrateRevampDeviceBox } from "./MigrateRevampDeviceBox";
|
|
8
9
|
export { migrateTimelineBox } from "./MigrateTimelineBox";
|
|
9
10
|
export { migrateValueEventBox } from "./MigrateValueEventBox";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/project/migration/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAC,0BAA0B,EAAC,MAAM,8BAA8B,CAAA;AACvE,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAC,2BAA2B,EAAC,MAAM,+BAA+B,CAAA;AACzE,OAAO,EAAC,4BAA4B,EAAC,MAAM,gCAAgC,CAAA;AAC3E,OAAO,EAAC,yBAAyB,EAAC,MAAM,6BAA6B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/project/migration/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAC,0BAA0B,EAAC,MAAM,8BAA8B,CAAA;AACvE,OAAO,EAAC,yBAAyB,EAAC,MAAM,6BAA6B,CAAA;AACrE,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAC,2BAA2B,EAAC,MAAM,+BAA+B,CAAA;AACzE,OAAO,EAAC,4BAA4B,EAAC,MAAM,gCAAgC,CAAA;AAC3E,OAAO,EAAC,yBAAyB,EAAC,MAAM,6BAA6B,CAAA"}
|
|
@@ -4,6 +4,7 @@ export { migrateAudioRegionBox } from "./MigrateAudioRegionBox";
|
|
|
4
4
|
export { migrateAudioUnitBox } from "./MigrateAudioUnitBox";
|
|
5
5
|
export { migrateDelayDeviceBox } from "./MigrateDelayDeviceBox";
|
|
6
6
|
export { migrateMIDIOutputDeviceBox } from "./MigrateMIDIOutputDeviceBox";
|
|
7
|
+
export { migrateNeuralAmpDeviceBox } from "./MigrateNeuralAmpDeviceBox";
|
|
7
8
|
export { migrateRevampDeviceBox } from "./MigrateRevampDeviceBox";
|
|
8
9
|
export { migrateTimelineBox } from "./MigrateTimelineBox";
|
|
9
10
|
export { migrateValueEventBox } from "./MigrateValueEventBox";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Client,
|
|
2
|
-
export type ClipboardEntry<T extends string = string
|
|
1
|
+
import { Client, Option, Subscription } from "@opendaw/lib-std";
|
|
2
|
+
export type ClipboardEntry<T extends string = string> = {
|
|
3
3
|
readonly type: T;
|
|
4
|
-
readonly data:
|
|
4
|
+
readonly data: ArrayBufferLike;
|
|
5
5
|
};
|
|
6
6
|
export interface ClipboardHandler<E extends ClipboardEntry> {
|
|
7
7
|
canCopy(client: Client): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClipboardManager.d.ts","sourceRoot":"","sources":["../../../src/ui/clipboard/ClipboardManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAa,MAAM,kBAAkB,CAAA;AASzE,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IACpD,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAChB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;CACjC,CAAA;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,cAAc;IACtD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;IAChC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;IAC/B,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;IACxD,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAA;IACjB,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAA;IAChB,KAAK,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAA;CACrC;AAED,yBAAiB,gBAAgB,CAAC;IAC9B,KAAK,QAAQ,GAAG,cAAc,CAAA;IA0B9B,MAAM,CAAC,MAAM,OAAO,GAAI,CAAC,SAAS,QAAQ,EAAE,SAAS,WAAW,EAAE,SAAS,gBAAgB,CAAC,CAAC,CAAC,KAAG,YAwGhG,CAAA;;CACJ"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Option, Terminable } from "@opendaw/lib-std";
|
|
2
|
+
import { Events, ReservedShortcuts } from "@opendaw/lib-dom";
|
|
3
|
+
import { ContextMenu } from "./ContextMenu";
|
|
4
|
+
import { MenuItem } from "../menu/MenuItems";
|
|
5
|
+
import { StudioPreferences } from "../../StudioPreferences";
|
|
6
|
+
const CLIPBOARD_HEADER = "OPENDAW";
|
|
7
|
+
const CLIPBOARD_VERSION = 2;
|
|
8
|
+
export var ClipboardManager;
|
|
9
|
+
(function (ClipboardManager) {
|
|
10
|
+
let fallbackEntry = Option.None;
|
|
11
|
+
const encode = (entry) => {
|
|
12
|
+
const bytes = new Uint8Array(entry.data);
|
|
13
|
+
let binary = "";
|
|
14
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
15
|
+
binary += String.fromCharCode(bytes[i]);
|
|
16
|
+
}
|
|
17
|
+
return `${CLIPBOARD_HEADER}:${CLIPBOARD_VERSION}:${entry.type}:${btoa(binary)}`;
|
|
18
|
+
};
|
|
19
|
+
const decode = (text) => {
|
|
20
|
+
const parts = text.split(":");
|
|
21
|
+
if (parts.length < 4 || parts[0] !== CLIPBOARD_HEADER) {
|
|
22
|
+
return Option.None;
|
|
23
|
+
}
|
|
24
|
+
const version = parseInt(parts[1], 10);
|
|
25
|
+
if (version !== CLIPBOARD_VERSION) {
|
|
26
|
+
return Option.None;
|
|
27
|
+
}
|
|
28
|
+
return Option.tryCatch(() => {
|
|
29
|
+
const type = parts[2];
|
|
30
|
+
const base64 = parts.slice(3).join(":");
|
|
31
|
+
const binary = atob(base64);
|
|
32
|
+
const bytes = new Uint8Array(binary.length);
|
|
33
|
+
for (let i = 0; i < binary.length; i++) {
|
|
34
|
+
bytes[i] = binary.charCodeAt(i);
|
|
35
|
+
}
|
|
36
|
+
return { type, data: bytes.buffer };
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
ClipboardManager.install = (element, handler) => {
|
|
40
|
+
const writeEntry = (entry) => {
|
|
41
|
+
fallbackEntry = Option.wrap(entry);
|
|
42
|
+
navigator.clipboard?.writeText(encode(entry)).catch(() => { });
|
|
43
|
+
};
|
|
44
|
+
const performCopy = () => {
|
|
45
|
+
const entry = handler.copy();
|
|
46
|
+
entry.ifSome(writeEntry);
|
|
47
|
+
return entry.nonEmpty();
|
|
48
|
+
};
|
|
49
|
+
const performCut = () => {
|
|
50
|
+
const entry = handler.cut();
|
|
51
|
+
entry.ifSome(writeEntry);
|
|
52
|
+
return entry.nonEmpty();
|
|
53
|
+
};
|
|
54
|
+
const performPaste = async () => {
|
|
55
|
+
try {
|
|
56
|
+
const rawText = await navigator.clipboard.readText();
|
|
57
|
+
const text = Option.wrap(rawText);
|
|
58
|
+
const entry = text.flatMap(decode);
|
|
59
|
+
if (entry.nonEmpty()) {
|
|
60
|
+
handler.paste(entry.unwrap());
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
fallbackEntry.ifSome(entry => handler.paste(entry));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (_error) {
|
|
67
|
+
fallbackEntry.ifSome(entry => handler.paste(entry));
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
return Terminable.many(Events.subscribe(element, "copy", (event) => {
|
|
71
|
+
handler.copy().ifSome(entry => {
|
|
72
|
+
event.preventDefault();
|
|
73
|
+
event.stopPropagation();
|
|
74
|
+
const encoded = encode(entry);
|
|
75
|
+
fallbackEntry = Option.wrap(entry);
|
|
76
|
+
event.clipboardData?.setData("text/plain", encoded);
|
|
77
|
+
});
|
|
78
|
+
}), Events.subscribe(element, "cut", (event) => {
|
|
79
|
+
handler.cut().ifSome(entry => {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
event.stopPropagation();
|
|
82
|
+
const encoded = encode(entry);
|
|
83
|
+
fallbackEntry = Option.wrap(entry);
|
|
84
|
+
event.clipboardData?.setData("text/plain", encoded);
|
|
85
|
+
});
|
|
86
|
+
}), Events.subscribe(document, "paste", (event) => {
|
|
87
|
+
if (!element.contains(document.activeElement) && document.activeElement !== document.body) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const text = event.clipboardData?.getData("text/plain") ?? "";
|
|
91
|
+
const entry = decode(text);
|
|
92
|
+
if (entry.nonEmpty()) {
|
|
93
|
+
event.preventDefault();
|
|
94
|
+
handler.paste(entry.unwrap());
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
fallbackEntry.ifSome(entry => {
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
handler.paste(entry);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}), Events.subscribe(document, "keydown", (event) => {
|
|
103
|
+
if (!element.contains(document.activeElement) && document.activeElement !== document.body) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const isMod = event.metaKey || event.ctrlKey;
|
|
107
|
+
if (!isMod || event.shiftKey || event.altKey) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (event.key === "c") {
|
|
111
|
+
if (performCopy()) {
|
|
112
|
+
event.preventDefault();
|
|
113
|
+
event.stopImmediatePropagation();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else if (event.key === "x") {
|
|
117
|
+
if (performCut()) {
|
|
118
|
+
event.preventDefault();
|
|
119
|
+
event.stopImmediatePropagation();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}), ContextMenu.subscribe(element, async (collector) => {
|
|
123
|
+
if (!StudioPreferences.settings.editing["show-clipboard-menu"]) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const { client } = collector;
|
|
127
|
+
const text = await Option.async(navigator.clipboard.readText());
|
|
128
|
+
const entry = text.flatMap(decode);
|
|
129
|
+
const canPaste = entry.map(entry => handler.canPaste(entry, client))
|
|
130
|
+
.unwrapOrElse(() => fallbackEntry
|
|
131
|
+
.map(entry => handler.canPaste(entry, client)).unwrapOrElse(false));
|
|
132
|
+
collector.addItems(MenuItem.default({
|
|
133
|
+
label: "Cut",
|
|
134
|
+
shortcut: ReservedShortcuts.Cut.format(),
|
|
135
|
+
selectable: handler.canCut(client)
|
|
136
|
+
}).setTriggerProcedure(performCut), MenuItem.default({
|
|
137
|
+
label: "Copy",
|
|
138
|
+
shortcut: ReservedShortcuts.Copy.format(),
|
|
139
|
+
selectable: handler.canCopy(client)
|
|
140
|
+
}).setTriggerProcedure(performCopy), MenuItem.default({
|
|
141
|
+
label: "Paste",
|
|
142
|
+
shortcut: ReservedShortcuts.Paste.format(),
|
|
143
|
+
selectable: canPaste
|
|
144
|
+
}).setTriggerProcedure(performPaste));
|
|
145
|
+
}));
|
|
146
|
+
};
|
|
147
|
+
})(ClipboardManager || (ClipboardManager = {}));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Predicate, Procedure } from "@opendaw/lib-std";
|
|
2
|
+
import { Box, BoxGraph, SpecialDecoder } from "@opendaw/lib-box";
|
|
3
|
+
export declare namespace ClipboardUtils {
|
|
4
|
+
const extractMetadata: (data: ArrayBufferLike) => ArrayBufferLike;
|
|
5
|
+
const serializeBoxes: (boxes: ReadonlyArray<Box>, metadata?: ArrayBufferLike) => ArrayBufferLike;
|
|
6
|
+
const deserializeBoxes: <T extends Box = Box>(data: ArrayBufferLike, targetGraph: BoxGraph, options: {
|
|
7
|
+
mapPointer: SpecialDecoder["map"];
|
|
8
|
+
modifyBox?: Procedure<T>;
|
|
9
|
+
excludeBox?: Predicate<Box>;
|
|
10
|
+
}) => ReadonlyArray<T>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=ClipboardUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClipboardUtils.d.ts","sourceRoot":"","sources":["../../../src/ui/clipboard/ClipboardUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,SAAS,EAAE,SAAS,EAAO,MAAM,kBAAkB,CAAA;AACpG,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAgB,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAK5E,yBAAiB,cAAc,CAAC;IACrB,MAAM,eAAe,GAAI,MAAM,eAAe,KAAG,eAMvD,CAAA;IAEM,MAAM,cAAc,GAAI,OAAO,aAAa,CAAC,GAAG,CAAC,EACzB,WAAU,eAAoC,KAAG,eAsB/E,CAAA;IAEM,MAAM,gBAAgB,GAAI,CAAC,SAAS,GAAG,GAAG,GAAG,EAAE,MAAM,eAAe,EACrB,aAAa,QAAQ,EACrB,SAAS;QACL,UAAU,EAAE,cAAc,CAAC,KAAK,CAAC,CAAA;QACjC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;QACxB,UAAU,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;KAC9B,KAAG,aAAa,CAAC,CAAC,CAkDxE,CAAA;CACJ"}
|