Improve calculation of arrangement points for Ableton export
This commit is contained in:
@@ -147,39 +147,49 @@ function getArrangementPoints(
|
|||||||
groupMixer: boolean,
|
groupMixer: boolean,
|
||||||
target: AbletonAutomationTarget,
|
target: AbletonAutomationTarget,
|
||||||
) {
|
) {
|
||||||
|
const orderedPatterns = patterns.toSorted((a, b) => {
|
||||||
|
const offsetDifference = a.offset - b.offset;
|
||||||
|
return offsetDifference || (a.occurrenceIndex ?? 0) - (b.occurrenceIndex ?? 0);
|
||||||
|
});
|
||||||
|
const hasAutomation = orderedPatterns.some((pattern) =>
|
||||||
|
pattern.faderAutomation.some((point) => point.parameter === parameter),
|
||||||
|
);
|
||||||
|
if (!hasAutomation) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const points: AutomationPoint[] = [];
|
const points: AutomationPoint[] = [];
|
||||||
let hasAutomation = false;
|
let previousValue = orderedPatterns[0]
|
||||||
let previousValue = patterns[0]
|
? getConvertedStaticValue(orderedPatterns[0], parameter, track, groupMixer, target)
|
||||||
? getConvertedStaticValue(patterns[0], parameter, track, groupMixer, target)
|
|
||||||
: convertFaderValue(parameter, defaultValue(parameter), track, groupMixer, target);
|
: convertFaderValue(parameter, defaultValue(parameter), track, groupMixer, target);
|
||||||
|
|
||||||
patterns.forEach((pattern) => {
|
orderedPatterns.forEach((pattern) => {
|
||||||
const beats = pattern.timeSignature.numerator * (4 / pattern.timeSignature.denominator);
|
const patternTicks = Math.max(1, pattern.loopDuration * 96);
|
||||||
const patternTicks = pattern.bars * beats * 96;
|
const occurrenceTicks = Math.max(1, pattern.duration * 96);
|
||||||
const sceneTicks = pattern.sceneBars * beats * 96;
|
const startTime = pattern.offset;
|
||||||
const startTime = pattern.offset * beats;
|
|
||||||
const sourcePoints = pattern.faderAutomation
|
const sourcePoints = pattern.faderAutomation
|
||||||
.filter((point) => point.parameter === parameter)
|
.filter((point) => point.parameter === parameter)
|
||||||
.sort((a, b) => a.position - b.position);
|
.sort((a, b) => a.position - b.position);
|
||||||
const staticValue = getConvertedStaticValue(pattern, parameter, track, groupMixer, target);
|
const staticValue = getConvertedStaticValue(pattern, parameter, track, groupMixer, target);
|
||||||
|
|
||||||
if (sourcePoints.length === 0) {
|
|
||||||
if (hasAutomation) {
|
|
||||||
points.push({ time: Math.max(0, startTime - BOUNDARY_EPSILON), value: previousValue });
|
points.push({ time: Math.max(0, startTime - BOUNDARY_EPSILON), value: previousValue });
|
||||||
points.push({ time: startTime, value: staticValue });
|
points.push({ time: startTime, value: staticValue });
|
||||||
}
|
|
||||||
previousValue = staticValue;
|
previousValue = staticValue;
|
||||||
|
|
||||||
|
if (sourcePoints.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasAutomation = true;
|
for (let loopOffset = 0; loopOffset < occurrenceTicks; loopOffset += patternTicks) {
|
||||||
for (let loopOffset = 0; loopOffset < sceneTicks; loopOffset += patternTicks) {
|
|
||||||
const loopStart = startTime + loopOffset / 96;
|
const loopStart = startTime + loopOffset / 96;
|
||||||
|
if (loopOffset > 0) {
|
||||||
points.push({ time: Math.max(0, loopStart - BOUNDARY_EPSILON), value: previousValue });
|
points.push({ time: Math.max(0, loopStart - BOUNDARY_EPSILON), value: previousValue });
|
||||||
points.push({ time: loopStart, value: staticValue });
|
points.push({ time: loopStart, value: staticValue });
|
||||||
|
previousValue = staticValue;
|
||||||
|
}
|
||||||
|
|
||||||
sourcePoints.forEach((point) => {
|
sourcePoints.forEach((point) => {
|
||||||
if (loopOffset + point.position >= sceneTicks) {
|
if (loopOffset + point.position >= occurrenceTicks) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const value = convertFaderValue(parameter, point.value, track, groupMixer, target);
|
const value = convertFaderValue(parameter, point.value, track, groupMixer, target);
|
||||||
@@ -189,10 +199,6 @@ function getArrangementPoints(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!hasAutomation) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [{ time: SENTINEL_TIME, value: points[0]?.value ?? previousValue }, ...points];
|
return [{ time: SENTINEL_TIME, value: points[0]?.value ?? previousValue }, ...points];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,9 +212,6 @@ function getClipPoints(
|
|||||||
const sourcePoints = pattern.faderAutomation
|
const sourcePoints = pattern.faderAutomation
|
||||||
.filter((point) => point.parameter === parameter)
|
.filter((point) => point.parameter === parameter)
|
||||||
.sort((a, b) => a.position - b.position);
|
.sort((a, b) => a.position - b.position);
|
||||||
if (sourcePoints.length === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const staticValue = getConvertedStaticValue(pattern, parameter, track, groupMixer, target);
|
const staticValue = getConvertedStaticValue(pattern, parameter, track, groupMixer, target);
|
||||||
return [
|
return [
|
||||||
|
|||||||
Reference in New Issue
Block a user