Add comprehensive automation target extraction for Ableton export
This commit is contained in:
@@ -7,7 +7,12 @@ import {
|
||||
ProjectSettings,
|
||||
} from '../../../types/types';
|
||||
import { EFFECTS } from '../../constants';
|
||||
import abletonTransformer, { AblClip, AblScene, AblTrack } from '../../transformers/ableton';
|
||||
import abletonTransformer, {
|
||||
AblClip,
|
||||
AblGroupLane,
|
||||
AblScene,
|
||||
AblTrack,
|
||||
} from '../../transformers/ableton';
|
||||
import { getQuarterNotesPerBar } from '../utils';
|
||||
import { ALSDrumBranch } from './types/drumBranch';
|
||||
import { ALSDrumRack } from './types/drumRack';
|
||||
@@ -25,6 +30,12 @@ import { ALSReturnTrack } from './types/returnTrack';
|
||||
import { ALSScene, ALSSceneContent } from './types/scene';
|
||||
import { ALSSimpler } from './types/simpler';
|
||||
import { ALSTrackSendHolder } from './types/trackSendHolder';
|
||||
import {
|
||||
AbletonAutomationTargets,
|
||||
buildArrangementEnvelopes,
|
||||
buildClipEnvelopes,
|
||||
getFaderValueAt,
|
||||
} from './automation';
|
||||
import {
|
||||
filterFreqFromNormalized,
|
||||
fixIds,
|
||||
@@ -82,6 +93,94 @@ function setLive10SampleReference(fileRef: any, sampleName: string) {
|
||||
fileRef.LivePackId = { '@Value': '' };
|
||||
}
|
||||
|
||||
function targetFor(parameter: any): { arrangement?: number; session?: number } {
|
||||
return {
|
||||
arrangement:
|
||||
parameter?.AutomationTarget?.['@Id'] === undefined
|
||||
? undefined
|
||||
: Number(parameter.AutomationTarget['@Id']),
|
||||
session:
|
||||
parameter?.ModulationTarget?.['@Id'] === undefined
|
||||
? undefined
|
||||
: Number(parameter.ModulationTarget['@Id']),
|
||||
};
|
||||
}
|
||||
|
||||
function findSimplers(node: any, result: any[] = []): any[] {
|
||||
if (Array.isArray(node)) {
|
||||
node.forEach((item) => findSimplers(item, result));
|
||||
return result;
|
||||
}
|
||||
if (!node || typeof node !== 'object') {
|
||||
return result;
|
||||
}
|
||||
if (node.OriginalSimpler) {
|
||||
result.push(node.OriginalSimpler);
|
||||
}
|
||||
Object.values(node).forEach((value) => findSimplers(value, result));
|
||||
return result;
|
||||
}
|
||||
|
||||
function addTarget(
|
||||
targets: AbletonAutomationTargets,
|
||||
parameter: FaderParam,
|
||||
target: { arrangement?: number; session?: number },
|
||||
) {
|
||||
if (target.arrangement === undefined && target.session === undefined) {
|
||||
return;
|
||||
}
|
||||
targets[parameter] = [...(targets[parameter] || []), target];
|
||||
}
|
||||
|
||||
function trackAutomationTargets(midiTrack: any, includeArrangementMixer: boolean) {
|
||||
const targets: AbletonAutomationTargets = {};
|
||||
const mixer = midiTrack.DeviceChain.Mixer;
|
||||
const sequencer = midiTrack.DeviceChain.MainSequencer;
|
||||
addTarget(targets, FaderParam.LVL, {
|
||||
arrangement: includeArrangementMixer
|
||||
? Number(mixer.Volume.AutomationTarget['@Id'])
|
||||
: undefined,
|
||||
session: Number(sequencer.VolumeModulationTarget['@Id']),
|
||||
});
|
||||
addTarget(targets, FaderParam.PAN, {
|
||||
arrangement: includeArrangementMixer ? Number(mixer.Pan.AutomationTarget['@Id']) : undefined,
|
||||
session: Number(mixer.Pan.ModulationTarget['@Id']),
|
||||
});
|
||||
|
||||
const send = mixer.Sends?.TrackSendHolder?.Send;
|
||||
if (send) {
|
||||
const target = targetFor(send);
|
||||
if (!includeArrangementMixer) {
|
||||
target.arrangement = undefined;
|
||||
}
|
||||
addTarget(targets, FaderParam.FX, target);
|
||||
}
|
||||
|
||||
findSimplers(midiTrack.DeviceChain.DeviceChain.Devices).forEach((simpler) => {
|
||||
addTarget(targets, FaderParam.PTC, targetFor(simpler.Pitch.TransposeKey));
|
||||
addTarget(targets, FaderParam.TUNE, targetFor(simpler.Pitch.TransposeFine));
|
||||
addTarget(targets, FaderParam.LPF, targetFor(simpler.Filter.Slot.Value.SimplerFilter.Freq));
|
||||
addTarget(targets, FaderParam.HPF, targetFor(simpler.Filter.Slot.Value.SimplerFilter.Freq));
|
||||
addTarget(targets, FaderParam.ATK, targetFor(simpler.VolumeAndPan.Envelope.AttackTime));
|
||||
addTarget(targets, FaderParam.REL, targetFor(simpler.VolumeAndPan.Envelope.ReleaseTime));
|
||||
addTarget(targets, FaderParam.MOD, targetFor(simpler.Pitch.PitchLfoAmount));
|
||||
});
|
||||
|
||||
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(
|
||||
koClip: AblClip,
|
||||
clipIdx: number,
|
||||
|
||||
Reference in New Issue
Block a user