diff --git a/src/lib/exporters/ableton/automation.ts b/src/lib/exporters/ableton/automation.ts index 180b7f8..dd33be1 100644 --- a/src/lib/exporters/ableton/automation.ts +++ b/src/lib/exporters/ableton/automation.ts @@ -1,11 +1,17 @@ import { FaderParam } from '../../../types/types'; import { AblGroupPatternOccurrence, AblTrack } from '../../transformers/ableton'; +import { + convertGroupFaderValue, + getFaderDefaultValue, + getFaderPolicy, +} from './faderPolicies'; export type AbletonAutomationTarget = { arrangement?: number; session?: number; staticValue?: number; valueOffset?: number; + padTrack?: AblTrack; }; export type AbletonAutomationTargets = Partial>; @@ -18,21 +24,6 @@ type AutomationPoint = { const SENTINEL_TIME = -63072000; const BOUNDARY_EPSILON = 0.000001; -function defaultValue(parameter: FaderParam) { - switch (parameter) { - case FaderParam.LVL: - case FaderParam.LPF: - return 1; - case FaderParam.PTC: - case FaderParam.TIM: - case FaderParam.PAN: - case FaderParam.TUNE: - return 0.5; - default: - return 0; - } -} - export function convertFaderValue( parameter: FaderParam, value: number, @@ -40,42 +31,11 @@ export function convertFaderValue( groupMixer: boolean, target?: AbletonAutomationTarget, ) { - let convertedValue: number; - switch (parameter) { - case FaderParam.LVL: - if (groupMixer) { - convertedValue = value; - } else { - convertedValue = track.volume * value; - } - break; - case FaderParam.PTC: - convertedValue = (target?.valueOffset ?? 0) + (value - 0.5) * 10; - break; - case FaderParam.LPF: - convertedValue = 20 + value * 0.9 * 115; - break; - case FaderParam.HPF: - convertedValue = 20 + value * 0.7 * 115; - break; - case FaderParam.FX: - convertedValue = value; - break; - case FaderParam.PAN: - convertedValue = (value - 0.5) * 2; - break; - case FaderParam.TUNE: - convertedValue = Math.max(-0.5, Math.min(0.5, value - 0.5)) * 100; - break; - case FaderParam.MOD: - convertedValue = value / 20; - break; - default: - convertedValue = value; - break; - } - - return convertedValue; + return convertGroupFaderValue(parameter, value, { + track: target?.padTrack ?? track, + groupMixer, + valueOffset: target?.valueOffset, + }); } export function getFaderValueAt( @@ -98,7 +58,7 @@ export function getFaderValueAt( function getStaticValue(pattern: AblGroupPatternOccurrence, parameter: FaderParam) { const value = pattern.faderParams[parameter]; - return value === -1 ? defaultValue(parameter) : value; + return value === -1 ? getFaderDefaultValue(parameter) : value; } function getConvertedStaticValue( @@ -141,7 +101,13 @@ function getArrangementPoints( const points: AutomationPoint[] = []; let previousValue = orderedPatterns[0] ? getConvertedStaticValue(orderedPatterns[0], parameter, track, groupMixer, target) - : convertFaderValue(parameter, defaultValue(parameter), track, groupMixer, target); + : convertFaderValue( + parameter, + getFaderDefaultValue(parameter), + track, + groupMixer, + target, + ); orderedPatterns.forEach((pattern) => { const patternTicks = Math.max(1, pattern.loopDuration * 96); @@ -193,6 +159,10 @@ function getClipPoints( .filter((point) => point.parameter === parameter) .sort((a, b) => a.position - b.position); + if (sourcePoints.length === 0) { + return []; + } + const staticValue = getConvertedStaticValue(pattern, parameter, track, groupMixer, target); return [ { time: SENTINEL_TIME, value: staticValue }, @@ -231,7 +201,7 @@ export function buildArrangementEnvelopes( const envelopes: any[] = []; Object.entries(targets).forEach(([parameterString, targetList]) => { const parameter = Number(parameterString) as FaderParam; - if (parameter === FaderParam.TIM || parameter === FaderParam.VEL) { + if (getFaderPolicy(parameter).renderStrategy !== 'target') { return; } targetList?.forEach((target) => { @@ -265,7 +235,7 @@ export function buildClipEnvelopes( const envelopes: any[] = []; Object.entries(targets).forEach(([parameterString, targetList]) => { const parameter = Number(parameterString) as FaderParam; - if (parameter === FaderParam.TIM || parameter === FaderParam.VEL) { + if (getFaderPolicy(parameter).renderStrategy !== 'target') { return; } targetList?.forEach((target) => {