Enhance Ableton export with value inversion support for automation and envelopes

This commit is contained in:
2026-07-13 08:50:03 +02:00
parent af18829b95
commit f8e928cb10
2 changed files with 28 additions and 5 deletions

View File

@@ -7,6 +7,7 @@ export type AbletonAutomationTarget = {
session?: number;
maxValue?: number;
soundLength?: number;
invertValue?: boolean;
};
export type AbletonAutomationTargets = Partial<Record<FaderParam, AbletonAutomationTarget[]>>;
@@ -64,11 +65,17 @@ export function convertFaderValue(
break;
case FaderParam.ATK:
convertedValue =
koEnvRangeToSeconds(value * 255, target?.soundLength ?? track.soundLength) * 1000;
koEnvRangeToSeconds(
(target?.invertValue ? 1 - value : value) * 255,
target?.soundLength ?? track.soundLength,
) * 1000;
break;
case FaderParam.REL:
convertedValue =
koEnvRangeToSeconds(value * 255, target?.soundLength ?? track.soundLength) * 1000;
koEnvRangeToSeconds(
(target?.invertValue ? 1 - value : value) * 255,
target?.soundLength ?? track.soundLength,
) * 1000;
break;
case FaderParam.PAN:
convertedValue = (value - 0.5) * 2;

View File

@@ -67,8 +67,14 @@ function getAbletonVersion(exporterParams: ExporterParams): AbletonVersion {
return exporterParams.abletonVersion === '10' ? '10' : '11';
}
function simplerEnvelopeMilliseconds(value: number, soundLength: number, oneshot: boolean) {
const milliseconds = koEnvRangeToSeconds(value, soundLength) * 1000;
function simplerEnvelopeMilliseconds(
value: number,
soundLength: number,
oneshot: boolean,
invertValue: boolean = false,
) {
const convertedValue = invertValue ? 255 - value : value;
const milliseconds = koEnvRangeToSeconds(convertedValue, soundLength) * 1000;
return oneshot ? Math.min(2000, milliseconds) : milliseconds;
}
@@ -104,7 +110,12 @@ function setLive10SampleReference(fileRef: any, sampleName: string) {
fileRef.LivePackId = { '@Value': '' };
}
function targetFor(parameter: any, maxValue?: number, soundLength?: number) {
function targetFor(
parameter: any,
maxValue?: number,
soundLength?: number,
invertValue?: boolean,
) {
const automationTarget =
parameter?.AutomationTarget?.['@Id'] === undefined
? undefined
@@ -114,6 +125,7 @@ function targetFor(parameter: any, maxValue?: number, soundLength?: number) {
session: automationTarget,
maxValue,
soundLength,
invertValue,
};
}
@@ -204,6 +216,7 @@ function trackAutomationTargets(midiTrack: any, includeArrangementMixer: boolean
: simpler.VolumeAndPan.Envelope.AttackTime,
oneshot ? 2000 : undefined,
soundLength,
false,
),
);
addTarget(
@@ -215,6 +228,7 @@ function trackAutomationTargets(midiTrack: any, includeArrangementMixer: boolean
: simpler.VolumeAndPan.Envelope.ReleaseTime,
oneshot ? 2000 : undefined,
soundLength,
oneshot,
),
);
addTarget(targets, FaderParam.MOD, targetFor(simpler.Pitch.PitchLfoAmount));
@@ -452,6 +466,7 @@ async function buildSimplerDevice(koTrack: AblTrack, abletonVersion: AbletonVers
koTrack.release,
koTrack.soundLength,
oneshot,
oneshot,
);
device.VolumeAndPan.Panorama.Manual['@Value'] = koTrack.pan;
@@ -470,6 +485,7 @@ async function buildSimplerDevice(koTrack: AblTrack, abletonVersion: AbletonVers
koTrack.faderParams[FaderParam.REL] * 255,
koTrack.soundLength,
oneshot,
oneshot,
);
}