Add support for group lanes and pattern-based fader automation in Ableton transformer
This commit is contained in:
@@ -16,6 +16,7 @@ import { findPad, findSoundByPad, findSoundIdByPad } from '../utils';
|
|||||||
export type AblData = {
|
export type AblData = {
|
||||||
tracks: AblTrack[];
|
tracks: AblTrack[];
|
||||||
scenes: AblScene[];
|
scenes: AblScene[];
|
||||||
|
groupLanes: AblGroupLane[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AblTrack = Omit<Pad, 'file' | 'rawData' | 'midiChannel'> & {
|
export type AblTrack = Omit<Pad, 'file' | 'rawData' | 'midiChannel'> & {
|
||||||
@@ -50,13 +51,30 @@ export type AblClip = {
|
|||||||
sceneName: string;
|
sceneName: string;
|
||||||
timeSignature: TimeSignature;
|
timeSignature: TimeSignature;
|
||||||
faderParams: { [K in FaderParam]: number };
|
faderParams: { [K in FaderParam]: number };
|
||||||
faderAutomation: AblFaderAutomationPoint[];
|
groupPattern?: AblGroupPatternOccurrence;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AblFaderAutomationPoint = Pick<FaderAutomationEvent, 'position' | 'value' | 'flags'> & {
|
export type AblFaderAutomationPoint = Pick<FaderAutomationEvent, 'position' | 'value' | 'flags'> & {
|
||||||
parameter: FaderParam;
|
parameter: FaderParam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type AblGroupPatternOccurrence = {
|
||||||
|
group: string;
|
||||||
|
bars: number;
|
||||||
|
sceneBars: number;
|
||||||
|
sceneIndex: number;
|
||||||
|
sceneName: string;
|
||||||
|
offset: number;
|
||||||
|
timeSignature: TimeSignature;
|
||||||
|
faderParams: { [K in FaderParam]: number };
|
||||||
|
faderAutomation: AblFaderAutomationPoint[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AblGroupLane = {
|
||||||
|
group: string;
|
||||||
|
patterns: AblGroupPatternOccurrence[];
|
||||||
|
};
|
||||||
|
|
||||||
export type AblScene = {
|
export type AblScene = {
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
@@ -65,6 +83,7 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams
|
|||||||
const { pads, scenes } = data;
|
const { pads, scenes } = data;
|
||||||
const customSceneNames = exporterParams.customSceneNames || {};
|
const customSceneNames = exporterParams.customSceneNames || {};
|
||||||
const lanes: AblLane[] = [];
|
const lanes: AblLane[] = [];
|
||||||
|
const groupLanes: AblGroupLane[] = [];
|
||||||
const ablScenes: AblScene[] = [];
|
const ablScenes: AblScene[] = [];
|
||||||
let tracks: AblTrack[] = [];
|
let tracks: AblTrack[] = [];
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
@@ -78,6 +97,41 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams
|
|||||||
const ablScene: AblScene = {
|
const ablScene: AblScene = {
|
||||||
name: customSceneNames[scene.name] || scene.name,
|
name: customSceneNames[scene.name] || scene.name,
|
||||||
};
|
};
|
||||||
|
const groupPatterns: Record<string, AblGroupPatternOccurrence> = {};
|
||||||
|
|
||||||
|
Object.entries(scene.patternEvents).forEach(([group, pattern]) => {
|
||||||
|
if (!pattern) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const faderParams = data.settings.groupFaderParams[group];
|
||||||
|
const groupPattern: AblGroupPatternOccurrence = {
|
||||||
|
group,
|
||||||
|
bars: pattern.bars,
|
||||||
|
sceneBars,
|
||||||
|
sceneIndex,
|
||||||
|
sceneName: customSceneNames[scene.name] || scene.name,
|
||||||
|
offset,
|
||||||
|
timeSignature: data.scenesSettings.timeSignature,
|
||||||
|
faderParams,
|
||||||
|
faderAutomation: pattern.events
|
||||||
|
.filter((event): event is FaderAutomationEvent => event.type === 'fader')
|
||||||
|
.filter((event) => event.parameter >= FaderParam.LVL && event.parameter <= FaderParam.MOD)
|
||||||
|
.map((event) => ({
|
||||||
|
position: event.position,
|
||||||
|
parameter: event.parameter as FaderParam,
|
||||||
|
value: event.value,
|
||||||
|
flags: event.flags,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
let groupLane = groupLanes.find((lane) => lane.group === group);
|
||||||
|
if (!groupLane) {
|
||||||
|
groupLane = { group, patterns: [] };
|
||||||
|
groupLanes.push(groupLane);
|
||||||
|
}
|
||||||
|
groupLane.patterns.push(groupPattern);
|
||||||
|
groupPatterns[group] = groupPattern;
|
||||||
|
});
|
||||||
|
|
||||||
scene.patterns.forEach((pattern) => {
|
scene.patterns.forEach((pattern) => {
|
||||||
let track = tracks.find((c) => c.padCode === pattern.pad);
|
let track = tracks.find((c) => c.padCode === pattern.pad);
|
||||||
@@ -112,15 +166,6 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams
|
|||||||
}
|
}
|
||||||
|
|
||||||
const faderParams = data.settings.groupFaderParams[pad.group];
|
const faderParams = data.settings.groupFaderParams[pad.group];
|
||||||
const faderAutomation = (scene.patternEvents[pad.group]?.events || [])
|
|
||||||
.filter((event): event is FaderAutomationEvent => event.type === 'fader')
|
|
||||||
.filter((event) => event.parameter >= FaderParam.LVL && event.parameter <= FaderParam.MOD)
|
|
||||||
.map((event) => ({
|
|
||||||
position: event.position,
|
|
||||||
parameter: event.parameter as FaderParam,
|
|
||||||
value: event.value,
|
|
||||||
flags: event.flags,
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (!track) {
|
if (!track) {
|
||||||
const soundId = findSoundIdByPad(pattern.pad, pads) || 0;
|
const soundId = findSoundIdByPad(pattern.pad, pads) || 0;
|
||||||
@@ -165,7 +210,7 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams
|
|||||||
sceneName: customSceneNames[scene.name] || scene.name,
|
sceneName: customSceneNames[scene.name] || scene.name,
|
||||||
timeSignature: data.scenesSettings.timeSignature,
|
timeSignature: data.scenesSettings.timeSignature,
|
||||||
faderParams,
|
faderParams,
|
||||||
faderAutomation,
|
groupPattern: groupPatterns[pad.group],
|
||||||
});
|
});
|
||||||
|
|
||||||
track.lane = lane;
|
track.lane = lane;
|
||||||
@@ -325,11 +370,13 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams
|
|||||||
Sentry.setContext(`abletonData`, {
|
Sentry.setContext(`abletonData`, {
|
||||||
tracks,
|
tracks,
|
||||||
scenes: ablScenes,
|
scenes: ablScenes,
|
||||||
|
groupLanes,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tracks,
|
tracks,
|
||||||
scenes: ablScenes,
|
scenes: ablScenes,
|
||||||
|
groupLanes,
|
||||||
} as AblData;
|
} as AblData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user