Implement time signature handling and build arrangement events for Ableton export

This commit is contained in:
2026-07-14 09:41:06 +02:00
parent 18d7095dd2
commit 4bf04cf93c

View File

@@ -280,18 +280,6 @@ function trackAutomationTargets(
return targets; return targets;
} }
function groupAutomationTargets(groupTrack: any) {
const targets: AbletonAutomationTargets = {};
const mixer = groupTrack.DeviceChain.Mixer;
addTarget(targets, FaderParam.LVL, targetFor(mixer.Volume));
addTarget(targets, FaderParam.PAN, targetFor(mixer.Pan));
const send = mixer.Sends?.TrackSendHolder?.Send;
if (send) {
addTarget(targets, FaderParam.FX, targetFor(send));
}
return targets;
}
async function buildMidiClip( async function buildMidiClip(
koClip: AblClip, koClip: AblClip,
clipIdx: number, clipIdx: number,
@@ -1107,6 +1095,44 @@ async function buildReturnTrack(
return { ReturnTrack: returnTrack }; return { ReturnTrack: returnTrack };
} }
function getTimeSignatureId(timeSignature: { numerator: number; denominator: number }) {
return (
TIME_SIGNATURES[`${timeSignature.numerator}/${timeSignature.denominator}`] ||
TIME_SIGNATURES['4/4']
);
}
function buildArrangementTimeSignatureEvents(
sections: AblArrangementSection[],
fallbackTimeSignature: { numerator: number; denominator: number },
) {
const initialTimeSignature = sections[0]?.timeSignature || fallbackTimeSignature;
const events = [
{
'@Id': 0,
'@Time': -63072000,
'@Value': getTimeSignatureId(initialTimeSignature),
},
];
let previousTimeSignatureId = getTimeSignatureId(initialTimeSignature);
sections.forEach((section, index) => {
const timeSignatureId = getTimeSignatureId(section.timeSignature);
if (index === 0 || timeSignatureId === previousTimeSignatureId) {
previousTimeSignatureId = timeSignatureId;
return;
}
events.push({
'@Id': events.length,
'@Time': section.offset,
'@Value': timeSignatureId,
});
previousTimeSignatureId = timeSignatureId;
});
return events;
}
export async function buildProject(projectData: ProjectRawData, exporterParams: ExporterParams) { export async function buildProject(projectData: ProjectRawData, exporterParams: ExporterParams) {
resetIds(); resetIds();
const abletonVersion = getAbletonVersion(exporterParams); const abletonVersion = getAbletonVersion(exporterParams);
@@ -1132,18 +1158,21 @@ export async function buildProject(projectData: ProjectRawData, exporterParams:
project.Ableton.LiveSet.MasterTrack.AutomationEnvelopes.Envelopes.AutomationEnvelope[1].Automation.Events.FloatEvent[ project.Ableton.LiveSet.MasterTrack.AutomationEnvelopes.Envelopes.AutomationEnvelope[1].Automation.Events.FloatEvent[
'@Value' '@Value'
] = projectData.settings.bpm; ] = projectData.settings.bpm;
// setting up time signature const initialTimeSignature =
project.Ableton.LiveSet.MasterTrack.AutomationEnvelopes.Envelopes.AutomationEnvelope[0].Automation.Events.EnumEvent[ transformedData.arrangementSections[0]?.timeSignature ||
'@Value' projectData.scenesSettings.timeSignature;
] = project.Ableton.LiveSet.MasterTrack.DeviceChain.Mixer.TimeSignature.Manual['@Value'] =
TIME_SIGNATURES[ getTimeSignatureId(initialTimeSignature);
`${projectData.scenesSettings.timeSignature.numerator}/${projectData.scenesSettings.timeSignature.denominator}` project.Ableton.LiveSet.MasterTrack.AutomationEnvelopes.Envelopes.AutomationEnvelope[0].Automation.Events.EnumEvent =
] || TIME_SIGNATURES['4/4']; buildArrangementTimeSignatureEvents(
transformedData.arrangementSections,
projectData.scenesSettings.timeSignature,
) as any;
const tracks = await buildTracks( const tracks = await buildTracks(
transformedData.tracks, transformedData.tracks,
transformedData.groupLanes, transformedData.groupLanes,
transformedData.scenes.length, transformedData.scenes,
exporterParams, exporterParams,
); );
project.Ableton.LiveSet.Tracks = { '#': tracks } as any; project.Ableton.LiveSet.Tracks = { '#': tracks } as any;
@@ -1158,18 +1187,16 @@ export async function buildProject(projectData: ProjectRawData, exporterParams:
project.Ableton.LiveSet.Tracks['#'].push(returnTrack); project.Ableton.LiveSet.Tracks['#'].push(returnTrack);
} }
if (exporterParams.clips) { const scenes = await buildScenes(
const scenes = await buildScenes( transformedData.scenes,
transformedData.scenes, projectData.settings,
projectData.settings, transformedData.scenes.length,
transformedData.scenes.length, abletonVersion,
abletonVersion, );
); if (abletonVersion === '10') {
if (abletonVersion === '10') { (project.Ableton.LiveSet as any).SceneNames.Scene = scenes;
(project.Ableton.LiveSet as any).SceneNames.Scene = scenes; } else {
} else { project.Ableton.LiveSet.Scenes.Scene = scenes;
project.Ableton.LiveSet.Scenes.Scene = scenes;
}
} }
if (exporterParams.sendEffects) { if (exporterParams.sendEffects) {