Implement time signature handling and build arrangement events for Ableton export
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user