Enhance Ableton exporter by incorporating automated fader parameter handling and default value logic
This commit is contained in:
@@ -30,7 +30,7 @@ import {
|
|||||||
filterEffectValues,
|
filterEffectValues,
|
||||||
reverbEffectValues,
|
reverbEffectValues,
|
||||||
} from './effects';
|
} from './effects';
|
||||||
import { convertGroupFaderValue } from './faderPolicies';
|
import { convertGroupFaderValue, getFaderDefaultValue } from './faderPolicies';
|
||||||
import { AbletonMidiControllerTargets, buildMidiClipEnvelopes } from './midi';
|
import { AbletonMidiControllerTargets, buildMidiClipEnvelopes } from './midi';
|
||||||
import { getPadEnvelopeState, getPadSoundState } from './padSound';
|
import { getPadEnvelopeState, getPadSoundState } from './padSound';
|
||||||
import { getSimplerPlaybackState } from './playback';
|
import { getSimplerPlaybackState } from './playback';
|
||||||
@@ -545,7 +545,11 @@ async function buildFaderFilterDevice(
|
|||||||
return { AutoFilter: filter };
|
return { AutoFilter: filter };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildDrumRackDevice(koTrack: AblTrack, abletonVersion: AbletonVersion) {
|
async function buildDrumRackDevice(
|
||||||
|
koTrack: AblTrack,
|
||||||
|
abletonVersion: AbletonVersion,
|
||||||
|
automatedParameters: ReadonlySet<FaderParam>,
|
||||||
|
) {
|
||||||
const [drumRackTemplate, drumBranchTemplate] = await Promise.all([
|
const [drumRackTemplate, drumBranchTemplate] = await Promise.all([
|
||||||
loadTemplate<ALSDrumRack>('drumRack', abletonVersion),
|
loadTemplate<ALSDrumRack>('drumRack', abletonVersion),
|
||||||
loadTemplate<ALSDrumBranch>('drumBranch', abletonVersion),
|
loadTemplate<ALSDrumBranch>('drumBranch', abletonVersion),
|
||||||
@@ -579,7 +583,11 @@ async function buildDrumRackDevice(koTrack: AblTrack, abletonVersion: AbletonVer
|
|||||||
drumBranch.BranchInfo.ChokeGroup['@Value'] = subtrack.inChokeGroup ? 1 : 0;
|
drumBranch.BranchInfo.ChokeGroup['@Value'] = subtrack.inChokeGroup ? 1 : 0;
|
||||||
drumBranch.MixerDevice.Volume.Manual['@Value'] = subtrack.volume;
|
drumBranch.MixerDevice.Volume.Manual['@Value'] = subtrack.volume;
|
||||||
drumBranch.MixerDevice.SendInfos = {};
|
drumBranch.MixerDevice.SendInfos = {};
|
||||||
const branchDevices = await buildSimplerDevice(subtrack, abletonVersion);
|
const branchDevices = await buildSimplerDevice(
|
||||||
|
subtrack,
|
||||||
|
abletonVersion,
|
||||||
|
automatedParameters,
|
||||||
|
);
|
||||||
assignDeviceListIds([branchDevices]);
|
assignDeviceListIds([branchDevices]);
|
||||||
drumBranch.DeviceChain.MidiToAudioDeviceChain.Devices = branchDevices;
|
drumBranch.DeviceChain.MidiToAudioDeviceChain.Devices = branchDevices;
|
||||||
|
|
||||||
@@ -601,6 +609,11 @@ async function buildTrack(
|
|||||||
const abletonVersion = getAbletonVersion(exporterParams);
|
const abletonVersion = getAbletonVersion(exporterParams);
|
||||||
const midiTrackTemplate = await loadTemplate<ALSMidiTrack>('midiTrack', abletonVersion);
|
const midiTrackTemplate = await loadTemplate<ALSMidiTrack>('midiTrack', abletonVersion);
|
||||||
const midiTrack = structuredClone(midiTrackTemplate.MidiTrack);
|
const midiTrack = structuredClone(midiTrackTemplate.MidiTrack);
|
||||||
|
const automatedParameters = new Set(
|
||||||
|
[...(groupLane?.sessionPatterns || []), ...(groupLane?.arrangementPatterns || [])].flatMap(
|
||||||
|
(pattern) => pattern.faderAutomation.map((point) => point.parameter),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
midiTrack['@Id'] = _localId++;
|
midiTrack['@Id'] = _localId++;
|
||||||
midiTrack.Name.EffectiveName['@Value'] = koTrack.soundId
|
midiTrack.Name.EffectiveName['@Value'] = koTrack.soundId
|
||||||
@@ -615,40 +628,44 @@ async function buildTrack(
|
|||||||
midiTrack.DeviceChain.Mixer.Volume.Manual['@Value'] = koTrack.volume;
|
midiTrack.DeviceChain.Mixer.Volume.Manual['@Value'] = koTrack.volume;
|
||||||
|
|
||||||
if (koTrack.faderParams[FaderParam.PAN] !== -1) {
|
if (koTrack.faderParams[FaderParam.PAN] !== -1) {
|
||||||
midiTrack.DeviceChain.Mixer.Pan.Manual['@Value'] =
|
midiTrack.DeviceChain.Mixer.Pan.Manual['@Value'] = convertGroupFaderValue(
|
||||||
(koTrack.faderParams[FaderParam.PAN] - 0.5) * 2;
|
FaderParam.PAN,
|
||||||
|
koTrack.faderParams[FaderParam.PAN],
|
||||||
|
{ track: koTrack },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (koTrack.faderParams[FaderParam.LVL] !== -1) {
|
if (koTrack.faderParams[FaderParam.LVL] !== -1) {
|
||||||
midiTrack.DeviceChain.Mixer.Volume.Manual['@Value'] =
|
midiTrack.DeviceChain.Mixer.Volume.Manual['@Value'] = convertGroupFaderValue(
|
||||||
koTrack.volume * koTrack.faderParams[FaderParam.LVL];
|
FaderParam.LVL,
|
||||||
|
koTrack.faderParams[FaderParam.LVL],
|
||||||
|
{ track: koTrack },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (koTrack.drumRack && exporterParams.includeArchivedSamples) {
|
if (koTrack.drumRack && exporterParams.includeArchivedSamples) {
|
||||||
midiTrack.DeviceChain.DeviceChain.Devices['#'].push(
|
midiTrack.DeviceChain.DeviceChain.Devices['#'].push(
|
||||||
await buildDrumRackDevice(koTrack, abletonVersion),
|
await buildDrumRackDevice(koTrack, abletonVersion, automatedParameters),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!koTrack.drumRack && koTrack.sampleName && exporterParams.includeArchivedSamples) {
|
if (!koTrack.drumRack && koTrack.sampleName && exporterParams.includeArchivedSamples) {
|
||||||
midiTrack.DeviceChain.DeviceChain.Devices['#'].push(
|
midiTrack.DeviceChain.DeviceChain.Devices['#'].push(
|
||||||
await buildSimplerDevice(koTrack, abletonVersion),
|
await buildSimplerDevice(koTrack, abletonVersion, automatedParameters),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exporterParams.includeArchivedSamples) {
|
if (exporterParams.includeArchivedSamples) {
|
||||||
for (const parameter of [FaderParam.LPF, FaderParam.HPF] as const) {
|
for (const parameter of [FaderParam.LPF, FaderParam.HPF] as const) {
|
||||||
const staticValue = koTrack.faderParams[parameter];
|
const staticValue = koTrack.faderParams[parameter];
|
||||||
const defaultValue = parameter === FaderParam.LPF ? 1 : 0;
|
const defaultValue = getFaderDefaultValue(parameter);
|
||||||
const hasAutomation = [
|
const hasAutomation = automatedParameters.has(parameter);
|
||||||
...(groupLane?.sessionPatterns || []),
|
|
||||||
...(groupLane?.arrangementPatterns || []),
|
|
||||||
].some((pattern) => pattern.faderAutomation.some((point) => point.parameter === parameter));
|
|
||||||
if (hasAutomation || (staticValue !== -1 && staticValue !== defaultValue)) {
|
if (hasAutomation || (staticValue !== -1 && staticValue !== defaultValue)) {
|
||||||
midiTrack.DeviceChain.DeviceChain.Devices['#'].push(
|
midiTrack.DeviceChain.DeviceChain.Devices['#'].push(
|
||||||
await buildFaderFilterDevice(
|
await buildFaderFilterDevice(
|
||||||
parameter,
|
parameter,
|
||||||
staticValue === -1 ? defaultValue : staticValue,
|
staticValue === -1 ? defaultValue : staticValue,
|
||||||
|
koTrack,
|
||||||
abletonVersion,
|
abletonVersion,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -671,7 +688,11 @@ async function buildTrack(
|
|||||||
);
|
);
|
||||||
const trackSendHolder = structuredClone(trackSendHolderTemplate.TrackSendHolder);
|
const trackSendHolder = structuredClone(trackSendHolderTemplate.TrackSendHolder);
|
||||||
trackSendHolder['@Id'] = 0;
|
trackSendHolder['@Id'] = 0;
|
||||||
trackSendHolder.Send.Manual['@Value'] = Math.max(0, koTrack.faderParams[FaderParam.FX]);
|
trackSendHolder.Send.Manual['@Value'] = convertGroupFaderValue(
|
||||||
|
FaderParam.FX,
|
||||||
|
Math.max(getFaderDefaultValue(FaderParam.FX), koTrack.faderParams[FaderParam.FX]),
|
||||||
|
{ track: koTrack },
|
||||||
|
);
|
||||||
midiTrack.DeviceChain.Mixer.Sends.TrackSendHolder = trackSendHolder;
|
midiTrack.DeviceChain.Mixer.Sends.TrackSendHolder = trackSendHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user