From 04cd054f45055f6a934572583bb95116a728db65 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Mon, 13 Jul 2026 04:48:39 +0200 Subject: [PATCH] Improve compatibility with different Ableton Live versions in builders --- src/lib/exporters/ableton/builders.ts | 45 ++++++++++++++++++++------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/lib/exporters/ableton/builders.ts b/src/lib/exporters/ableton/builders.ts index 74afb0e..0df78de 100644 --- a/src/lib/exporters/ableton/builders.ts +++ b/src/lib/exporters/ableton/builders.ts @@ -597,7 +597,7 @@ async function buildReturnTrack( setColorValue(returnTrack, 28); if (projectData.effects.effectType === EffectType.Reverb) { - const effectReverbTemplate = await loadTemplate('effectReverb'); + const effectReverbTemplate = await loadTemplate('effectReverb', abletonVersion); const effectReverb = structuredClone(effectReverbTemplate.Reverb); // these params are very rough approximation of the KO's reverb @@ -612,7 +612,7 @@ async function buildReturnTrack( } if (projectData.effects.effectType === EffectType.Delay) { - const effectDelayTemplate = await loadTemplate('effectDelay'); + const effectDelayTemplate = await loadTemplate('effectDelay', abletonVersion); const effectDelay = structuredClone(effectDelayTemplate.Delay); effectDelay.DelayLine_SyncL.Manual['@Value'] = 'false'; @@ -628,7 +628,10 @@ async function buildReturnTrack( } if (projectData.effects.effectType === EffectType.Distortion) { - const effectDistortionTemplate = await loadTemplate('effectDistortion'); + const effectDistortionTemplate = await loadTemplate( + 'effectDistortion', + abletonVersion, + ); const effectDistortion = structuredClone(effectDistortionTemplate.Overdrive); effectDistortion.Drive.Manual['@Value'] = projectData.effects.param1 * 50; @@ -638,18 +641,27 @@ async function buildReturnTrack( } if (projectData.effects.effectType === EffectType.Chorus) { - const effectChorusTemplate = await loadTemplate('effectChorus'); - const effectChorus = structuredClone(effectChorusTemplate.Chorus2); + const effectChorusTemplate = await loadTemplate('effectChorus', abletonVersion); + const effectChorus = structuredClone( + abletonVersion === '10' + ? (effectChorusTemplate as any).Chorus + : effectChorusTemplate.Chorus2, + ); - effectChorus.Amount.Manual['@Value'] = projectData.effects.param1; + if (abletonVersion === '10') { + effectChorus.ModAmount.Manual['@Value'] = projectData.effects.param1 * 6.5; + } else { + effectChorus.Amount.Manual['@Value'] = projectData.effects.param1; + } effectChorus.Feedback.Manual['@Value'] = projectData.effects.param2 * 0.8; - returnTrack.DeviceChain.DeviceChain.Devices = { Chorus2: effectChorus }; + returnTrack.DeviceChain.DeviceChain.Devices = + abletonVersion === '10' ? { Chorus: effectChorus } : { Chorus2: effectChorus }; } // putting a filter in return track is absolutely pointless, but hey, why not if (projectData.effects.effectType === EffectType.Filter) { - const effectFilterTemplate = await loadTemplate('effectFilter'); + const effectFilterTemplate = await loadTemplate('effectFilter', abletonVersion); const effectFilter = structuredClone(effectFilterTemplate.AutoFilter); effectFilter.Cutoff.Manual['@Value'] = 20 + projectData.effects.param1 * (135 - 20); @@ -659,7 +671,10 @@ async function buildReturnTrack( } if (projectData.effects.effectType === EffectType.Compressor) { - const effectCompressorTemplate = await loadTemplate('effectCompressor'); + const effectCompressorTemplate = await loadTemplate( + 'effectCompressor', + abletonVersion, + ); const effectCompressor = structuredClone(effectCompressorTemplate.Compressor2); // params are ignored for now, just putting a basic compressor @@ -672,6 +687,7 @@ async function buildReturnTrack( export async function buildProject(projectData: ProjectRawData, exporterParams: ExporterParams) { resetIds(); + const abletonVersion = getAbletonVersion(exporterParams); const transformedData = abletonTransformer(projectData, exporterParams); if (import.meta.env.DEV) { @@ -685,7 +701,7 @@ export async function buildProject(projectData: ProjectRawData, exporterParams: _localTrackColor = 1; _localGroupTrackColor = 1; - const projectTemplate = await loadTemplate('project'); + const projectTemplate = await loadTemplate('project', abletonVersion); const project = structuredClone(projectTemplate); // setting up tempo @@ -712,17 +728,24 @@ export async function buildProject(projectData: ProjectRawData, exporterParams: const returnTrack = await buildReturnTrack( projectData, project.Ableton.LiveSet.Tracks['#'].length + 1, + abletonVersion, ); project.Ableton.LiveSet.Tracks['#'].push(returnTrack); } if (exporterParams.clips) { - project.Ableton.LiveSet.Scenes.Scene = await buildScenes( + const scenes = await buildScenes( transformedData.scenes, projectData.settings, transformedData.scenes.length, + abletonVersion, ); + if (abletonVersion === '10') { + (project.Ableton.LiveSet as any).SceneNames.Scene = scenes; + } else { + project.Ableton.LiveSet.Scenes.Scene = scenes; + } } if (exporterParams.sendEffects) {