@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.
Files changed (108) hide show
  1. package/dist/AudioDevices.d.ts +2 -0
  2. package/dist/AudioDevices.d.ts.map +1 -1
  3. package/dist/AudioDevices.js +3 -0
  4. package/dist/AudioOfflineRenderer.d.ts +2 -0
  5. package/dist/AudioOfflineRenderer.d.ts.map +1 -1
  6. package/dist/AudioOfflineRenderer.js +2 -1
  7. package/dist/Engine.d.ts +2 -1
  8. package/dist/Engine.d.ts.map +1 -1
  9. package/dist/EngineFacade.d.ts +2 -1
  10. package/dist/EngineFacade.d.ts.map +1 -1
  11. package/dist/EngineFacade.js +3 -0
  12. package/dist/EngineWorklet.d.ts +2 -1
  13. package/dist/EngineWorklet.d.ts.map +1 -1
  14. package/dist/EngineWorklet.js +8 -2
  15. package/dist/OfflineEngineRenderer.d.ts +16 -5
  16. package/dist/OfflineEngineRenderer.d.ts.map +1 -1
  17. package/dist/OfflineEngineRenderer.js +85 -38
  18. package/dist/OpenDAWHeaders.d.ts.map +1 -1
  19. package/dist/OpenDAWHeaders.js +1 -2
  20. package/dist/RecordingWorklet.d.ts.map +1 -1
  21. package/dist/RecordingWorklet.js +0 -1
  22. package/dist/StudioPreferences.d.ts +22 -12
  23. package/dist/StudioPreferences.d.ts.map +1 -1
  24. package/dist/StudioSettings.d.ts +22 -12
  25. package/dist/StudioSettings.d.ts.map +1 -1
  26. package/dist/StudioSettings.js +41 -12
  27. package/dist/WavFile.d.ts.map +1 -1
  28. package/dist/WavFile.js +33 -9
  29. package/dist/capture/CaptureAudio.js +4 -4
  30. package/dist/capture/RecordAudio.d.ts.map +1 -1
  31. package/dist/capture/RecordAudio.js +49 -12
  32. package/dist/capture/RecordMidi.d.ts.map +1 -1
  33. package/dist/capture/RecordMidi.js +44 -8
  34. package/dist/capture/Recording.d.ts +2 -0
  35. package/dist/capture/Recording.d.ts.map +1 -1
  36. package/dist/capture/Recording.js +6 -2
  37. package/dist/midi/MIDIReceiver.d.ts +2 -2
  38. package/dist/midi/MIDIReceiver.d.ts.map +1 -1
  39. package/dist/midi/MIDIReceiver.js +2 -7
  40. package/dist/midi/index.d.ts +1 -0
  41. package/dist/midi/index.d.ts.map +1 -1
  42. package/dist/midi/index.js +1 -0
  43. package/dist/offline-engine.js +1 -1
  44. package/dist/offline-engine.js.map +3 -3
  45. package/dist/processors.js +15 -15
  46. package/dist/processors.js.map +4 -4
  47. package/dist/project/Project.d.ts +2 -1
  48. package/dist/project/Project.d.ts.map +1 -1
  49. package/dist/project/Project.js +18 -3
  50. package/dist/project/ProjectMigration.d.ts.map +1 -1
  51. package/dist/project/ProjectMigration.js +18 -251
  52. package/dist/project/migration/MigrateAudioClipBox.d.ts +4 -0
  53. package/dist/project/migration/MigrateAudioClipBox.d.ts.map +1 -0
  54. package/dist/project/migration/MigrateAudioClipBox.js +32 -0
  55. package/dist/project/migration/MigrateAudioFileBox.d.ts +5 -0
  56. package/dist/project/migration/MigrateAudioFileBox.d.ts.map +1 -0
  57. package/dist/project/migration/MigrateAudioFileBox.js +13 -0
  58. package/dist/project/migration/MigrateAudioRegionBox.d.ts +4 -0
  59. package/dist/project/migration/MigrateAudioRegionBox.d.ts.map +1 -0
  60. package/dist/project/migration/MigrateAudioRegionBox.js +54 -0
  61. package/dist/project/migration/MigrateAudioUnitBox.d.ts +4 -0
  62. package/dist/project/migration/MigrateAudioUnitBox.d.ts.map +1 -0
  63. package/dist/project/migration/MigrateAudioUnitBox.js +19 -0
  64. package/dist/project/migration/MigrateDelayDeviceBox.d.ts +4 -0
  65. package/dist/project/migration/MigrateDelayDeviceBox.d.ts.map +1 -0
  66. package/dist/project/migration/MigrateDelayDeviceBox.js +36 -0
  67. package/dist/project/migration/MigrateMIDIOutputDeviceBox.d.ts +4 -0
  68. package/dist/project/migration/MigrateMIDIOutputDeviceBox.d.ts.map +1 -0
  69. package/dist/project/migration/MigrateMIDIOutputDeviceBox.js +20 -0
  70. package/dist/project/migration/MigrateRevampDeviceBox.d.ts +4 -0
  71. package/dist/project/migration/MigrateRevampDeviceBox.d.ts.map +1 -0
  72. package/dist/project/migration/MigrateRevampDeviceBox.js +7 -0
  73. package/dist/project/migration/MigrateTimelineBox.d.ts +4 -0
  74. package/dist/project/migration/MigrateTimelineBox.d.ts.map +1 -0
  75. package/dist/project/migration/MigrateTimelineBox.js +10 -0
  76. package/dist/project/migration/MigrateValueEventBox.d.ts +4 -0
  77. package/dist/project/migration/MigrateValueEventBox.d.ts.map +1 -0
  78. package/dist/project/migration/MigrateValueEventBox.js +32 -0
  79. package/dist/project/migration/MigrateValueEventCollection.d.ts +4 -0
  80. package/dist/project/migration/MigrateValueEventCollection.d.ts.map +1 -0
  81. package/dist/project/migration/MigrateValueEventCollection.js +59 -0
  82. package/dist/project/migration/MigrateValueEventCollection.test.d.ts +2 -0
  83. package/dist/project/migration/MigrateValueEventCollection.test.d.ts.map +1 -0
  84. package/dist/project/migration/MigrateValueEventCollection.test.js +199 -0
  85. package/dist/project/migration/MigrateVaporisateurDeviceBox.d.ts +4 -0
  86. package/dist/project/migration/MigrateVaporisateurDeviceBox.d.ts.map +1 -0
  87. package/dist/project/migration/MigrateVaporisateurDeviceBox.js +28 -0
  88. package/dist/project/migration/MigrateZeitgeistDeviceBox.d.ts +4 -0
  89. package/dist/project/migration/MigrateZeitgeistDeviceBox.d.ts.map +1 -0
  90. package/dist/project/migration/MigrateZeitgeistDeviceBox.js +8 -0
  91. package/dist/project/migration/index.d.ts +13 -0
  92. package/dist/project/migration/index.d.ts.map +1 -0
  93. package/dist/project/migration/index.js +12 -0
  94. package/dist/samples/OpenSampleAPI.d.ts.map +1 -1
  95. package/dist/samples/OpenSampleAPI.js +3 -0
  96. package/dist/ui/generic/ClipboardManager.js +1 -1
  97. package/dist/ui/generic/ContextMenu.d.ts +1 -1
  98. package/dist/ui/generic/ContextMenu.js +1 -1
  99. package/dist/ui/generic/{menu-item.d.ts → MenuItems.d.ts} +1 -1
  100. package/dist/ui/generic/{menu-item.d.ts.map → MenuItems.d.ts.map} +1 -1
  101. package/dist/ui/index.d.ts +1 -1
  102. package/dist/ui/index.js +1 -1
  103. package/dist/workers-main.js +1 -1
  104. package/dist/workers-main.js.map +3 -3
  105. package/dist/ysync/YMapper.d.ts.map +1 -1
  106. package/dist/ysync/YMapper.js +7 -3
  107. package/package.json +15 -15
  108. /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":"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"}
1
+ {"version":3,"file":"Project.d.ts","sourceRoot":"","sources":["../../src/project/Project.ts"],"names":[],"mappings":"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"}
@@ -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
- setTimeout(() => this.startRecording(true), 100);
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":"AAuBA,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAA;AAIxD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AASvC,qBAAa,gBAAgB;WACZ,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,EAAC,QAAQ,EAAE,cAAc,EAAC,EAAE,eAAe;CA8RpF"}
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 { AudioFileBox, AudioPitchStretchBox, CaptureAudioBox, CaptureMidiBox, GrooveShuffleBox, MIDIOutputBox, ValueEventCollectionBox, ValueEventCurveBox } from "@opendaw/studio-boxes";
2
- import { asDefined, asInstanceOf, clamp, Float, isDefined, UUID } from "@opendaw/lib-std";
3
- import { AudioPlayback, AudioUnitType } 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) => {
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: async (box) => {
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
- const { duration, loopOffset, loopDuration, playback } = box;
70
- if (isIntEncodedAsFloat(duration.getValue())
71
- || isIntEncodedAsFloat(loopOffset.getValue())
72
- || isIntEncodedAsFloat(loopDuration.getValue())) {
73
- console.debug("Migrate 'AudioRegionBox' to float");
74
- boxGraph.beginTransaction();
75
- duration.setValue(Float.floatToIntBits(duration.getValue()));
76
- loopOffset.setValue(Float.floatToIntBits(loopOffset.getValue()));
77
- loopDuration.setValue(Float.floatToIntBits(loopDuration.getValue()));
78
- boxGraph.endTransaction();
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,4 @@
1
+ import { BoxGraph } from "@opendaw/lib-box";
2
+ import { AudioClipBox, BoxIO } from "@opendaw/studio-boxes";
3
+ export declare const migrateAudioClipBox: (boxGraph: BoxGraph<BoxIO.TypeMap>, box: AudioClipBox) => void;
4
+ //# sourceMappingURL=MigrateAudioClipBox.d.ts.map
@@ -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,4 @@
1
+ import { BoxGraph } from "@opendaw/lib-box";
2
+ import { AudioUnitBox, BoxIO } from "@opendaw/studio-boxes";
3
+ export declare const migrateAudioUnitBox: (boxGraph: BoxGraph<BoxIO.TypeMap>, box: AudioUnitBox) => void;
4
+ //# sourceMappingURL=MigrateAudioUnitBox.d.ts.map
@@ -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"}