@opendaw/studio-core 0.0.91 → 0.0.93
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 +2 -0
- package/dist/AudioDevices.d.ts.map +1 -1
- package/dist/AudioDevices.js +3 -0
- package/dist/AudioOfflineRenderer.d.ts +2 -0
- package/dist/AudioOfflineRenderer.d.ts.map +1 -1
- package/dist/AudioOfflineRenderer.js +2 -1
- package/dist/Engine.d.ts +2 -1
- package/dist/Engine.d.ts.map +1 -1
- package/dist/EngineFacade.d.ts +2 -1
- package/dist/EngineFacade.d.ts.map +1 -1
- package/dist/EngineFacade.js +3 -0
- package/dist/EngineWorklet.d.ts +2 -1
- package/dist/EngineWorklet.d.ts.map +1 -1
- package/dist/EngineWorklet.js +8 -2
- package/dist/OfflineEngineRenderer.d.ts +16 -5
- package/dist/OfflineEngineRenderer.d.ts.map +1 -1
- package/dist/OfflineEngineRenderer.js +85 -38
- package/dist/OpenDAWHeaders.d.ts.map +1 -1
- package/dist/OpenDAWHeaders.js +1 -2
- package/dist/RecordingWorklet.d.ts.map +1 -1
- package/dist/RecordingWorklet.js +0 -1
- package/dist/StudioPreferences.d.ts +22 -12
- package/dist/StudioPreferences.d.ts.map +1 -1
- package/dist/StudioSettings.d.ts +22 -12
- package/dist/StudioSettings.d.ts.map +1 -1
- package/dist/StudioSettings.js +41 -12
- package/dist/WavFile.d.ts.map +1 -1
- package/dist/WavFile.js +33 -9
- package/dist/capture/CaptureAudio.js +4 -4
- package/dist/capture/RecordAudio.d.ts.map +1 -1
- package/dist/capture/RecordAudio.js +49 -12
- package/dist/capture/RecordMidi.d.ts.map +1 -1
- package/dist/capture/RecordMidi.js +44 -8
- package/dist/capture/Recording.d.ts +2 -0
- package/dist/capture/Recording.d.ts.map +1 -1
- package/dist/capture/Recording.js +6 -2
- package/dist/midi/MIDIReceiver.d.ts +2 -2
- package/dist/midi/MIDIReceiver.d.ts.map +1 -1
- package/dist/midi/MIDIReceiver.js +2 -7
- package/dist/midi/index.d.ts +1 -0
- package/dist/midi/index.d.ts.map +1 -1
- package/dist/midi/index.js +1 -0
- package/dist/offline-engine.js +1 -1
- package/dist/offline-engine.js.map +3 -3
- package/dist/processors.js +15 -15
- package/dist/processors.js.map +4 -4
- package/dist/project/Project.d.ts +2 -1
- package/dist/project/Project.d.ts.map +1 -1
- package/dist/project/Project.js +18 -3
- package/dist/project/ProjectMigration.d.ts.map +1 -1
- package/dist/project/ProjectMigration.js +18 -251
- package/dist/project/migration/MigrateAudioClipBox.d.ts +4 -0
- package/dist/project/migration/MigrateAudioClipBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateAudioClipBox.js +32 -0
- package/dist/project/migration/MigrateAudioFileBox.d.ts +5 -0
- package/dist/project/migration/MigrateAudioFileBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateAudioFileBox.js +13 -0
- package/dist/project/migration/MigrateAudioRegionBox.d.ts +4 -0
- package/dist/project/migration/MigrateAudioRegionBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateAudioRegionBox.js +54 -0
- package/dist/project/migration/MigrateAudioUnitBox.d.ts +4 -0
- package/dist/project/migration/MigrateAudioUnitBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateAudioUnitBox.js +19 -0
- package/dist/project/migration/MigrateDelayDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateDelayDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateDelayDeviceBox.js +36 -0
- package/dist/project/migration/MigrateMIDIOutputDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateMIDIOutputDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateMIDIOutputDeviceBox.js +20 -0
- package/dist/project/migration/MigrateRevampDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateRevampDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateRevampDeviceBox.js +7 -0
- package/dist/project/migration/MigrateTimelineBox.d.ts +4 -0
- package/dist/project/migration/MigrateTimelineBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateTimelineBox.js +10 -0
- package/dist/project/migration/MigrateValueEventBox.d.ts +4 -0
- package/dist/project/migration/MigrateValueEventBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateValueEventBox.js +32 -0
- package/dist/project/migration/MigrateValueEventCollection.d.ts +4 -0
- package/dist/project/migration/MigrateValueEventCollection.d.ts.map +1 -0
- package/dist/project/migration/MigrateValueEventCollection.js +59 -0
- package/dist/project/migration/MigrateValueEventCollection.test.d.ts +2 -0
- package/dist/project/migration/MigrateValueEventCollection.test.d.ts.map +1 -0
- package/dist/project/migration/MigrateValueEventCollection.test.js +199 -0
- package/dist/project/migration/MigrateVaporisateurDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateVaporisateurDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateVaporisateurDeviceBox.js +28 -0
- package/dist/project/migration/MigrateZeitgeistDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateZeitgeistDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateZeitgeistDeviceBox.js +8 -0
- package/dist/project/migration/index.d.ts +13 -0
- package/dist/project/migration/index.d.ts.map +1 -0
- package/dist/project/migration/index.js +12 -0
- package/dist/samples/OpenSampleAPI.d.ts.map +1 -1
- package/dist/samples/OpenSampleAPI.js +3 -0
- package/dist/ui/generic/ClipboardManager.js +1 -1
- package/dist/ui/generic/ContextMenu.d.ts +1 -1
- package/dist/ui/generic/ContextMenu.js +1 -1
- package/dist/ui/generic/{menu-item.d.ts → MenuItems.d.ts} +1 -1
- package/dist/ui/generic/{menu-item.d.ts.map → MenuItems.d.ts.map} +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/workers-main.js +1 -1
- package/dist/workers-main.js.map +3 -3
- package/dist/ysync/YMapper.d.ts.map +1 -1
- package/dist/ysync/YMapper.js +7 -3
- package/package.json +15 -15
- /package/dist/ui/generic/{menu-item.js → MenuItems.js} +0 -0
|
@@ -10,7 +10,7 @@ import { CaptureDevices } from "../capture";
|
|
|
10
10
|
import { EngineFacade } from "../EngineFacade";
|
|
11
11
|
import { EngineWorklet } from "../EngineWorklet";
|
|
12
12
|
import { MIDILearning } from "../midi";
|
|
13
|
-
import { TempoMap } from "@opendaw/lib-dsp";
|
|
13
|
+
import { ppqn, TempoMap } from "@opendaw/lib-dsp";
|
|
14
14
|
export type RestartWorklet = {
|
|
15
15
|
unload: Func<unknown, Promise<unknown>>;
|
|
16
16
|
load: Procedure<EngineWorklet>;
|
|
@@ -65,6 +65,7 @@ export declare class Project implements BoxAdaptersContext, Terminable, Terminab
|
|
|
65
65
|
toArrayBuffer(): ArrayBufferLike;
|
|
66
66
|
copy(env?: Partial<ProjectEnv>): Project;
|
|
67
67
|
invalid(): boolean;
|
|
68
|
+
lastRegionAction(): ppqn;
|
|
68
69
|
terminate(): void;
|
|
69
70
|
}
|
|
70
71
|
//# 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,
|
|
1
|
+
{"version":3,"file":"Project.d.ts","sourceRoot":"","sources":["../../src/project/Project.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,IAAI,EAGJ,SAAS,EAGT,UAAU,EACV,eAAe,EACf,UAAU,EACV,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,UAAU,EAAE,QAAQ,EAA0B,MAAM,kBAAkB,CAAA;AAC9E,OAAO,EACH,WAAW,EAGX,YAAY,EACZ,KAAK,EAEL,OAAO,EACP,WAAW,EAEX,gBAAgB,EACnB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACH,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EAEhB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAElB,kBAAkB,EAElB,eAAe,EAClB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,qBAAqB,EAAE,kBAAkB,EAAC,MAAM,qBAAqB,CAAA;AAC7E,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AACvC,OAAO,EAAC,KAAK,EAAC,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAC,cAAc,EAAY,MAAM,YAAY,CAAA;AACpD,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAc,YAAY,EAAC,MAAM,SAAS,CAAA;AAEjD,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAW,MAAM,kBAAkB,CAAA;AAIzD,MAAM,MAAM,cAAc,GAAG;IAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC,aAAa,CAAC,CAAA;CAAE,CAAA;AAExG,MAAM,MAAM,oBAAoB,GAAG;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAA;CAC1B,CAAA;AAGD,qBAAa,OAAQ,YAAW,kBAAkB,EAAE,UAAU,EAAE,eAAe;;IAC3E,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO;IAYpE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO;WAIlD,cAAc,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAOxF,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAE,OAAc,GAAG,OAAO;IAWzG,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAE1C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,kBAAkB,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAA;IAC5D,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAA;IAClC,QAAQ,CAAC,eAAe,EAAE,YAAY,CAAA;IACtC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IAEjC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;IACxB,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;IACvC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAA;IACnC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAA;IAC/C,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAA;IACvD,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAA;IAC/C,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAA;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,MAAM,eAAqB;IAEpC,OAAO;IA+CP,iBAAiB,CAAC,OAAO,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,aAAa;IAoBtF,cAAc,CAAC,OAAO,GAAE,OAAc;IAMtC,MAAM,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;IAMnC,GAAG,CAAC,CAAC,SAAS,UAAU,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC;IAC3C,MAAM,CAAC,CAAC,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI;IAC5D,KAAK,IAAI,UAAU;IAEnB,IAAI,GAAG,IAAI,UAAU,CAAmB;IACxC,IAAI,cAAc,IAAI,cAAc,CAAmE;IACvG,IAAI,kBAAkB,IAAI,kBAAkB,CAA2E;IACvH,IAAI,aAAa,IAAI,mBAAmB,CAAiC;IACzE,IAAI,gBAAgB,IAAI,sBAAsB,CAAoC;IAClF,IAAI,cAAc,IAAI,cAAc,CAAkD;IACtF,IAAI,cAAc,IAAI,OAAO,CAAe;IAC5C,IAAI,YAAY,IAAI,OAAO,CAAc;IACzC,IAAI,qBAAqB,IAAI,qBAAqB,CAAkD;IAEpG,IAAI,QAAQ,IAAI,eAAe,CAW9B;IAED,sBAAsB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAe9F,kBAAkB,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;IAM/C,gBAAgB,IAAI,IAAI;IAqBxB,aAAa,IAAI,eAAe;IAEhC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO;IAIxC,OAAO,IAAI,OAAO;IAmBlB,gBAAgB,IAAI,IAAI;IAOxB,SAAS,IAAI,IAAI;CAcpB"}
|
package/dist/project/Project.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Arrays, panic, safeExecute, Terminator, UUID } from "@opendaw/lib-std";
|
|
1
|
+
import { Arrays, isDefined, panic, 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
4
|
import { BoxAdapters, ParameterFieldAdapters, ProjectSkeleton, RootBoxAdapter, TimelineBoxAdapter, UnionBoxTypes, UserEditingManager, VaryingTempoMap, VertexSelection } from "@opendaw/studio-adapters";
|
|
@@ -17,7 +17,7 @@ import { StudioPreferences } from "../StudioPreferences";
|
|
|
17
17
|
export class Project {
|
|
18
18
|
static new(env, options) {
|
|
19
19
|
const createDefaultUser = options?.noDefaultUser !== true;
|
|
20
|
-
const createOutputCompressor = StudioPreferences.settings["auto-create-output-compressor"];
|
|
20
|
+
const createOutputCompressor = StudioPreferences.settings.engine["auto-create-output-compressor"];
|
|
21
21
|
const { boxGraph, mandatoryBoxes } = ProjectSkeleton.empty({
|
|
22
22
|
createOutputCompressor,
|
|
23
23
|
createDefaultUser
|
|
@@ -180,6 +180,7 @@ export class Project {
|
|
|
180
180
|
}
|
|
181
181
|
restartRecording() {
|
|
182
182
|
if (this.engine.isRecording.getValue()) {
|
|
183
|
+
const countingIn = Recording.wasCountingIn();
|
|
183
184
|
this.engine.stopRecording();
|
|
184
185
|
this.editing.modify(() => this.captureDevices.filterArmed()
|
|
185
186
|
.forEach(capture => {
|
|
@@ -187,7 +188,15 @@ export class Project {
|
|
|
187
188
|
capture.clearRecordedRegions();
|
|
188
189
|
}), false);
|
|
189
190
|
this.engine.stop(true);
|
|
190
|
-
|
|
191
|
+
const subscription = this.engine.isRecording.catchupAndSubscribe(owner => {
|
|
192
|
+
if (!owner.getValue()) {
|
|
193
|
+
queueMicrotask(() => subscription.terminate());
|
|
194
|
+
this.startRecording(countingIn);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
this.startRecording();
|
|
191
200
|
}
|
|
192
201
|
}
|
|
193
202
|
toArrayBuffer() { return ProjectSkeleton.encode(this.boxGraph); }
|
|
@@ -212,6 +221,12 @@ export class Project {
|
|
|
212
221
|
}
|
|
213
222
|
}) ?? false);
|
|
214
223
|
}
|
|
224
|
+
lastRegionAction() {
|
|
225
|
+
return this.rootBoxAdapter.audioUnits.adapters()
|
|
226
|
+
.flatMap(audioUnitAdapter => audioUnitAdapter.tracks.values()
|
|
227
|
+
.map(trackAdapter => trackAdapter.regions.collection.asArray().at(-1)))
|
|
228
|
+
.filter(isDefined).reduce((position, region) => Math.max(position, region.complete), 0);
|
|
229
|
+
}
|
|
215
230
|
terminate() {
|
|
216
231
|
this.#sampleRegistrations.forEach(({ terminable }) => terminable.terminate());
|
|
217
232
|
this.#sampleRegistrations.clear();
|
|
@@ -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":"AAiBA,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAA;AAExD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AAgBvC,qBAAa,gBAAgB;WACZ,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,EAAC,QAAQ,EAAE,cAAc,EAAC,EAAE,eAAe;CA6DpF"}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { PPQN, TimeBase } from "@opendaw/lib-dsp";
|
|
5
|
-
import { AudioContentHelpers } from "./audio/AudioContentHelpers";
|
|
6
|
-
const isIntEncodedAsFloat = (v) => v > 0 && v < 1e-6 && Number.isFinite(v) && (v / 1.401298464324817e-45) % 1 === 0;
|
|
7
|
-
const toSeconds = (property, bpm) => {
|
|
8
|
-
return PPQN.pulsesToSeconds(property.getValue(), bpm);
|
|
9
|
-
};
|
|
1
|
+
import { GrooveShuffleBox } from "@opendaw/studio-boxes";
|
|
2
|
+
import { asInstanceOf, UUID } from "@opendaw/lib-std";
|
|
3
|
+
import { migrateAudioClipBox, migrateAudioFileBox, migrateAudioRegionBox, migrateAudioUnitBox, migrateDelayDeviceBox, migrateMIDIOutputDeviceBox, migrateRevampDeviceBox, migrateTimelineBox, migrateValueEventBox, migrateValueEventCollection, migrateVaporisateurDeviceBox, migrateZeitgeistDeviceBox } from "./migration";
|
|
10
4
|
export class ProjectMigration {
|
|
11
5
|
static async migrate(env, { boxGraph, mandatoryBoxes }) {
|
|
12
6
|
const { rootBox, timelineBox: { bpm } } = mandatoryBoxes;
|
|
@@ -46,255 +40,28 @@ export class ProjectMigration {
|
|
|
46
40
|
orphans.forEach(orphan => orphan.delete());
|
|
47
41
|
boxGraph.endTransaction();
|
|
48
42
|
}
|
|
43
|
+
const grooveTarget = rootBox.groove.targetVertex.unwrap();
|
|
44
|
+
const outputMidiDevices = rootBox.outputMidiDevices;
|
|
45
|
+
const bpmValue = bpm.getValue();
|
|
49
46
|
// 1st pass (2nd pass might rely on those changes)
|
|
50
47
|
for (const box of boxGraph.boxes()) {
|
|
51
48
|
await box.accept({
|
|
52
|
-
visitAudioFileBox:
|
|
53
|
-
const { startInSeconds, endInSeconds, fileName } = box;
|
|
54
|
-
if (isIntEncodedAsFloat(startInSeconds.getValue()) || isIntEncodedAsFloat(endInSeconds.getValue()) || endInSeconds.getValue() === 0) {
|
|
55
|
-
const audioData = await loadAudioData(box.address.uuid);
|
|
56
|
-
const seconds = audioData.numberOfFrames / audioData.sampleRate;
|
|
57
|
-
console.debug(`Migrate 'AudioFileBox' to float sec (${fileName.getValue()})`, seconds.toFixed(3));
|
|
58
|
-
boxGraph.beginTransaction();
|
|
59
|
-
startInSeconds.setValue(0);
|
|
60
|
-
endInSeconds.setValue(seconds);
|
|
61
|
-
boxGraph.endTransaction();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
49
|
+
visitAudioFileBox: (box) => migrateAudioFileBox(boxGraph, box, loadAudioData)
|
|
64
50
|
});
|
|
65
51
|
}
|
|
66
52
|
// 2nd pass. We need to run on a copy, because we might add more boxes during the migration
|
|
67
53
|
boxGraph.boxes().slice().forEach(box => box.accept({
|
|
68
|
-
visitAudioRegionBox: (box) =>
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
if (playback.getValue() === AudioPlayback.AudioFit) {
|
|
81
|
-
console.debug("Migrate 'AudioRegionBox' to AudioPlayback.NoSync");
|
|
82
|
-
boxGraph.beginTransaction();
|
|
83
|
-
const file = asInstanceOf(box.file.targetVertex.unwrap(), AudioFileBox);
|
|
84
|
-
const fileDuration = file.endInSeconds.getValue() - file.startInSeconds.getValue();
|
|
85
|
-
const currentLoopDurationSeconds = toSeconds(box.loopDuration, bpm.getValue());
|
|
86
|
-
const scale = fileDuration / currentLoopDurationSeconds;
|
|
87
|
-
const currentDurationSeconds = toSeconds(box.duration, bpm.getValue());
|
|
88
|
-
const currentLoopOffsetSeconds = toSeconds(box.loopOffset, bpm.getValue());
|
|
89
|
-
box.timeBase.setValue(TimeBase.Seconds);
|
|
90
|
-
box.duration.setValue(currentDurationSeconds * scale);
|
|
91
|
-
box.loopDuration.setValue(fileDuration);
|
|
92
|
-
box.loopOffset.setValue(currentLoopOffsetSeconds * scale);
|
|
93
|
-
box.playback.setValue("");
|
|
94
|
-
boxGraph.endTransaction();
|
|
95
|
-
}
|
|
96
|
-
else if (playback.getValue() === AudioPlayback.Pitch) {
|
|
97
|
-
console.debug("Migrate 'AudioRegionBox' to new PitchStretchBox");
|
|
98
|
-
boxGraph.beginTransaction();
|
|
99
|
-
const file = asInstanceOf(box.file.targetVertex.unwrap(), AudioFileBox);
|
|
100
|
-
const fileDuration = file.endInSeconds.getValue() - file.startInSeconds.getValue();
|
|
101
|
-
const pitchBox = AudioPitchStretchBox.create(boxGraph, UUID.generate());
|
|
102
|
-
AudioContentHelpers.addDefaultWarpMarkers(boxGraph, pitchBox, box.loopDuration.getValue(), fileDuration);
|
|
103
|
-
box.timeBase.setValue(TimeBase.Musical);
|
|
104
|
-
box.playMode.refer(pitchBox);
|
|
105
|
-
box.playback.setValue("");
|
|
106
|
-
boxGraph.endTransaction();
|
|
107
|
-
}
|
|
108
|
-
if (box.events.isEmpty()) {
|
|
109
|
-
console.debug("Migrate 'AudioRegionBox' to have a ValueEventCollectionBox");
|
|
110
|
-
boxGraph.beginTransaction();
|
|
111
|
-
box.events.refer(ValueEventCollectionBox.create(boxGraph, UUID.generate()).owners);
|
|
112
|
-
boxGraph.endTransaction();
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
visitAudioClipBox: (box) => {
|
|
116
|
-
if (box.events.isEmpty()) {
|
|
117
|
-
console.debug("Migrate 'AudioClipBox' to have a ValueEventCollectionBox");
|
|
118
|
-
boxGraph.beginTransaction();
|
|
119
|
-
box.events.refer(ValueEventCollectionBox.create(boxGraph, UUID.generate()).owners);
|
|
120
|
-
boxGraph.endTransaction();
|
|
121
|
-
}
|
|
122
|
-
if (isIntEncodedAsFloat(box.duration.getValue())) {
|
|
123
|
-
console.debug("Migrate 'AudioClipBox' to float");
|
|
124
|
-
boxGraph.beginTransaction();
|
|
125
|
-
box.duration.setValue(Float.floatToIntBits(box.duration.getValue()));
|
|
126
|
-
boxGraph.endTransaction();
|
|
127
|
-
}
|
|
128
|
-
if (box.playback.getValue() === AudioPlayback.Pitch) {
|
|
129
|
-
console.debug("Migrate 'AudioClipBox' to new PitchStretchBox");
|
|
130
|
-
boxGraph.beginTransaction();
|
|
131
|
-
const file = asInstanceOf(box.file.targetVertex.unwrap(), AudioFileBox);
|
|
132
|
-
const fileDuration = file.endInSeconds.getValue() - file.startInSeconds.getValue();
|
|
133
|
-
const pitchBox = AudioPitchStretchBox.create(boxGraph, UUID.generate());
|
|
134
|
-
AudioContentHelpers.addDefaultWarpMarkers(boxGraph, pitchBox, box.duration.getValue(), fileDuration);
|
|
135
|
-
box.timeBase.setValue(TimeBase.Musical);
|
|
136
|
-
box.playMode.refer(pitchBox);
|
|
137
|
-
box.playback.setValue("");
|
|
138
|
-
boxGraph.endTransaction();
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
visitTimelineBox: (timelineBox) => {
|
|
142
|
-
if (timelineBox.tempoTrack.events.isEmpty()) {
|
|
143
|
-
console.debug("Migrate 'TimelineBox' to have a ValueEventCollectionBox for tempo events");
|
|
144
|
-
boxGraph.beginTransaction();
|
|
145
|
-
ValueEventCollectionBox.create(boxGraph, UUID.generate(), box => timelineBox.tempoTrack.events.refer(box.owners));
|
|
146
|
-
boxGraph.endTransaction();
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
|
-
visitMIDIOutputDeviceBox: (deviceBox) => {
|
|
150
|
-
const id = deviceBox.deprecatedDevice.id.getValue();
|
|
151
|
-
const label = deviceBox.deprecatedDevice.label.getValue();
|
|
152
|
-
const delay = deviceBox.deprecatedDelay.getValue();
|
|
153
|
-
if (id !== "") {
|
|
154
|
-
console.debug("Migrate 'MIDIOutputDeviceBox' to MIDIOutputBox");
|
|
155
|
-
boxGraph.beginTransaction();
|
|
156
|
-
deviceBox.device.refer(MIDIOutputBox.create(boxGraph, UUID.generate(), box => {
|
|
157
|
-
box.id.setValue(id);
|
|
158
|
-
box.label.setValue(label);
|
|
159
|
-
box.delayInMs.setValue(delay);
|
|
160
|
-
box.root.refer(rootBox.outputMidiDevices);
|
|
161
|
-
}).device);
|
|
162
|
-
// clear all data
|
|
163
|
-
deviceBox.deprecatedDevice.id.setValue("");
|
|
164
|
-
deviceBox.deprecatedDevice.label.setValue("");
|
|
165
|
-
boxGraph.endTransaction();
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
visitZeitgeistDeviceBox: (box) => {
|
|
169
|
-
if (box.groove.targetAddress.isEmpty()) {
|
|
170
|
-
console.debug("Migrate 'ZeitgeistDeviceBox' to GrooveShuffleBox");
|
|
171
|
-
boxGraph.beginTransaction();
|
|
172
|
-
box.groove.refer(rootBox.groove.targetVertex.unwrap());
|
|
173
|
-
boxGraph.endTransaction();
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
visitValueEventBox: (eventBox) => {
|
|
177
|
-
const slope = eventBox.slope.getValue();
|
|
178
|
-
if (isNaN(slope)) {
|
|
179
|
-
return;
|
|
180
|
-
} // already migrated, nothing to do
|
|
181
|
-
if (slope === 0.0) { // never set
|
|
182
|
-
console.debug("Migrate 'ValueEventBox'");
|
|
183
|
-
boxGraph.beginTransaction();
|
|
184
|
-
eventBox.slope.setValue(NaN);
|
|
185
|
-
boxGraph.endTransaction();
|
|
186
|
-
}
|
|
187
|
-
else if (eventBox.interpolation.getValue() === 1) { // linear
|
|
188
|
-
if (slope === 0.5) {
|
|
189
|
-
console.debug("Migrate 'ValueEventBox' to linear");
|
|
190
|
-
boxGraph.beginTransaction();
|
|
191
|
-
eventBox.slope.setValue(NaN);
|
|
192
|
-
boxGraph.endTransaction();
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
console.debug("Migrate 'ValueEventBox' to new ValueEventCurveBox");
|
|
196
|
-
boxGraph.beginTransaction();
|
|
197
|
-
ValueEventCurveBox.create(boxGraph, UUID.generate(), box => {
|
|
198
|
-
box.event.refer(eventBox.interpolation);
|
|
199
|
-
box.slope.setValue(slope);
|
|
200
|
-
});
|
|
201
|
-
eventBox.slope.setValue(NaN);
|
|
202
|
-
boxGraph.endTransaction();
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
visitAudioUnitBox: (box) => {
|
|
207
|
-
if (box.type.getValue() !== AudioUnitType.Instrument || box.capture.nonEmpty()) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
boxGraph.beginTransaction();
|
|
211
|
-
const captureBox = asDefined(box.input.pointerHub.incoming().at(0)?.box
|
|
212
|
-
.accept({
|
|
213
|
-
visitVaporisateurDeviceBox: () => CaptureMidiBox.create(boxGraph, UUID.generate()),
|
|
214
|
-
visitNanoDeviceBox: () => CaptureMidiBox.create(boxGraph, UUID.generate()),
|
|
215
|
-
visitPlayfieldDeviceBox: () => CaptureMidiBox.create(boxGraph, UUID.generate()),
|
|
216
|
-
visitTapeDeviceBox: () => CaptureAudioBox.create(boxGraph, UUID.generate())
|
|
217
|
-
}));
|
|
218
|
-
box.capture.refer(captureBox);
|
|
219
|
-
boxGraph.endTransaction();
|
|
220
|
-
},
|
|
221
|
-
visitRevampDeviceBox: (box) => {
|
|
222
|
-
// Clamp order in RevampDeviceBox to 0-3
|
|
223
|
-
// The older version stored the actual order,
|
|
224
|
-
// but the new version only stores indices, so 4 is not valid anymore
|
|
225
|
-
boxGraph.beginTransaction();
|
|
226
|
-
box.lowPass.order.setValue(clamp(box.lowPass.order.getValue(), 0, 3));
|
|
227
|
-
box.highPass.order.setValue(clamp(box.highPass.order.getValue(), 0, 3));
|
|
228
|
-
boxGraph.endTransaction();
|
|
229
|
-
},
|
|
230
|
-
visitVaporisateurDeviceBox: (box) => {
|
|
231
|
-
if (box.version.getValue() === 0) {
|
|
232
|
-
console.debug("Migrate 'VaporisateurDeviceBox to zero db");
|
|
233
|
-
boxGraph.beginTransaction();
|
|
234
|
-
box.volume.setValue(box.volume.getValue() - 15.0);
|
|
235
|
-
box.version.setValue(1);
|
|
236
|
-
boxGraph.endTransaction();
|
|
237
|
-
}
|
|
238
|
-
if (box.version.getValue() === 1) {
|
|
239
|
-
console.debug("Migrate 'VaporisateurDeviceBox to extended osc");
|
|
240
|
-
boxGraph.beginTransaction();
|
|
241
|
-
const [oscA, oscB] = box.oscillators.fields();
|
|
242
|
-
const movePointers = (oldTarget, newTarget) => {
|
|
243
|
-
oldTarget.pointerHub.incoming().forEach((pointer) => pointer.refer(newTarget));
|
|
244
|
-
};
|
|
245
|
-
movePointers(box.waveform, oscA.waveform);
|
|
246
|
-
movePointers(box.octave, oscA.octave);
|
|
247
|
-
movePointers(box.tune, oscA.tune);
|
|
248
|
-
movePointers(box.volume, oscA.volume);
|
|
249
|
-
oscA.waveform.setValue(box.waveform.getValue());
|
|
250
|
-
oscA.octave.setValue(box.octave.getValue());
|
|
251
|
-
oscA.tune.setValue(box.tune.getValue());
|
|
252
|
-
oscA.volume.setValue(box.volume.getValue());
|
|
253
|
-
oscB.volume.setValue(Number.NEGATIVE_INFINITY);
|
|
254
|
-
box.version.setValue(2);
|
|
255
|
-
boxGraph.endTransaction();
|
|
256
|
-
}
|
|
257
|
-
},
|
|
258
|
-
visitDelayDeviceBox: (box) => {
|
|
259
|
-
// Version 0: old descending array (17 values)
|
|
260
|
-
// Version 1: new ascending array with off (21 values)
|
|
261
|
-
if (box.version.getValue() !== 0) {
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
// Old descending: 1/1, 1/2, 1/3, 1/4, 3/16, 1/6, 1/8, 3/32, 1/12, 1/16, 3/64, 1/24, 1/32, 1/48, 1/64, 1/96, 1/128
|
|
265
|
-
// New ascending: off, 1/128, 1/96, 1/64, 1/48, 1/32, 1/24, 3/64, 1/16, 1/12, 3/32, 1/8, 1/6, 3/16, 1/4, 5/16, 1/3, 3/8, 7/16, 1/2, 1/1
|
|
266
|
-
// Mapping: old[i] fraction -> find the same fraction in the new array
|
|
267
|
-
const oldToNewIndex = [20, 19, 16, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
|
|
268
|
-
const oldMaxIndex = 16;
|
|
269
|
-
const newMaxIndex = 20;
|
|
270
|
-
const oldIndex = box.delayMusical.getValue();
|
|
271
|
-
const newIndex = oldToNewIndex[Math.round(clamp(oldIndex, 0, oldMaxIndex))];
|
|
272
|
-
console.debug(`Migrate 'DelayDeviceBox' delay index from ${oldIndex} to ${newIndex}`);
|
|
273
|
-
boxGraph.beginTransaction();
|
|
274
|
-
box.delayMusical.setValue(newIndex);
|
|
275
|
-
box.delayMillis.setValue(0);
|
|
276
|
-
box.preSyncTimeLeft.setValue(0);
|
|
277
|
-
box.preMillisTimeLeft.setValue(0);
|
|
278
|
-
box.preSyncTimeRight.setValue(0);
|
|
279
|
-
box.preMillisTimeRight.setValue(0);
|
|
280
|
-
box.version.setValue(1);
|
|
281
|
-
// Migrate automation events targeting the delay field
|
|
282
|
-
// Automation stores normalized values in [0, 1] range
|
|
283
|
-
box.delayMusical.pointerHub.incoming().forEach(pointer => {
|
|
284
|
-
const eventBox = pointer.box.accept({
|
|
285
|
-
visitValueEventBox: (event) => event
|
|
286
|
-
});
|
|
287
|
-
if (isDefined(eventBox)) {
|
|
288
|
-
const oldNormalized = eventBox.value.getValue();
|
|
289
|
-
const oldEventIndex = Math.round(oldNormalized * oldMaxIndex);
|
|
290
|
-
const newEventIndex = oldToNewIndex[clamp(oldEventIndex, 0, oldMaxIndex)];
|
|
291
|
-
const newNormalized = newEventIndex / newMaxIndex;
|
|
292
|
-
console.debug(` Migrate automation: ${oldNormalized.toFixed(4)} (idx ${oldEventIndex}) -> ${newNormalized.toFixed(4)} (idx ${newEventIndex})`);
|
|
293
|
-
eventBox.value.setValue(newNormalized);
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
boxGraph.endTransaction();
|
|
297
|
-
}
|
|
54
|
+
visitAudioRegionBox: (box) => migrateAudioRegionBox(boxGraph, box, bpmValue),
|
|
55
|
+
visitAudioClipBox: (box) => migrateAudioClipBox(boxGraph, box),
|
|
56
|
+
visitTimelineBox: (box) => migrateTimelineBox(boxGraph, box),
|
|
57
|
+
visitMIDIOutputDeviceBox: (box) => migrateMIDIOutputDeviceBox(boxGraph, box, outputMidiDevices),
|
|
58
|
+
visitZeitgeistDeviceBox: (box) => migrateZeitgeistDeviceBox(boxGraph, box, grooveTarget),
|
|
59
|
+
visitValueEventBox: (box) => migrateValueEventBox(boxGraph, box),
|
|
60
|
+
visitAudioUnitBox: (box) => migrateAudioUnitBox(boxGraph, box),
|
|
61
|
+
visitRevampDeviceBox: (box) => migrateRevampDeviceBox(boxGraph, box),
|
|
62
|
+
visitVaporisateurDeviceBox: (box) => migrateVaporisateurDeviceBox(boxGraph, box),
|
|
63
|
+
visitValueEventCollectionBox: (box) => migrateValueEventCollection(boxGraph, box),
|
|
64
|
+
visitDelayDeviceBox: (box) => migrateDelayDeviceBox(boxGraph, box)
|
|
298
65
|
}));
|
|
299
66
|
}
|
|
300
67
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigrateAudioClipBox.d.ts","sourceRoot":"","sources":["../../../src/project/migration/MigrateAudioClipBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAC,YAAY,EAAsC,KAAK,EAA0B,MAAM,uBAAuB,CAAA;AAQtH,eAAO,MAAM,mBAAmB,GAAI,UAAU,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,YAAY,KAAG,IAyB1F,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { asInstanceOf, Float, UUID } from "@opendaw/lib-std";
|
|
2
|
+
import { AudioFileBox, AudioPitchStretchBox, ValueEventCollectionBox } from "@opendaw/studio-boxes";
|
|
3
|
+
import { AudioPlayback } from "@opendaw/studio-enums";
|
|
4
|
+
import { TimeBase } from "@opendaw/lib-dsp";
|
|
5
|
+
import { AudioContentHelpers } from "../audio/AudioContentHelpers";
|
|
6
|
+
const isIntEncodedAsFloat = (v) => v > 0 && v < 1e-6 && Number.isFinite(v) && (v / 1.401298464324817e-45) % 1 === 0;
|
|
7
|
+
export const migrateAudioClipBox = (boxGraph, box) => {
|
|
8
|
+
if (box.events.isEmpty()) {
|
|
9
|
+
console.debug("Migrate 'AudioClipBox' to have a ValueEventCollectionBox");
|
|
10
|
+
boxGraph.beginTransaction();
|
|
11
|
+
box.events.refer(ValueEventCollectionBox.create(boxGraph, UUID.generate()).owners);
|
|
12
|
+
boxGraph.endTransaction();
|
|
13
|
+
}
|
|
14
|
+
if (isIntEncodedAsFloat(box.duration.getValue())) {
|
|
15
|
+
console.debug("Migrate 'AudioClipBox' to float");
|
|
16
|
+
boxGraph.beginTransaction();
|
|
17
|
+
box.duration.setValue(Float.floatToIntBits(box.duration.getValue()));
|
|
18
|
+
boxGraph.endTransaction();
|
|
19
|
+
}
|
|
20
|
+
if (box.playback.getValue() === AudioPlayback.Pitch) {
|
|
21
|
+
console.debug("Migrate 'AudioClipBox' to new PitchStretchBox");
|
|
22
|
+
boxGraph.beginTransaction();
|
|
23
|
+
const file = asInstanceOf(box.file.targetVertex.unwrap(), AudioFileBox);
|
|
24
|
+
const fileDuration = file.endInSeconds.getValue() - file.startInSeconds.getValue();
|
|
25
|
+
const pitchBox = AudioPitchStretchBox.create(boxGraph, UUID.generate());
|
|
26
|
+
AudioContentHelpers.addDefaultWarpMarkers(boxGraph, pitchBox, box.duration.getValue(), fileDuration);
|
|
27
|
+
box.timeBase.setValue(TimeBase.Musical);
|
|
28
|
+
box.playMode.refer(pitchBox);
|
|
29
|
+
box.playback.setValue("");
|
|
30
|
+
boxGraph.endTransaction();
|
|
31
|
+
}
|
|
32
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { BoxGraph } from "@opendaw/lib-box";
|
|
2
|
+
import { AudioData } from "@opendaw/lib-dsp";
|
|
3
|
+
import { AudioFileBox, BoxIO } from "@opendaw/studio-boxes";
|
|
4
|
+
export declare const migrateAudioFileBox: (boxGraph: BoxGraph<BoxIO.TypeMap>, box: AudioFileBox, loadAudioData: (uuid: Uint8Array) => Promise<AudioData>) => Promise<void>;
|
|
5
|
+
//# sourceMappingURL=MigrateAudioFileBox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigrateAudioFileBox.d.ts","sourceRoot":"","sources":["../../../src/project/migration/MigrateAudioFileBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAC,SAAS,EAAC,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAC,YAAY,EAAE,KAAK,EAAC,MAAM,uBAAuB,CAAA;AAKzD,eAAO,MAAM,mBAAmB,GAC5B,UAAU,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EACjC,KAAK,YAAY,EACjB,eAAe,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,SAAS,CAAC,KACxD,OAAO,CAAC,IAAI,CAWd,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const isIntEncodedAsFloat = (v) => v > 0 && v < 1e-6 && Number.isFinite(v) && (v / 1.401298464324817e-45) % 1 === 0;
|
|
2
|
+
export const migrateAudioFileBox = async (boxGraph, box, loadAudioData) => {
|
|
3
|
+
const { startInSeconds, endInSeconds, fileName } = box;
|
|
4
|
+
if (isIntEncodedAsFloat(startInSeconds.getValue()) || isIntEncodedAsFloat(endInSeconds.getValue()) || endInSeconds.getValue() === 0) {
|
|
5
|
+
const audioData = await loadAudioData(box.address.uuid);
|
|
6
|
+
const seconds = audioData.numberOfFrames / audioData.sampleRate;
|
|
7
|
+
console.debug(`Migrate 'AudioFileBox' to float sec (${fileName.getValue()})`, seconds.toFixed(3));
|
|
8
|
+
boxGraph.beginTransaction();
|
|
9
|
+
startInSeconds.setValue(0);
|
|
10
|
+
endInSeconds.setValue(seconds);
|
|
11
|
+
boxGraph.endTransaction();
|
|
12
|
+
}
|
|
13
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { BoxGraph } from "@opendaw/lib-box";
|
|
2
|
+
import { AudioRegionBox, BoxIO } from "@opendaw/studio-boxes";
|
|
3
|
+
export declare const migrateAudioRegionBox: (boxGraph: BoxGraph<BoxIO.TypeMap>, box: AudioRegionBox, bpm: number) => void;
|
|
4
|
+
//# sourceMappingURL=MigrateAudioRegionBox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigrateAudioRegionBox.d.ts","sourceRoot":"","sources":["../../../src/project/migration/MigrateAudioRegionBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAqC,cAAc,EAAE,KAAK,EAA0B,MAAM,uBAAuB,CAAA;AAWxH,eAAO,MAAM,qBAAqB,GAAI,UAAU,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,cAAc,EAAE,KAAK,MAAM,KAAG,IA6C3G,CAAA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { asInstanceOf, Float, UUID } from "@opendaw/lib-std";
|
|
2
|
+
import { AudioFileBox, AudioPitchStretchBox, ValueEventCollectionBox } from "@opendaw/studio-boxes";
|
|
3
|
+
import { AudioPlayback } from "@opendaw/studio-enums";
|
|
4
|
+
import { PPQN, TimeBase } from "@opendaw/lib-dsp";
|
|
5
|
+
import { AudioContentHelpers } from "../audio/AudioContentHelpers";
|
|
6
|
+
const isIntEncodedAsFloat = (v) => v > 0 && v < 1e-6 && Number.isFinite(v) && (v / 1.401298464324817e-45) % 1 === 0;
|
|
7
|
+
const toSeconds = (property, bpm) => PPQN.pulsesToSeconds(property.getValue(), bpm);
|
|
8
|
+
export const migrateAudioRegionBox = (boxGraph, box, bpm) => {
|
|
9
|
+
const { duration, loopOffset, loopDuration, playback } = box;
|
|
10
|
+
if (isIntEncodedAsFloat(duration.getValue())
|
|
11
|
+
|| isIntEncodedAsFloat(loopOffset.getValue())
|
|
12
|
+
|| isIntEncodedAsFloat(loopDuration.getValue())) {
|
|
13
|
+
console.debug("Migrate 'AudioRegionBox' to float");
|
|
14
|
+
boxGraph.beginTransaction();
|
|
15
|
+
duration.setValue(Float.floatToIntBits(duration.getValue()));
|
|
16
|
+
loopOffset.setValue(Float.floatToIntBits(loopOffset.getValue()));
|
|
17
|
+
loopDuration.setValue(Float.floatToIntBits(loopDuration.getValue()));
|
|
18
|
+
boxGraph.endTransaction();
|
|
19
|
+
}
|
|
20
|
+
if (playback.getValue() === AudioPlayback.AudioFit) {
|
|
21
|
+
console.debug("Migrate 'AudioRegionBox' to AudioPlayback.NoSync");
|
|
22
|
+
boxGraph.beginTransaction();
|
|
23
|
+
const file = asInstanceOf(box.file.targetVertex.unwrap(), AudioFileBox);
|
|
24
|
+
const fileDuration = file.endInSeconds.getValue() - file.startInSeconds.getValue();
|
|
25
|
+
const currentLoopDurationSeconds = toSeconds(box.loopDuration, bpm);
|
|
26
|
+
const scale = fileDuration / currentLoopDurationSeconds;
|
|
27
|
+
const currentDurationSeconds = toSeconds(box.duration, bpm);
|
|
28
|
+
const currentLoopOffsetSeconds = toSeconds(box.loopOffset, bpm);
|
|
29
|
+
box.timeBase.setValue(TimeBase.Seconds);
|
|
30
|
+
box.duration.setValue(currentDurationSeconds * scale);
|
|
31
|
+
box.loopDuration.setValue(fileDuration);
|
|
32
|
+
box.loopOffset.setValue(currentLoopOffsetSeconds * scale);
|
|
33
|
+
box.playback.setValue("");
|
|
34
|
+
boxGraph.endTransaction();
|
|
35
|
+
}
|
|
36
|
+
else if (playback.getValue() === AudioPlayback.Pitch) {
|
|
37
|
+
console.debug("Migrate 'AudioRegionBox' to new PitchStretchBox");
|
|
38
|
+
boxGraph.beginTransaction();
|
|
39
|
+
const file = asInstanceOf(box.file.targetVertex.unwrap(), AudioFileBox);
|
|
40
|
+
const fileDuration = file.endInSeconds.getValue() - file.startInSeconds.getValue();
|
|
41
|
+
const pitchBox = AudioPitchStretchBox.create(boxGraph, UUID.generate());
|
|
42
|
+
AudioContentHelpers.addDefaultWarpMarkers(boxGraph, pitchBox, box.loopDuration.getValue(), fileDuration);
|
|
43
|
+
box.timeBase.setValue(TimeBase.Musical);
|
|
44
|
+
box.playMode.refer(pitchBox);
|
|
45
|
+
box.playback.setValue("");
|
|
46
|
+
boxGraph.endTransaction();
|
|
47
|
+
}
|
|
48
|
+
if (box.events.isEmpty()) {
|
|
49
|
+
console.debug("Migrate 'AudioRegionBox' to have a ValueEventCollectionBox");
|
|
50
|
+
boxGraph.beginTransaction();
|
|
51
|
+
box.events.refer(ValueEventCollectionBox.create(boxGraph, UUID.generate()).owners);
|
|
52
|
+
boxGraph.endTransaction();
|
|
53
|
+
}
|
|
54
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigrateAudioUnitBox.d.ts","sourceRoot":"","sources":["../../../src/project/migration/MigrateAudioUnitBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAC,YAAY,EAAE,KAAK,EAA8C,MAAM,uBAAuB,CAAA;AAItG,eAAO,MAAM,mBAAmB,GAAI,UAAU,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,YAAY,KAAG,IAY1F,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { asDefined } from "@opendaw/lib-std";
|
|
2
|
+
import { CaptureAudioBox, CaptureMidiBox } from "@opendaw/studio-boxes";
|
|
3
|
+
import { AudioUnitType } from "@opendaw/studio-enums";
|
|
4
|
+
import { UUID } from "@opendaw/lib-std";
|
|
5
|
+
export const migrateAudioUnitBox = (boxGraph, box) => {
|
|
6
|
+
if (box.type.getValue() !== AudioUnitType.Instrument || box.capture.nonEmpty()) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
boxGraph.beginTransaction();
|
|
10
|
+
const captureBox = asDefined(box.input.pointerHub.incoming().at(0)?.box
|
|
11
|
+
.accept({
|
|
12
|
+
visitVaporisateurDeviceBox: () => CaptureMidiBox.create(boxGraph, UUID.generate()),
|
|
13
|
+
visitNanoDeviceBox: () => CaptureMidiBox.create(boxGraph, UUID.generate()),
|
|
14
|
+
visitPlayfieldDeviceBox: () => CaptureMidiBox.create(boxGraph, UUID.generate()),
|
|
15
|
+
visitTapeDeviceBox: () => CaptureAudioBox.create(boxGraph, UUID.generate())
|
|
16
|
+
}));
|
|
17
|
+
box.capture.refer(captureBox);
|
|
18
|
+
boxGraph.endTransaction();
|
|
19
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { BoxGraph } from "@opendaw/lib-box";
|
|
2
|
+
import { BoxIO, DelayDeviceBox } from "@opendaw/studio-boxes";
|
|
3
|
+
export declare const migrateDelayDeviceBox: (boxGraph: BoxGraph<BoxIO.TypeMap>, box: DelayDeviceBox) => void;
|
|
4
|
+
//# sourceMappingURL=MigrateDelayDeviceBox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigrateDelayDeviceBox.d.ts","sourceRoot":"","sources":["../../../src/project/migration/MigrateDelayDeviceBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAC,KAAK,EAAc,cAAc,EAAgB,MAAM,uBAAuB,CAAA;AAEtF,eAAO,MAAM,qBAAqB,GAAI,UAAU,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,cAAc,KAAG,IAgC9F,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { clamp, isDefined } from "@opendaw/lib-std";
|
|
2
|
+
export const migrateDelayDeviceBox = (boxGraph, box) => {
|
|
3
|
+
if (box.version.getValue() !== 0) {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
// Old descending: 1/1, 1/2, 1/3, 1/4, 3/16, 1/6, 1/8, 3/32, 1/12, 1/16, 3/64, 1/24, 1/32, 1/48, 1/64, 1/96, 1/128
|
|
7
|
+
// New ascending: off, 1/128, 1/96, 1/64, 1/48, 1/32, 1/24, 3/64, 1/16, 1/12, 3/32, 1/8, 1/6, 3/16, 1/4, 5/16, 1/3, 3/8, 7/16, 1/2, 1/1
|
|
8
|
+
const oldToNewIndex = [20, 19, 16, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
|
|
9
|
+
const oldMaxIndex = 16;
|
|
10
|
+
const newMaxIndex = 20;
|
|
11
|
+
const oldIndex = box.delayMusical.getValue();
|
|
12
|
+
const newIndex = oldToNewIndex[Math.round(clamp(oldIndex, 0, oldMaxIndex))];
|
|
13
|
+
console.debug(`Migrate 'DelayDeviceBox' delay index from ${oldIndex} to ${newIndex}`);
|
|
14
|
+
boxGraph.beginTransaction();
|
|
15
|
+
box.delayMusical.setValue(newIndex);
|
|
16
|
+
box.delayMillis.setValue(0);
|
|
17
|
+
box.preSyncTimeLeft.setValue(0);
|
|
18
|
+
box.preMillisTimeLeft.setValue(0);
|
|
19
|
+
box.preSyncTimeRight.setValue(0);
|
|
20
|
+
box.preMillisTimeRight.setValue(0);
|
|
21
|
+
box.version.setValue(1);
|
|
22
|
+
box.delayMusical.pointerHub.incoming().forEach(pointer => {
|
|
23
|
+
const eventBox = pointer.box.accept({
|
|
24
|
+
visitValueEventBox: (event) => event
|
|
25
|
+
});
|
|
26
|
+
if (isDefined(eventBox)) {
|
|
27
|
+
const oldNormalized = eventBox.value.getValue();
|
|
28
|
+
const oldEventIndex = Math.round(oldNormalized * oldMaxIndex);
|
|
29
|
+
const newEventIndex = oldToNewIndex[clamp(oldEventIndex, 0, oldMaxIndex)];
|
|
30
|
+
const newNormalized = newEventIndex / newMaxIndex;
|
|
31
|
+
console.debug(` Migrate automation: ${oldNormalized.toFixed(4)} (idx ${oldEventIndex}) -> ${newNormalized.toFixed(4)} (idx ${newEventIndex})`);
|
|
32
|
+
eventBox.value.setValue(newNormalized);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
boxGraph.endTransaction();
|
|
36
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { BoxGraph, Field } from "@opendaw/lib-box";
|
|
2
|
+
import { BoxIO, MIDIOutputDeviceBox } from "@opendaw/studio-boxes";
|
|
3
|
+
export declare const migrateMIDIOutputDeviceBox: (boxGraph: BoxGraph<BoxIO.TypeMap>, deviceBox: MIDIOutputDeviceBox, outputMidiDevices: Field) => void;
|
|
4
|
+
//# sourceMappingURL=MigrateMIDIOutputDeviceBox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigrateMIDIOutputDeviceBox.d.ts","sourceRoot":"","sources":["../../../src/project/migration/MigrateMIDIOutputDeviceBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,kBAAkB,CAAA;AAEhD,OAAO,EAAC,KAAK,EAAiB,mBAAmB,EAAC,MAAM,uBAAuB,CAAA;AAE/E,eAAO,MAAM,0BAA0B,GAAI,UAAU,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,WAAW,mBAAmB,EAAE,mBAAmB,KAAK,KAAG,IAmBxI,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { UUID } from "@opendaw/lib-std";
|
|
2
|
+
import { MIDIOutputBox } from "@opendaw/studio-boxes";
|
|
3
|
+
export const migrateMIDIOutputDeviceBox = (boxGraph, deviceBox, outputMidiDevices) => {
|
|
4
|
+
const id = deviceBox.deprecatedDevice.id.getValue();
|
|
5
|
+
const label = deviceBox.deprecatedDevice.label.getValue();
|
|
6
|
+
const delay = deviceBox.deprecatedDelay.getValue();
|
|
7
|
+
if (id !== "") {
|
|
8
|
+
console.debug("Migrate 'MIDIOutputDeviceBox' to MIDIOutputBox");
|
|
9
|
+
boxGraph.beginTransaction();
|
|
10
|
+
deviceBox.device.refer(MIDIOutputBox.create(boxGraph, UUID.generate(), box => {
|
|
11
|
+
box.id.setValue(id);
|
|
12
|
+
box.label.setValue(label);
|
|
13
|
+
box.delayInMs.setValue(delay);
|
|
14
|
+
box.root.refer(outputMidiDevices);
|
|
15
|
+
}).device);
|
|
16
|
+
deviceBox.deprecatedDevice.id.setValue("");
|
|
17
|
+
deviceBox.deprecatedDevice.label.setValue("");
|
|
18
|
+
boxGraph.endTransaction();
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { BoxGraph } from "@opendaw/lib-box";
|
|
2
|
+
import { BoxIO, RevampDeviceBox } from "@opendaw/studio-boxes";
|
|
3
|
+
export declare const migrateRevampDeviceBox: (boxGraph: BoxGraph<BoxIO.TypeMap>, box: RevampDeviceBox) => void;
|
|
4
|
+
//# sourceMappingURL=MigrateRevampDeviceBox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigrateRevampDeviceBox.d.ts","sourceRoot":"","sources":["../../../src/project/migration/MigrateRevampDeviceBox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAC,KAAK,EAAE,eAAe,EAAC,MAAM,uBAAuB,CAAA;AAE5D,eAAO,MAAM,sBAAsB,GAAI,UAAU,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,eAAe,KAAG,IAKhG,CAAA"}
|