Add support for MIDI events in Ableton export pipeline
This commit is contained in:
@@ -800,6 +800,7 @@ async function buildTrack(
|
|||||||
if (!hasClip && hasSupportedAutomation) {
|
if (!hasClip && hasSupportedAutomation) {
|
||||||
sessionClips.push({
|
sessionClips.push({
|
||||||
notes: [],
|
notes: [],
|
||||||
|
midiEvents: [],
|
||||||
bars: pattern.bars,
|
bars: pattern.bars,
|
||||||
offset: pattern.offset,
|
offset: pattern.offset,
|
||||||
sceneBars: pattern.sceneBars,
|
sceneBars: pattern.sceneBars,
|
||||||
|
|||||||
@@ -314,11 +314,18 @@ function getPatternsForScene(scenesIntermediate: IntermediateScenes, scenePatter
|
|||||||
|
|
||||||
if (lookupSceneData?.groups[group]) {
|
if (lookupSceneData?.groups[group]) {
|
||||||
const groupData = lookupSceneData.groups[group];
|
const groupData = lookupSceneData.groups[group];
|
||||||
Object.entries(groupData.notes).forEach(([padNum, notes]) => {
|
const sources = new Set(Object.keys(groupData.notes).map(Number));
|
||||||
|
groupData.events.forEach((event) => {
|
||||||
|
if (event.type === 'midi' && event.source >= 0 && event.source < 12) {
|
||||||
|
sources.add(event.source);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
[...sources].toSorted((a, b) => a - b).forEach((padNum) => {
|
||||||
patterns.push({
|
patterns.push({
|
||||||
pad: `${group}${padNum}` as PadCode,
|
pad: `${group}${padNum}` as PadCode,
|
||||||
group,
|
group,
|
||||||
notes,
|
notes: groupData.notes[padNum] || [],
|
||||||
bars: groupData.bars,
|
bars: groupData.bars,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
ExporterParams,
|
ExporterParams,
|
||||||
FaderAutomationEvent,
|
FaderAutomationEvent,
|
||||||
FaderParam,
|
FaderParam,
|
||||||
|
MidiPatternEvent,
|
||||||
Note,
|
Note,
|
||||||
Pad,
|
Pad,
|
||||||
PadCode,
|
PadCode,
|
||||||
@@ -44,6 +45,7 @@ export type AblNote = Note;
|
|||||||
|
|
||||||
export type AblClip = {
|
export type AblClip = {
|
||||||
notes: AblNote[];
|
notes: AblNote[];
|
||||||
|
midiEvents: AblMidiEvent[];
|
||||||
bars: number;
|
bars: number;
|
||||||
offset: number;
|
offset: number;
|
||||||
sceneBars: number;
|
sceneBars: number;
|
||||||
@@ -54,6 +56,11 @@ export type AblClip = {
|
|||||||
groupPattern?: AblGroupPatternOccurrence;
|
groupPattern?: AblGroupPatternOccurrence;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type AblMidiEvent = Pick<
|
||||||
|
MidiPatternEvent,
|
||||||
|
'position' | 'source' | 'flags' | 'data' | 'rawData'
|
||||||
|
>;
|
||||||
|
|
||||||
export type AblFaderAutomationPoint = Pick<FaderAutomationEvent, 'position' | 'value' | 'flags'> & {
|
export type AblFaderAutomationPoint = Pick<FaderAutomationEvent, 'position' | 'value' | 'flags'> & {
|
||||||
parameter: FaderParam;
|
parameter: FaderParam;
|
||||||
};
|
};
|
||||||
@@ -166,6 +173,10 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams
|
|||||||
}
|
}
|
||||||
|
|
||||||
const faderParams = data.settings.groupFaderParams[pad.group];
|
const faderParams = data.settings.groupFaderParams[pad.group];
|
||||||
|
const source = Number(pattern.pad.slice(1));
|
||||||
|
const midiEvents = (scene.patternEvents[pattern.group]?.events || []).filter(
|
||||||
|
(event): event is MidiPatternEvent => event.type === 'midi' && event.source === source,
|
||||||
|
);
|
||||||
|
|
||||||
if (!track) {
|
if (!track) {
|
||||||
const soundId = findSoundIdByPad(pattern.pad, pads) || 0;
|
const soundId = findSoundIdByPad(pattern.pad, pads) || 0;
|
||||||
@@ -204,6 +215,7 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams
|
|||||||
lane.clips.push({
|
lane.clips.push({
|
||||||
offset,
|
offset,
|
||||||
notes: pattern.notes,
|
notes: pattern.notes,
|
||||||
|
midiEvents,
|
||||||
bars: pattern.bars,
|
bars: pattern.bars,
|
||||||
sceneBars,
|
sceneBars,
|
||||||
sceneIndex,
|
sceneIndex,
|
||||||
@@ -324,6 +336,7 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams
|
|||||||
if (!newClips[clip.sceneName]) {
|
if (!newClips[clip.sceneName]) {
|
||||||
newClips[clip.sceneName] = structuredClone(clip);
|
newClips[clip.sceneName] = structuredClone(clip);
|
||||||
newClips[clip.sceneName].notes = [];
|
newClips[clip.sceneName].notes = [];
|
||||||
|
newClips[clip.sceneName].midiEvents = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
newClips[clip.sceneName].notes = [
|
newClips[clip.sceneName].notes = [
|
||||||
@@ -333,6 +346,10 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams
|
|||||||
note: drumPad,
|
note: drumPad,
|
||||||
})),
|
})),
|
||||||
];
|
];
|
||||||
|
newClips[clip.sceneName].midiEvents = [
|
||||||
|
...newClips[clip.sceneName].midiEvents,
|
||||||
|
...clip.midiEvents,
|
||||||
|
];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user