@opendaw/studio-adapters 0.0.47 → 0.0.49
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/AutomatableParameterFieldAdapter.js +86 -73
- package/dist/BoxAdapterCollection.js +30 -17
- package/dist/BoxAdapters.d.ts.map +1 -1
- package/dist/BoxAdapters.js +87 -72
- package/dist/BoxAdaptersContext.d.ts +2 -2
- package/dist/BoxAdaptersContext.d.ts.map +1 -1
- package/dist/EngineProcessorAttachment.d.ts +2 -1
- package/dist/EngineProcessorAttachment.d.ts.map +1 -1
- package/dist/FieldAdapter.js +45 -32
- package/dist/IndexedBoxAdapterCollection.js +45 -32
- package/dist/NoteBroadcaster.js +25 -12
- package/dist/NoteStreamReceiver.js +29 -16
- package/dist/ParameterAdapterSet.js +24 -11
- package/dist/ParameterFieldAdapters.js +19 -6
- package/dist/Parsing.d.ts +5 -0
- package/dist/Parsing.d.ts.map +1 -0
- package/dist/Parsing.js +10 -0
- package/dist/PianoModeAdapter.js +32 -19
- package/dist/RootBoxAdapter.d.ts +2 -1
- package/dist/RootBoxAdapter.d.ts.map +1 -1
- package/dist/RootBoxAdapter.js +41 -23
- package/dist/Validator.d.ts +10 -0
- package/dist/Validator.d.ts.map +1 -0
- package/dist/Validator.js +35 -0
- package/dist/audio/AudioFileBoxAdapter.js +23 -10
- package/dist/audio-unit/AudioBusBoxAdapter.d.ts +1 -1
- package/dist/audio-unit/AudioBusBoxAdapter.d.ts.map +1 -1
- package/dist/audio-unit/AudioBusBoxAdapter.js +31 -18
- package/dist/audio-unit/AudioUnitBoxAdapter.js +74 -63
- package/dist/audio-unit/AudioUnitInput.d.ts +1 -1
- package/dist/audio-unit/AudioUnitInput.d.ts.map +1 -1
- package/dist/audio-unit/AudioUnitInput.js +43 -30
- package/dist/audio-unit/AudioUnitOutput.js +33 -20
- package/dist/audio-unit/AudioUnitTracks.js +39 -26
- package/dist/audio-unit/AuxSendBoxAdapter.js +47 -34
- package/dist/devices/audio-effects/CompressorDeviceBoxAdapter.js +49 -37
- package/dist/devices/audio-effects/CrusherDeviceBoxAdapter.js +41 -29
- package/dist/devices/audio-effects/DelayDeviceBoxAdapter.js +51 -39
- package/dist/devices/audio-effects/FoldDeviceBoxAdapter.js +39 -27
- package/dist/devices/audio-effects/ModularDeviceBoxAdapter.js +33 -20
- package/dist/devices/audio-effects/RevampDeviceBoxAdapter.js +46 -34
- package/dist/devices/audio-effects/ReverbDeviceBoxAdapter.js +45 -33
- package/dist/devices/audio-effects/StereoToolDeviceBoxAdapter.js +43 -31
- package/dist/devices/audio-effects/TidalDeviceBoxAdapter.d.ts +36 -0
- package/dist/devices/audio-effects/TidalDeviceBoxAdapter.d.ts.map +1 -0
- package/dist/devices/audio-effects/TidalDeviceBoxAdapter.js +63 -0
- package/dist/devices/audio-effects/UnknownAudioEffectDeviceBoxAdapter.js +30 -17
- package/dist/devices/instruments/MIDIOutputDeviceBoxAdapter.d.ts +3 -2
- package/dist/devices/instruments/MIDIOutputDeviceBoxAdapter.d.ts.map +1 -1
- package/dist/devices/instruments/MIDIOutputDeviceBoxAdapter.js +45 -26
- package/dist/devices/instruments/NanoDeviceBoxAdapter.js +38 -26
- package/dist/devices/instruments/Playfield/PlayfieldSampleBoxAdapter.js +101 -89
- package/dist/devices/instruments/PlayfieldDeviceBoxAdapter.d.ts +0 -1
- package/dist/devices/instruments/PlayfieldDeviceBoxAdapter.d.ts.map +1 -1
- package/dist/devices/instruments/PlayfieldDeviceBoxAdapter.js +36 -24
- package/dist/devices/instruments/SoundfontDeviceBoxAdapter.js +84 -72
- package/dist/devices/instruments/TapeDeviceBoxAdapter.js +40 -28
- package/dist/devices/instruments/VaporisateurDeviceBoxAdapter.d.ts +26 -4
- package/dist/devices/instruments/VaporisateurDeviceBoxAdapter.d.ts.map +1 -1
- package/dist/devices/instruments/VaporisateurDeviceBoxAdapter.js +70 -33
- package/dist/devices/instruments/VaporisateurSettings.d.ts +17 -0
- package/dist/devices/instruments/VaporisateurSettings.d.ts.map +1 -0
- package/dist/devices/instruments/VaporisateurSettings.js +24 -0
- package/dist/devices/midi-effects/ArpeggioDeviceBoxAdapter.js +51 -39
- package/dist/devices/midi-effects/PitchDeviceBoxAdapter.js +40 -28
- package/dist/devices/midi-effects/UnknownMidiEffectDeviceBoxAdapter.js +30 -17
- package/dist/devices/midi-effects/VelocityDeviceBoxAdapter.js +47 -35
- package/dist/devices/midi-effects/ZeitgeistDeviceBoxAdapter.js +32 -19
- package/dist/editing/UserEditing.js +33 -20
- package/dist/editing/UserEditingManager.js +28 -15
- package/dist/factories/AudioBusFactory.d.ts +7 -0
- package/dist/factories/AudioBusFactory.d.ts.map +1 -0
- package/dist/factories/AudioBusFactory.js +29 -0
- package/dist/factories/AudioUnitFactory.d.ts +13 -0
- package/dist/factories/AudioUnitFactory.d.ts.map +1 -0
- package/dist/factories/AudioUnitFactory.js +44 -0
- package/dist/factories/AudioUnitOrdering.d.ts +3 -0
- package/dist/factories/AudioUnitOrdering.d.ts.map +1 -0
- package/dist/factories/AudioUnitOrdering.js +7 -0
- package/dist/factories/ColorCodes.d.ts +7 -0
- package/dist/factories/ColorCodes.d.ts.map +1 -0
- package/dist/factories/ColorCodes.js +32 -0
- package/dist/factories/Colors.d.ts +15 -0
- package/dist/factories/Colors.d.ts.map +1 -0
- package/dist/factories/Colors.js +23 -0
- package/dist/factories/InstrumentBox.d.ts +3 -0
- package/dist/factories/InstrumentBox.d.ts.map +1 -0
- package/dist/factories/InstrumentBox.js +1 -0
- package/dist/factories/InstrumentFactories.d.ts +34 -0
- package/dist/factories/InstrumentFactories.d.ts.map +1 -0
- package/dist/factories/InstrumentFactories.js +137 -0
- package/dist/factories/InstrumentFactory.d.ts +13 -0
- package/dist/factories/InstrumentFactory.d.ts.map +1 -0
- package/dist/factories/InstrumentFactory.js +1 -0
- package/dist/factories/InstrumentOptions.d.ts +9 -0
- package/dist/factories/InstrumentOptions.d.ts.map +1 -0
- package/dist/factories/InstrumentOptions.js +1 -0
- package/dist/factories/InstrumentProduct.d.ts +8 -0
- package/dist/factories/InstrumentProduct.d.ts.map +1 -0
- package/dist/factories/InstrumentProduct.js +1 -0
- package/dist/grooves/GrooveShuffleBoxAdapter.js +47 -35
- package/dist/index.d.ts +20 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -3
- package/dist/modular/abstract.js +37 -24
- package/dist/modular/connection.js +20 -7
- package/dist/modular/connector.js +29 -16
- package/dist/modular/modular.js +49 -36
- package/dist/modular/modules/audio-input.js +17 -4
- package/dist/modular/modules/audio-output.js +17 -4
- package/dist/modular/modules/delay.js +24 -11
- package/dist/modular/modules/gain.js +24 -11
- package/dist/modular/modules/multiplier.js +21 -8
- package/dist/modular/user-interface.js +25 -12
- package/dist/preset/PresetDecoder.d.ts +11 -0
- package/dist/preset/PresetDecoder.d.ts.map +1 -0
- package/dist/preset/PresetDecoder.js +154 -0
- package/dist/preset/PresetEncoder.d.ts +5 -0
- package/dist/preset/PresetEncoder.d.ts.map +1 -0
- package/dist/preset/PresetEncoder.js +19 -0
- package/dist/preset/PresetHeader.d.ts +5 -0
- package/dist/preset/PresetHeader.d.ts.map +1 -0
- package/dist/preset/PresetHeader.js +5 -0
- package/dist/project/ProjectQueries.d.ts +5 -0
- package/dist/project/ProjectQueries.d.ts.map +1 -0
- package/dist/project/ProjectQueries.js +10 -0
- package/dist/project/ProjectSkeleton.d.ts +10 -1
- package/dist/project/ProjectSkeleton.d.ts.map +1 -1
- package/dist/project/ProjectSkeleton.js +100 -1
- package/dist/project/ProjectUtils.d.ts +13 -0
- package/dist/project/ProjectUtils.d.ts.map +1 -0
- package/dist/project/ProjectUtils.js +142 -0
- package/dist/protocols.d.ts.map +1 -1
- package/dist/selection/FilteredSelection.js +47 -34
- package/dist/selection/VertexSelection.js +66 -55
- package/dist/soundfont/SoundfontFileBoxAdapter.js +21 -8
- package/dist/timeline/MarkerBoxAdapter.js +33 -20
- package/dist/timeline/MarkerTrackAdapter.js +34 -22
- package/dist/timeline/TimelineBoxAdapter.js +24 -11
- package/dist/timeline/TrackBoxAdapter.d.ts.map +1 -1
- package/dist/timeline/TrackBoxAdapter.js +97 -85
- package/dist/timeline/TrackClips.js +27 -14
- package/dist/timeline/TrackRegions.js +40 -27
- package/dist/timeline/TrackType.d.ts +1 -1
- package/dist/timeline/TrackType.d.ts.map +1 -1
- package/dist/timeline/TrackType.js +1 -1
- package/dist/timeline/clip/AudioClipBoxAdapter.js +66 -53
- package/dist/timeline/clip/NoteClipBoxAdapter.js +66 -53
- package/dist/timeline/clip/ValueClipBoxAdapter.js +67 -54
- package/dist/timeline/collection/NoteEventCollectionBoxAdapter.js +85 -73
- package/dist/timeline/collection/ValueEventCollectionBoxAdapter.js +53 -40
- package/dist/timeline/event/NoteEventBoxAdapter.js +43 -30
- package/dist/timeline/event/ValueEventBoxAdapter.js +67 -54
- package/dist/timeline/region/AudioRegionBoxAdapter.d.ts +17 -9
- package/dist/timeline/region/AudioRegionBoxAdapter.d.ts.map +1 -1
- package/dist/timeline/region/AudioRegionBoxAdapter.js +149 -83
- package/dist/timeline/region/MutableRegion.d.ts +8 -0
- package/dist/timeline/region/MutableRegion.d.ts.map +1 -0
- package/dist/timeline/region/MutableRegion.js +1 -0
- package/dist/timeline/region/NoteRegionBoxAdapter.d.ts +6 -1
- package/dist/timeline/region/NoteRegionBoxAdapter.d.ts.map +1 -1
- package/dist/timeline/region/NoteRegionBoxAdapter.js +78 -61
- package/dist/timeline/region/ValueRegionBoxAdapter.d.ts +6 -1
- package/dist/timeline/region/ValueRegionBoxAdapter.d.ts.map +1 -1
- package/dist/timeline/region/ValueRegionBoxAdapter.js +79 -62
- package/package.json +8 -8
- package/dist/IconSymbol.d.ts +0 -126
- package/dist/IconSymbol.d.ts.map +0 -1
- package/dist/IconSymbol.js +0 -126
- package/dist/UpdateClockRate.d.ts +0 -2
- package/dist/UpdateClockRate.d.ts.map +0 -1
- package/dist/UpdateClockRate.js +0 -2
- package/dist/project/ProjectDecoder.d.ts +0 -10
- package/dist/project/ProjectDecoder.d.ts.map +0 -1
- package/dist/project/ProjectDecoder.js +0 -36
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { asDefined, asInstanceOf, Attempts, ByteArrayInput, isDefined, isInstanceOf, Option, RuntimeNotifier, UUID } from "@opendaw/lib-std";
|
|
2
|
+
import { BoxGraph, PointerField } from "@opendaw/lib-box";
|
|
3
|
+
import { AudioUnitType } from "@opendaw/studio-enums";
|
|
4
|
+
import { AudioFileBox, AudioUnitBox, BoxIO, CaptureAudioBox, CaptureMidiBox, SoundfontFileBox, TrackBox } from "@opendaw/studio-boxes";
|
|
5
|
+
import { ProjectSkeleton } from "../project/ProjectSkeleton";
|
|
6
|
+
import { ProjectUtils } from "../project/ProjectUtils";
|
|
7
|
+
import { TrackType } from "../timeline/TrackType";
|
|
8
|
+
import { PresetHeader } from "./PresetHeader";
|
|
9
|
+
export var PresetDecoder;
|
|
10
|
+
(function (PresetDecoder) {
|
|
11
|
+
PresetDecoder.decode = (bytes, target) => {
|
|
12
|
+
const header = new ByteArrayInput(bytes.slice(0, 8));
|
|
13
|
+
if (header.readInt() !== PresetHeader.MAGIC_HEADER_OPEN) {
|
|
14
|
+
RuntimeNotifier.info({
|
|
15
|
+
headline: "Could Not Import Preset",
|
|
16
|
+
message: "Invalid preset file"
|
|
17
|
+
}).then();
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (header.readInt() !== PresetHeader.FORMAT_VERSION) {
|
|
21
|
+
RuntimeNotifier.info({
|
|
22
|
+
headline: "Could Not Import Preset",
|
|
23
|
+
message: "Invalid preset version"
|
|
24
|
+
}).then();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const sourceBoxGraph = new BoxGraph(Option.wrap(BoxIO.create));
|
|
28
|
+
try {
|
|
29
|
+
sourceBoxGraph.fromArrayBuffer(bytes.slice(8));
|
|
30
|
+
}
|
|
31
|
+
catch (reason) {
|
|
32
|
+
RuntimeNotifier.info({
|
|
33
|
+
headline: "Could Not Import Preset",
|
|
34
|
+
message: String(reason)
|
|
35
|
+
}).then();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const sourceAudioUnitBoxes = sourceBoxGraph.boxes()
|
|
39
|
+
.filter(box => isInstanceOf(box, AudioUnitBox))
|
|
40
|
+
.filter(box => box.type.getValue() !== AudioUnitType.Output);
|
|
41
|
+
ProjectUtils.extractAudioUnits(sourceAudioUnitBoxes, target, { excludeTimeline: true })
|
|
42
|
+
.filter(box => box.type.getValue() !== AudioUnitType.Output)
|
|
43
|
+
.forEach((audioUnitBox) => {
|
|
44
|
+
const inputBox = audioUnitBox.input.pointerHub.incoming().at(0)?.box;
|
|
45
|
+
if (isDefined(inputBox)) {
|
|
46
|
+
audioUnitBox.capture.targetVertex.ifSome(({ box: captureBox }) => {
|
|
47
|
+
if (captureBox instanceof CaptureMidiBox) {
|
|
48
|
+
TrackBox.create(target.boxGraph, UUID.generate(), box => {
|
|
49
|
+
box.index.setValue(0);
|
|
50
|
+
box.type.setValue(TrackType.Notes);
|
|
51
|
+
box.target.refer(audioUnitBox);
|
|
52
|
+
box.tracks.refer(audioUnitBox.tracks);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else if (captureBox instanceof CaptureAudioBox) {
|
|
56
|
+
TrackBox.create(target.boxGraph, UUID.generate(), box => {
|
|
57
|
+
box.index.setValue(0);
|
|
58
|
+
box.type.setValue(TrackType.Audio);
|
|
59
|
+
box.target.refer(audioUnitBox);
|
|
60
|
+
box.tracks.refer(audioUnitBox.tracks);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
PresetDecoder.replaceAudioUnit = (arrayBuffer, targetAudioUnitBox, options) => {
|
|
68
|
+
console.debug("ReplaceAudioUnit with preset...");
|
|
69
|
+
const skeleton = ProjectSkeleton.empty({
|
|
70
|
+
createDefaultUser: false,
|
|
71
|
+
createOutputCompressor: false
|
|
72
|
+
});
|
|
73
|
+
const sourceBoxGraph = skeleton.boxGraph;
|
|
74
|
+
const targetBoxGraph = targetAudioUnitBox.graph;
|
|
75
|
+
sourceBoxGraph.beginTransaction();
|
|
76
|
+
PresetDecoder.decode(arrayBuffer, skeleton);
|
|
77
|
+
sourceBoxGraph.endTransaction();
|
|
78
|
+
const sourceAudioUnitBox = asDefined(skeleton.mandatoryBoxes.rootBox.audioUnits.pointerHub.incoming()
|
|
79
|
+
.map(({ box }) => asInstanceOf(box, AudioUnitBox))
|
|
80
|
+
.find((box) => box.type.getValue() !== AudioUnitType.Output), "Source has no audioUnitBox");
|
|
81
|
+
const sourceCaptureBox = sourceAudioUnitBox.capture.targetVertex.mapOr(({ box }) => box.name, "");
|
|
82
|
+
const targetCaptureBox = targetAudioUnitBox.capture.targetVertex.mapOr(({ box }) => box.name, "");
|
|
83
|
+
if (sourceCaptureBox !== targetCaptureBox) {
|
|
84
|
+
return Attempts.err("Cannot replace incompatible instruments");
|
|
85
|
+
}
|
|
86
|
+
const replaceMIDIEffects = options?.keepMIDIEffects !== true;
|
|
87
|
+
const replaceAudioEffects = options?.keepAudioEffects !== true;
|
|
88
|
+
console.debug("replaceMIDIEffects", replaceMIDIEffects);
|
|
89
|
+
console.debug("replaceAudioEffects", replaceAudioEffects);
|
|
90
|
+
asDefined(targetAudioUnitBox.input.pointerHub.incoming().at(0)?.box, "Target has no input").delete();
|
|
91
|
+
if (replaceMIDIEffects) {
|
|
92
|
+
targetAudioUnitBox.midiEffects.pointerHub.incoming().forEach(({ box }) => box.delete());
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
sourceBoxGraph.beginTransaction();
|
|
96
|
+
sourceAudioUnitBox.midiEffects.pointerHub.incoming().forEach(({ box }) => box.delete());
|
|
97
|
+
sourceBoxGraph.endTransaction();
|
|
98
|
+
}
|
|
99
|
+
if (replaceAudioEffects) {
|
|
100
|
+
targetAudioUnitBox.audioEffects.pointerHub.incoming().forEach(({ box }) => box.delete());
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
sourceBoxGraph.beginTransaction();
|
|
104
|
+
sourceAudioUnitBox.audioEffects.pointerHub.incoming().forEach(({ box }) => box.delete());
|
|
105
|
+
sourceBoxGraph.endTransaction();
|
|
106
|
+
}
|
|
107
|
+
// We do not take track or capture boxes into account
|
|
108
|
+
const excludeBox = (box) => box.accept({
|
|
109
|
+
visitTrackBox: (_box) => true,
|
|
110
|
+
visitCaptureMidiBox: (_box) => true,
|
|
111
|
+
visitCaptureAudioBox: (_box) => true
|
|
112
|
+
}) === true;
|
|
113
|
+
const uuidMap = UUID.newSet(({ source }) => source);
|
|
114
|
+
const dependencies = Array.from(sourceBoxGraph.dependenciesOf(sourceAudioUnitBox, {
|
|
115
|
+
excludeBox,
|
|
116
|
+
alwaysFollowMandatory: false
|
|
117
|
+
}).boxes);
|
|
118
|
+
uuidMap.addMany([
|
|
119
|
+
{
|
|
120
|
+
source: sourceAudioUnitBox.address.uuid,
|
|
121
|
+
target: targetAudioUnitBox.address.uuid
|
|
122
|
+
},
|
|
123
|
+
...dependencies
|
|
124
|
+
.map(({ address: { uuid }, name }) => ({
|
|
125
|
+
source: uuid,
|
|
126
|
+
target: name === AudioFileBox.ClassName || name === SoundfontFileBox.ClassName
|
|
127
|
+
? uuid
|
|
128
|
+
: UUID.generate()
|
|
129
|
+
}))
|
|
130
|
+
]);
|
|
131
|
+
PointerField.decodeWith({
|
|
132
|
+
map: (_pointer, newAddress) => newAddress.map(address => uuidMap.opt(address.uuid).match({
|
|
133
|
+
none: () => address,
|
|
134
|
+
some: ({ target }) => address.moveTo(target)
|
|
135
|
+
}))
|
|
136
|
+
}, () => {
|
|
137
|
+
dependencies
|
|
138
|
+
.forEach((source) => {
|
|
139
|
+
const input = new ByteArrayInput(source.toArrayBuffer());
|
|
140
|
+
const key = source.name;
|
|
141
|
+
const uuid = uuidMap.get(source.address.uuid).target;
|
|
142
|
+
if (source instanceof AudioFileBox || source instanceof SoundfontFileBox) {
|
|
143
|
+
// Those boxes keep their UUID. So if they are already in the graph, we can just read them.
|
|
144
|
+
if (targetBoxGraph.findBox(source.address.uuid).nonEmpty()) {
|
|
145
|
+
source.read(input);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
targetBoxGraph.createBox(key, uuid, box => box.read(input));
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
return Attempts.Ok;
|
|
153
|
+
};
|
|
154
|
+
})(PresetDecoder || (PresetDecoder = {}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PresetEncoder.d.ts","sourceRoot":"","sources":["../../src/preset/PresetEncoder.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAA;AAKlD,yBAAiB,aAAa,CAAC;IACpB,MAAM,MAAM,GAAI,cAAc,YAAY,KAAG,eAWnD,CAAA;CACJ"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Arrays, ByteArrayOutput } from "@opendaw/lib-std";
|
|
2
|
+
import { ProjectSkeleton } from "../project/ProjectSkeleton";
|
|
3
|
+
import { ProjectUtils } from "../project/ProjectUtils";
|
|
4
|
+
import { PresetHeader } from "./PresetHeader";
|
|
5
|
+
export var PresetEncoder;
|
|
6
|
+
(function (PresetEncoder) {
|
|
7
|
+
PresetEncoder.encode = (audioUnitBox) => {
|
|
8
|
+
const header = ByteArrayOutput.create();
|
|
9
|
+
header.writeInt(PresetHeader.MAGIC_HEADER_OPEN);
|
|
10
|
+
header.writeInt(PresetHeader.FORMAT_VERSION);
|
|
11
|
+
const preset = ProjectSkeleton.empty({ createOutputCompressor: false, createDefaultUser: false });
|
|
12
|
+
preset.boxGraph.beginTransaction();
|
|
13
|
+
ProjectUtils.extractAudioUnits([audioUnitBox], preset, { excludeTimeline: true });
|
|
14
|
+
preset.boxGraph.endTransaction();
|
|
15
|
+
console.debug("SAVING...");
|
|
16
|
+
preset.boxGraph.debugBoxes();
|
|
17
|
+
return Arrays.concatArrayBuffers(header.toArrayBuffer(), preset.boxGraph.toArrayBuffer());
|
|
18
|
+
};
|
|
19
|
+
})(PresetEncoder || (PresetEncoder = {}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PresetHeader.d.ts","sourceRoot":"","sources":["../../src/preset/PresetHeader.ts"],"names":[],"mappings":"AAAA,yBAAiB,YAAY,CAAC;IACnB,MAAM,iBAAiB,aAAa,CAAA;IACpC,MAAM,cAAc,IAAI,CAAA;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectQueries.d.ts","sourceRoot":"","sources":["../../src/project/ProjectQueries.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,OAAO,EAAC,MAAM,uBAAuB,CAAA;AAG3D,yBAAiB,cAAc,CAAC;IACrB,MAAM,uBAAuB,GAAI,SAAS,OAAO,aAGtD,CAAA;CACL"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { asDefined, asInstanceOf } from "@opendaw/lib-std";
|
|
2
|
+
import { AudioUnitBox } from "@opendaw/studio-boxes";
|
|
3
|
+
import { StringField } from "@opendaw/lib-box";
|
|
4
|
+
export var ProjectQueries;
|
|
5
|
+
(function (ProjectQueries) {
|
|
6
|
+
ProjectQueries.existingInstrumentNames = (rootBox) => rootBox.audioUnits.pointerHub.incoming().map(({ box }) => {
|
|
7
|
+
const inputBox = asDefined(asInstanceOf(box, AudioUnitBox).input.pointerHub.incoming().at(0)).box;
|
|
8
|
+
return "label" in inputBox && inputBox.label instanceof StringField ? inputBox.label.getValue() : "N/A";
|
|
9
|
+
});
|
|
10
|
+
})(ProjectQueries || (ProjectQueries = {}));
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { BoxGraph } from "@opendaw/lib-box";
|
|
2
2
|
import { BoxIO } from "@opendaw/studio-boxes";
|
|
3
|
-
import { ProjectMandatoryBoxes } from "
|
|
3
|
+
import { ProjectMandatoryBoxes } from "./ProjectMandatoryBoxes";
|
|
4
4
|
export type ProjectSkeleton = {
|
|
5
5
|
boxGraph: BoxGraph<BoxIO.TypeMap>;
|
|
6
6
|
mandatoryBoxes: ProjectMandatoryBoxes;
|
|
7
7
|
};
|
|
8
|
+
export declare namespace ProjectSkeleton {
|
|
9
|
+
const empty: (options: {
|
|
10
|
+
createOutputCompressor: boolean;
|
|
11
|
+
createDefaultUser: boolean;
|
|
12
|
+
}) => ProjectSkeleton;
|
|
13
|
+
const encode: (boxGraph: BoxGraph) => ArrayBufferLike;
|
|
14
|
+
const decode: (arrayBuffer: ArrayBufferLike) => ProjectSkeleton;
|
|
15
|
+
const findMandatoryBoxes: (boxGraph: BoxGraph) => ProjectMandatoryBoxes;
|
|
16
|
+
}
|
|
8
17
|
//# sourceMappingURL=ProjectSkeleton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectSkeleton.d.ts","sourceRoot":"","sources":["../../src/project/ProjectSkeleton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"ProjectSkeleton.d.ts","sourceRoot":"","sources":["../../src/project/ProjectSkeleton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAGH,KAAK,EAOR,MAAM,uBAAuB,CAAA;AAa9B,OAAO,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAA;AAE7D,MAAM,MAAM,eAAe,GAAG;IAC1B,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClC,cAAc,EAAE,qBAAqB,CAAA;CACxC,CAAA;AAED,yBAAiB,eAAe,CAAC;IAItB,MAAM,KAAK,GAAI,SAAS;QAC3B,sBAAsB,EAAE,OAAO,CAAC;QAChC,iBAAiB,EAAE,OAAO,CAAA;KAC7B,KAAG,eAqDH,CAAA;IAEM,MAAM,MAAM,GAAI,UAAU,QAAQ,oBAQxC,CAAA;IAEM,MAAM,MAAM,GAAI,aAAa,eAAe,KAAG,eAYrD,CAAA;IAEM,MAAM,kBAAkB,GAAI,UAAU,QAAQ,KAAG,qBAiBvD,CAAA;CACJ"}
|
|
@@ -1 +1,100 @@
|
|
|
1
|
-
|
|
1
|
+
import { BoxGraph } from "@opendaw/lib-box";
|
|
2
|
+
import { AudioBusBox, AudioUnitBox, BoxIO, CompressorDeviceBox, GrooveShuffleBox, RootBox, TimelineBox, UserInterfaceBox } from "@opendaw/studio-boxes";
|
|
3
|
+
import { asInstanceOf, assert, ByteArrayInput, ByteArrayOutput, isDefined, Option, panic, UUID } from "@opendaw/lib-std";
|
|
4
|
+
import { AudioUnitType, IconSymbol } from "@opendaw/studio-enums";
|
|
5
|
+
export var ProjectSkeleton;
|
|
6
|
+
(function (ProjectSkeleton) {
|
|
7
|
+
const MAGIC_HEADER_OPEN = 0x4F50454E;
|
|
8
|
+
const FORMAT_VERSION = 2;
|
|
9
|
+
ProjectSkeleton.empty = (options) => {
|
|
10
|
+
const boxGraph = new BoxGraph(Option.wrap(BoxIO.create));
|
|
11
|
+
const isoString = new Date().toISOString();
|
|
12
|
+
console.debug(`New Project created on ${isoString}`);
|
|
13
|
+
boxGraph.beginTransaction();
|
|
14
|
+
const grooveShuffleBox = GrooveShuffleBox.create(boxGraph, UUID.generate(), box => {
|
|
15
|
+
box.label.setValue("Groove Shuffle");
|
|
16
|
+
});
|
|
17
|
+
const rootBox = RootBox.create(boxGraph, UUID.generate(), box => {
|
|
18
|
+
box.groove.refer(grooveShuffleBox);
|
|
19
|
+
box.created.setValue(isoString);
|
|
20
|
+
});
|
|
21
|
+
const primaryAudioBus = AudioBusBox.create(boxGraph, UUID.generate(), box => {
|
|
22
|
+
box.collection.refer(rootBox.audioBusses);
|
|
23
|
+
box.label.setValue("Output");
|
|
24
|
+
box.icon.setValue(IconSymbol.toName(IconSymbol.SpeakerHeadphone));
|
|
25
|
+
box.color.setValue(/*Colors.blue*/ "hsl(189, 100%, 65%)"); // TODO
|
|
26
|
+
});
|
|
27
|
+
const primaryAudioOutputUnit = AudioUnitBox.create(boxGraph, UUID.generate(), box => {
|
|
28
|
+
box.type.setValue(AudioUnitType.Output);
|
|
29
|
+
box.collection.refer(rootBox.audioUnits);
|
|
30
|
+
box.output.refer(rootBox.outputDevice);
|
|
31
|
+
box.index.setValue(0);
|
|
32
|
+
});
|
|
33
|
+
if (options.createOutputCompressor) {
|
|
34
|
+
CompressorDeviceBox.create(boxGraph, UUID.generate(), box => {
|
|
35
|
+
box.label.setValue("Compressor");
|
|
36
|
+
box.index.setValue(0);
|
|
37
|
+
box.host.refer(primaryAudioOutputUnit.audioEffects);
|
|
38
|
+
box.threshold.setValue(0);
|
|
39
|
+
box.ratio.setValue(24);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const timelineBox = TimelineBox.create(boxGraph, UUID.generate());
|
|
43
|
+
rootBox.timeline.refer(timelineBox.root);
|
|
44
|
+
primaryAudioBus.output.refer(primaryAudioOutputUnit.input);
|
|
45
|
+
const userInterfaceBoxes = [];
|
|
46
|
+
if (options.createDefaultUser) {
|
|
47
|
+
const userInterfaceBox = UserInterfaceBox.create(boxGraph, UUID.generate());
|
|
48
|
+
userInterfaceBox.root.refer(rootBox.users);
|
|
49
|
+
userInterfaceBoxes.push(userInterfaceBox);
|
|
50
|
+
}
|
|
51
|
+
boxGraph.endTransaction();
|
|
52
|
+
return {
|
|
53
|
+
boxGraph,
|
|
54
|
+
mandatoryBoxes: {
|
|
55
|
+
rootBox,
|
|
56
|
+
primaryAudioBus,
|
|
57
|
+
primaryAudioOutputUnit,
|
|
58
|
+
timelineBox,
|
|
59
|
+
userInterfaceBoxes
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
ProjectSkeleton.encode = (boxGraph) => {
|
|
64
|
+
const output = ByteArrayOutput.create();
|
|
65
|
+
output.writeInt(MAGIC_HEADER_OPEN);
|
|
66
|
+
output.writeInt(FORMAT_VERSION);
|
|
67
|
+
const boxGraphChunk = boxGraph.toArrayBuffer();
|
|
68
|
+
output.writeInt(boxGraphChunk.byteLength);
|
|
69
|
+
output.writeBytes(new Int8Array(boxGraphChunk));
|
|
70
|
+
return output.toArrayBuffer();
|
|
71
|
+
};
|
|
72
|
+
ProjectSkeleton.decode = (arrayBuffer) => {
|
|
73
|
+
const input = new ByteArrayInput(arrayBuffer);
|
|
74
|
+
assert(input.readInt() === MAGIC_HEADER_OPEN, "Corrupt header. Probably not an openDAW project file.");
|
|
75
|
+
assert(input.readInt() === FORMAT_VERSION, "Deprecated Format");
|
|
76
|
+
const boxGraphChunkLength = input.readInt();
|
|
77
|
+
const boxGraphChunk = new Int8Array(boxGraphChunkLength);
|
|
78
|
+
input.readBytes(boxGraphChunk);
|
|
79
|
+
const boxGraph = new BoxGraph(Option.wrap(BoxIO.create));
|
|
80
|
+
boxGraph.fromArrayBuffer(boxGraphChunk.buffer);
|
|
81
|
+
return { boxGraph, mandatoryBoxes: ProjectSkeleton.findMandatoryBoxes(boxGraph) };
|
|
82
|
+
};
|
|
83
|
+
ProjectSkeleton.findMandatoryBoxes = (boxGraph) => {
|
|
84
|
+
const rootBox = boxGraph.boxes().find(box => box.accept({ visitRootBox: () => true }));
|
|
85
|
+
if (isDefined(rootBox)) {
|
|
86
|
+
const primaryAudioOutputUnit = asInstanceOf(rootBox.outputDevice.pointerHub.incoming().at(0)?.box, AudioUnitBox);
|
|
87
|
+
const primaryAudioBus = asInstanceOf(primaryAudioOutputUnit.input.pointerHub.incoming().at(0)?.box, AudioBusBox);
|
|
88
|
+
const timelineBox = asInstanceOf(rootBox.timeline.targetVertex.unwrap("TimelineBox not found").box, TimelineBox);
|
|
89
|
+
const userInterfaceBoxes = rootBox.users.pointerHub.incoming().map(({ box }) => asInstanceOf(box, UserInterfaceBox));
|
|
90
|
+
return {
|
|
91
|
+
rootBox,
|
|
92
|
+
primaryAudioBus,
|
|
93
|
+
primaryAudioOutputUnit,
|
|
94
|
+
timelineBox,
|
|
95
|
+
userInterfaceBoxes
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return panic("Could not find mandatory boxes");
|
|
99
|
+
};
|
|
100
|
+
})(ProjectSkeleton || (ProjectSkeleton = {}));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ppqn } from "@opendaw/lib-dsp";
|
|
2
|
+
import { AudioUnitBox } from "@opendaw/studio-boxes";
|
|
3
|
+
import { ProjectSkeleton } from "./ProjectSkeleton";
|
|
4
|
+
import { AnyRegionBox } from "../unions";
|
|
5
|
+
export declare namespace ProjectUtils {
|
|
6
|
+
const extractAudioUnits: (audioUnitBoxes: ReadonlyArray<AudioUnitBox>, { boxGraph, mandatoryBoxes: { primaryAudioBus, rootBox } }: ProjectSkeleton, options?: {
|
|
7
|
+
includeAux?: boolean;
|
|
8
|
+
includeBus?: boolean;
|
|
9
|
+
excludeTimeline?: boolean;
|
|
10
|
+
}) => ReadonlyArray<AudioUnitBox>;
|
|
11
|
+
const extractRegions: (regionBoxes: ReadonlyArray<AnyRegionBox>, { boxGraph, mandatoryBoxes: { primaryAudioBus, rootBox } }: ProjectSkeleton, insertPosition?: ppqn) => void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=ProjectUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectUtils.d.ts","sourceRoot":"","sources":["../../src/project/ProjectUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAcrC,OAAO,EAEH,YAAY,EAQf,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,YAAY,EAAgB,MAAM,WAAW,CAAA;AAGrD,yBAAiB,YAAY,CAAC;IASnB,MAAM,iBAAiB,GAAI,gBAAgB,aAAa,CAAC,YAAY,CAAC,EAC3C,4DAAwD,eAAe,EACvE,UAAS;QACL,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,eAAe,CAAC,EAAE,OAAO,CAAC;KACxB,KAClC,aAAa,CAAC,YAAY,CAgB/B,CAAA;IAEM,MAAM,cAAc,GAAI,aAAa,aAAa,CAAC,YAAY,CAAC,EACxC,4DAAwD,eAAe,EACvE,iBAAgB,IAAU,KAAG,IA8C3D,CAAA;CAqFJ"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Arrays, asInstanceOf, assert, ByteArrayInput, isInstanceOf, Predicates, SetMultimap, UUID } from "@opendaw/lib-std";
|
|
2
|
+
import { AudioFileBox, AudioUnitBox, AuxSendBox, SelectionBox, SoundfontFileBox, TrackBox } from "@opendaw/studio-boxes";
|
|
3
|
+
import { IndexedBox, PointerField } from "@opendaw/lib-box";
|
|
4
|
+
import { UnionBoxTypes } from "../unions";
|
|
5
|
+
import { AudioUnitOrdering } from "../factories/AudioUnitOrdering";
|
|
6
|
+
export var ProjectUtils;
|
|
7
|
+
(function (ProjectUtils) {
|
|
8
|
+
const isSameGraph = ({ graph: a }, { graph: b }) => a === b;
|
|
9
|
+
const compareIndex = (a, b) => a.index.getValue() - b.index.getValue();
|
|
10
|
+
const excludeTimelinePredicate = (box) => box.accept({
|
|
11
|
+
visitTrackBox: (_box) => true
|
|
12
|
+
}) === true;
|
|
13
|
+
ProjectUtils.extractAudioUnits = (audioUnitBoxes, { boxGraph, mandatoryBoxes: { primaryAudioBus, rootBox } }, options = {}) => {
|
|
14
|
+
assert(Arrays.satisfy(audioUnitBoxes, isSameGraph), "AudioUnits must share the same BoxGraph");
|
|
15
|
+
// TODO Implement include options.
|
|
16
|
+
assert(!options.includeAux && !options.includeBus, "Options are not yet implemented");
|
|
17
|
+
const excludeBox = options?.excludeTimeline === true ? excludeTimelinePredicate : Predicates.alwaysFalse;
|
|
18
|
+
const dependencies = audioUnitBoxes
|
|
19
|
+
.flatMap(box => Array.from(box.graph.dependenciesOf(box, { alwaysFollowMandatory: true, excludeBox }).boxes))
|
|
20
|
+
.filter(box => box.name !== SelectionBox.ClassName && box.name !== AuxSendBox.ClassName);
|
|
21
|
+
const uuidMap = generateTransferMap(audioUnitBoxes, dependencies, rootBox.audioUnits.address.uuid, primaryAudioBus.address.uuid);
|
|
22
|
+
copy(uuidMap, boxGraph, audioUnitBoxes, dependencies);
|
|
23
|
+
reorderAudioUnits(uuidMap, audioUnitBoxes, rootBox);
|
|
24
|
+
console.debug("inTransaction", boxGraph.inTransaction());
|
|
25
|
+
return audioUnitBoxes.map(source => asInstanceOf(rootBox.graph
|
|
26
|
+
.findBox(uuidMap.get(source.address.uuid).target)
|
|
27
|
+
.unwrap("Target Track has not been copied"), AudioUnitBox));
|
|
28
|
+
};
|
|
29
|
+
ProjectUtils.extractRegions = (regionBoxes, { boxGraph, mandatoryBoxes: { primaryAudioBus, rootBox } }, insertPosition = 0.0) => {
|
|
30
|
+
assert(Arrays.satisfy(regionBoxes, isSameGraph), "Region smust be from the same BoxGraph");
|
|
31
|
+
const regionBoxSet = new Set(regionBoxes);
|
|
32
|
+
const trackBoxSet = new Set();
|
|
33
|
+
const audioUnitBoxSet = new SetMultimap();
|
|
34
|
+
// Collect AudioUnits and Tracks
|
|
35
|
+
regionBoxes.forEach(regionBox => {
|
|
36
|
+
const trackBox = asInstanceOf(regionBox.regions.targetVertex.unwrap().box, TrackBox);
|
|
37
|
+
trackBoxSet.add(trackBox);
|
|
38
|
+
const audioUnitBox = asInstanceOf(trackBox.tracks.targetVertex.unwrap().box, AudioUnitBox);
|
|
39
|
+
audioUnitBoxSet.add(audioUnitBox, trackBox);
|
|
40
|
+
});
|
|
41
|
+
console.debug(`Found ${audioUnitBoxSet.keyCount()} audioUnits`);
|
|
42
|
+
console.debug(`Found ${trackBoxSet.size} tracks`);
|
|
43
|
+
const audioUnitBoxes = [...audioUnitBoxSet.keys()];
|
|
44
|
+
const excludeBox = box => (isInstanceOf(box, TrackBox) && !trackBoxSet.has(box))
|
|
45
|
+
|| (UnionBoxTypes.isRegionBox(box) && !regionBoxSet.has(box));
|
|
46
|
+
const dependencies = audioUnitBoxes
|
|
47
|
+
.flatMap(box => Array.from(box.graph.dependenciesOf(box, { excludeBox, alwaysFollowMandatory: true }).boxes))
|
|
48
|
+
.filter(box => box.name !== SelectionBox.ClassName && box.name !== AuxSendBox.ClassName);
|
|
49
|
+
const uuidMap = generateTransferMap(audioUnitBoxes, dependencies, rootBox.audioUnits.address.uuid, primaryAudioBus.address.uuid);
|
|
50
|
+
copy(uuidMap, boxGraph, audioUnitBoxes, dependencies);
|
|
51
|
+
reorderAudioUnits(uuidMap, audioUnitBoxes, rootBox);
|
|
52
|
+
// reorder track indices
|
|
53
|
+
audioUnitBoxSet.forEach((_, trackBoxes) => [...trackBoxes]
|
|
54
|
+
.sort(compareIndex)
|
|
55
|
+
.forEach((source, index) => {
|
|
56
|
+
const box = boxGraph
|
|
57
|
+
.findBox(uuidMap.get(source.address.uuid).target)
|
|
58
|
+
.unwrap("Target Track has not been copied");
|
|
59
|
+
asInstanceOf(box, TrackBox).index.setValue(index);
|
|
60
|
+
}));
|
|
61
|
+
// move new regions to the target position
|
|
62
|
+
const minPosition = regionBoxes.reduce((min, region) => Math.min(min, region.position.getValue()), Number.MAX_VALUE);
|
|
63
|
+
const delta = insertPosition - minPosition;
|
|
64
|
+
regionBoxes.forEach((source) => {
|
|
65
|
+
const box = boxGraph
|
|
66
|
+
.findBox(uuidMap.get(source.address.uuid).target)
|
|
67
|
+
.unwrap("Target Track has not been copied");
|
|
68
|
+
const position = UnionBoxTypes.asRegionBox(box).position;
|
|
69
|
+
position.setValue(position.getValue() + delta);
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
const generateTransferMap = (audioUnitBoxes, dependencies, rootBoxUUID, masterBusBoxUUID) => {
|
|
73
|
+
const uuidMap = UUID.newSet(({ source }) => source);
|
|
74
|
+
uuidMap.addMany([
|
|
75
|
+
...audioUnitBoxes
|
|
76
|
+
.filter(({ output: { targetAddress } }) => targetAddress.nonEmpty())
|
|
77
|
+
.map(box => ({
|
|
78
|
+
source: box.output.targetAddress.unwrap().uuid,
|
|
79
|
+
target: masterBusBoxUUID
|
|
80
|
+
})),
|
|
81
|
+
...audioUnitBoxes
|
|
82
|
+
.map(box => ({
|
|
83
|
+
source: box.collection.targetAddress.unwrap("AudioUnitBox was not connected to a RootBox").uuid,
|
|
84
|
+
target: rootBoxUUID
|
|
85
|
+
})),
|
|
86
|
+
...audioUnitBoxes
|
|
87
|
+
.map(box => ({
|
|
88
|
+
source: box.address.uuid,
|
|
89
|
+
target: UUID.generate()
|
|
90
|
+
})),
|
|
91
|
+
...dependencies
|
|
92
|
+
.map(({ address: { uuid }, name }) => ({
|
|
93
|
+
source: uuid,
|
|
94
|
+
target: name === AudioFileBox.ClassName || name === SoundfontFileBox.ClassName
|
|
95
|
+
? uuid
|
|
96
|
+
: UUID.generate()
|
|
97
|
+
}))
|
|
98
|
+
]);
|
|
99
|
+
return uuidMap;
|
|
100
|
+
};
|
|
101
|
+
const copy = (uuidMap, boxGraph, audioUnitBoxes, dependencies) => {
|
|
102
|
+
PointerField.decodeWith({
|
|
103
|
+
map: (_pointer, newAddress) => newAddress.map(address => uuidMap.opt(address.uuid).match({
|
|
104
|
+
none: () => address,
|
|
105
|
+
some: ({ target }) => address.moveTo(target)
|
|
106
|
+
}))
|
|
107
|
+
}, () => {
|
|
108
|
+
audioUnitBoxes
|
|
109
|
+
.forEach((source) => {
|
|
110
|
+
const input = new ByteArrayInput(source.toArrayBuffer());
|
|
111
|
+
const key = source.name;
|
|
112
|
+
const uuid = uuidMap.get(source.address.uuid).target;
|
|
113
|
+
boxGraph.createBox(key, uuid, box => box.read(input));
|
|
114
|
+
});
|
|
115
|
+
dependencies
|
|
116
|
+
.forEach((source) => {
|
|
117
|
+
const input = new ByteArrayInput(source.toArrayBuffer());
|
|
118
|
+
const key = source.name;
|
|
119
|
+
const uuid = uuidMap.get(source.address.uuid).target;
|
|
120
|
+
if (source instanceof AudioFileBox || source instanceof SoundfontFileBox) {
|
|
121
|
+
// Those boxes keep their UUID. So if they are already in the graph, we can just read them.
|
|
122
|
+
if (boxGraph.findBox(source.address.uuid).nonEmpty()) {
|
|
123
|
+
source.read(input);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
boxGraph.createBox(key, uuid, box => box.read(input));
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const reorderAudioUnits = (uuidMap, audioUnitBoxes, rootBox) => audioUnitBoxes
|
|
132
|
+
.toSorted(compareIndex)
|
|
133
|
+
.map(source => (asInstanceOf(rootBox.graph
|
|
134
|
+
.findBox(uuidMap.get(source.address.uuid).target)
|
|
135
|
+
.unwrap("Target Track has not been copied"), AudioUnitBox)))
|
|
136
|
+
.forEach((target) => IndexedBox.collectIndexedBoxes(rootBox.audioUnits, AudioUnitBox).toSorted((a, b) => {
|
|
137
|
+
const orderA = AudioUnitOrdering[a.type.getValue()];
|
|
138
|
+
const orderB = AudioUnitOrdering[b.type.getValue()];
|
|
139
|
+
const orderDifference = orderA - orderB;
|
|
140
|
+
return orderDifference === 0 ? b === target ? -1 : 1 : orderDifference;
|
|
141
|
+
}).forEach((box, index) => box.index.setValue(index)));
|
|
142
|
+
})(ProjectUtils || (ProjectUtils = {}));
|
package/dist/protocols.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocols.d.ts","sourceRoot":"","sources":["../src/protocols.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACrC,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EAAC,qBAAqB,EAAC,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AAE1C,MAAM,WAAW,cAAe,SAAQ,UAAU;IAC9C,IAAI,IAAI,IAAI,CAAA;IACZ,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IAC1B,WAAW,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAA;IACjC,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7C,aAAa,IAAI,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"protocols.d.ts","sourceRoot":"","sources":["../src/protocols.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACrC,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EAAC,qBAAqB,EAAC,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AAE1C,MAAM,WAAW,cAAe,SAAQ,UAAU;IAC9C,IAAI,IAAI,IAAI,CAAA;IACZ,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IAC1B,WAAW,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAA;IACjC,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7C,aAAa,IAAI,IAAI,CAAA;IACrB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAC3C,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACnD,mBAAmB,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,CAAA;IACrC,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IAExC,KAAK,IAAI,IAAI,CAAA;IAEb,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAA;IACpC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;IAExC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IAC1D,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;CAC9D;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAA;IAC5B,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IAChD,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACrD,yBAAyB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAA;IAC/D,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAA;IAC3D,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IACpF,KAAK,IAAI,IAAI,CAAA;CAChB"}
|
|
@@ -1,59 +1,72 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _FilteredSelection_selection, _FilteredSelection_filter, _FilteredSelection_mapping, _FilteredSelection_set, _FilteredSelection_listeners, _FilteredSelection_subscription;
|
|
1
13
|
import { Listeners } from "@opendaw/lib-std";
|
|
2
14
|
import { Address } from "@opendaw/lib-box";
|
|
3
15
|
export class FilteredSelection {
|
|
4
|
-
#selection;
|
|
5
|
-
#filter;
|
|
6
|
-
#mapping;
|
|
7
|
-
#set;
|
|
8
|
-
#listeners;
|
|
9
|
-
#subscription;
|
|
10
16
|
constructor(selection, filter, mapping) {
|
|
11
|
-
this
|
|
12
|
-
this
|
|
13
|
-
this
|
|
14
|
-
|
|
15
|
-
this
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
this
|
|
17
|
+
_FilteredSelection_selection.set(this, void 0);
|
|
18
|
+
_FilteredSelection_filter.set(this, void 0);
|
|
19
|
+
_FilteredSelection_mapping.set(this, void 0);
|
|
20
|
+
_FilteredSelection_set.set(this, void 0);
|
|
21
|
+
_FilteredSelection_listeners.set(this, void 0);
|
|
22
|
+
_FilteredSelection_subscription.set(this, void 0);
|
|
23
|
+
__classPrivateFieldSet(this, _FilteredSelection_selection, selection, "f");
|
|
24
|
+
__classPrivateFieldSet(this, _FilteredSelection_filter, filter, "f");
|
|
25
|
+
__classPrivateFieldSet(this, _FilteredSelection_mapping, mapping, "f");
|
|
26
|
+
__classPrivateFieldSet(this, _FilteredSelection_set, Address.newSet(addressable => addressable.address), "f");
|
|
27
|
+
__classPrivateFieldSet(this, _FilteredSelection_listeners, new Listeners(), "f");
|
|
28
|
+
__classPrivateFieldGet(this, _FilteredSelection_selection, "f").selected()
|
|
29
|
+
.filter(element => __classPrivateFieldGet(this, _FilteredSelection_filter, "f").call(this, element))
|
|
30
|
+
.forEach(element => __classPrivateFieldGet(this, _FilteredSelection_set, "f").add(__classPrivateFieldGet(this, _FilteredSelection_mapping, "f").fy(element)));
|
|
31
|
+
__classPrivateFieldSet(this, _FilteredSelection_subscription, __classPrivateFieldGet(this, _FilteredSelection_selection, "f").catchupAndSubscribe({
|
|
20
32
|
onSelected: (element) => {
|
|
21
|
-
if (this
|
|
22
|
-
const value = this
|
|
23
|
-
this
|
|
24
|
-
this
|
|
33
|
+
if (__classPrivateFieldGet(this, _FilteredSelection_filter, "f").call(this, element)) {
|
|
34
|
+
const value = __classPrivateFieldGet(this, _FilteredSelection_mapping, "f").fy(element);
|
|
35
|
+
__classPrivateFieldGet(this, _FilteredSelection_set, "f").add(value);
|
|
36
|
+
__classPrivateFieldGet(this, _FilteredSelection_listeners, "f").proxy.onSelected(value);
|
|
25
37
|
}
|
|
26
38
|
},
|
|
27
39
|
onDeselected: (element) => {
|
|
28
|
-
if (this
|
|
29
|
-
this
|
|
40
|
+
if (__classPrivateFieldGet(this, _FilteredSelection_filter, "f").call(this, element)) {
|
|
41
|
+
__classPrivateFieldGet(this, _FilteredSelection_listeners, "f").proxy.onDeselected(__classPrivateFieldGet(this, _FilteredSelection_set, "f").removeByKey(element.address));
|
|
30
42
|
}
|
|
31
43
|
}
|
|
32
|
-
});
|
|
44
|
+
}), "f");
|
|
33
45
|
}
|
|
34
|
-
terminate() { this
|
|
46
|
+
terminate() { __classPrivateFieldGet(this, _FilteredSelection_subscription, "f").terminate(); }
|
|
35
47
|
select(...selectables) {
|
|
36
|
-
this
|
|
48
|
+
__classPrivateFieldGet(this, _FilteredSelection_selection, "f").select(...selectables.map(selectable => __classPrivateFieldGet(this, _FilteredSelection_mapping, "f").fx(selectable)));
|
|
37
49
|
}
|
|
38
50
|
deselect(...selectables) {
|
|
39
|
-
this
|
|
51
|
+
__classPrivateFieldGet(this, _FilteredSelection_selection, "f").deselect(...selectables.map(selectable => __classPrivateFieldGet(this, _FilteredSelection_mapping, "f").fx(selectable)));
|
|
40
52
|
}
|
|
41
53
|
deselectAll() {
|
|
42
|
-
this
|
|
54
|
+
__classPrivateFieldGet(this, _FilteredSelection_selection, "f").deselect(...(__classPrivateFieldGet(this, _FilteredSelection_set, "f").values().map(selectable => __classPrivateFieldGet(this, _FilteredSelection_mapping, "f").fx(selectable))));
|
|
43
55
|
}
|
|
44
56
|
distance(inventory) {
|
|
45
|
-
return this
|
|
57
|
+
return __classPrivateFieldGet(this, _FilteredSelection_selection, "f").distance(inventory.map(selectable => __classPrivateFieldGet(this, _FilteredSelection_mapping, "f").fx(selectable))).map(item => __classPrivateFieldGet(this, _FilteredSelection_mapping, "f").fy(item));
|
|
46
58
|
}
|
|
47
|
-
isEmpty() { return this
|
|
48
|
-
nonEmpty() { return this
|
|
49
|
-
count() { return this
|
|
50
|
-
isSelected(selectable) { return this
|
|
51
|
-
selected() { return this
|
|
59
|
+
isEmpty() { return __classPrivateFieldGet(this, _FilteredSelection_set, "f").size() === 0; }
|
|
60
|
+
nonEmpty() { return __classPrivateFieldGet(this, _FilteredSelection_set, "f").size() > 0; }
|
|
61
|
+
count() { return __classPrivateFieldGet(this, _FilteredSelection_set, "f").size(); }
|
|
62
|
+
isSelected(selectable) { return __classPrivateFieldGet(this, _FilteredSelection_set, "f").hasKey(selectable.address); }
|
|
63
|
+
selected() { return __classPrivateFieldGet(this, _FilteredSelection_set, "f").values(); }
|
|
52
64
|
subscribe(listener) {
|
|
53
|
-
return this
|
|
65
|
+
return __classPrivateFieldGet(this, _FilteredSelection_listeners, "f").subscribe(listener);
|
|
54
66
|
}
|
|
55
67
|
catchupAndSubscribe(listener) {
|
|
56
|
-
this
|
|
68
|
+
__classPrivateFieldGet(this, _FilteredSelection_set, "f").forEach(selectable => listener.onSelected(selectable));
|
|
57
69
|
return this.subscribe(listener);
|
|
58
70
|
}
|
|
59
71
|
}
|
|
72
|
+
_FilteredSelection_selection = new WeakMap(), _FilteredSelection_filter = new WeakMap(), _FilteredSelection_mapping = new WeakMap(), _FilteredSelection_set = new WeakMap(), _FilteredSelection_listeners = new WeakMap(), _FilteredSelection_subscription = new WeakMap();
|