diff --git a/src/lib/transformers/ableton.ts b/src/lib/transformers/ableton.ts index db55dd9..2b77b4a 100644 --- a/src/lib/transformers/ableton.ts +++ b/src/lib/transformers/ableton.ts @@ -16,6 +16,7 @@ import { findPad, findSoundByPad, findSoundIdByPad } from '../utils'; export type AblData = { tracks: AblTrack[]; scenes: AblScene[]; + groupLanes: AblGroupLane[]; }; export type AblTrack = Omit & { @@ -50,13 +51,30 @@ export type AblClip = { sceneName: string; timeSignature: TimeSignature; faderParams: { [K in FaderParam]: number }; - faderAutomation: AblFaderAutomationPoint[]; + groupPattern?: AblGroupPatternOccurrence; }; export type AblFaderAutomationPoint = Pick & { 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 = { name: string; }; @@ -65,6 +83,7 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams const { pads, scenes } = data; const customSceneNames = exporterParams.customSceneNames || {}; const lanes: AblLane[] = []; + const groupLanes: AblGroupLane[] = []; const ablScenes: AblScene[] = []; let tracks: AblTrack[] = []; let offset = 0; @@ -78,6 +97,41 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams const ablScene: AblScene = { name: customSceneNames[scene.name] || scene.name, }; + const groupPatterns: Record = {}; + + 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) => { 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 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) { const soundId = findSoundIdByPad(pattern.pad, pads) || 0; @@ -165,7 +210,7 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams sceneName: customSceneNames[scene.name] || scene.name, timeSignature: data.scenesSettings.timeSignature, faderParams, - faderAutomation, + groupPattern: groupPatterns[pad.group], }); track.lane = lane; @@ -325,11 +370,13 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams Sentry.setContext(`abletonData`, { tracks, scenes: ablScenes, + groupLanes, }); return { tracks, scenes: ablScenes, + groupLanes, } as AblData; }