Enhance Ableton export logic with scaled note velocity and filter fader canonicalization
This commit is contained in:
@@ -52,6 +52,16 @@ export function getFaderValueAt(
|
||||
return value;
|
||||
}
|
||||
|
||||
export function getScaledNoteVelocity(
|
||||
originalVelocity: number,
|
||||
occurrence: AblGroupPatternOccurrence | undefined,
|
||||
position: number,
|
||||
) {
|
||||
const faderValue = getFaderValueAt(occurrence, FaderParam.VEL, position);
|
||||
const velocity = faderValue === undefined ? originalVelocity : originalVelocity * faderValue;
|
||||
return Math.max(1, Math.min(127, Math.round(velocity)));
|
||||
}
|
||||
|
||||
function getStaticValue(pattern: AblGroupPatternOccurrence, parameter: FaderParam) {
|
||||
const value = pattern.faderParams[parameter];
|
||||
return value === -1 ? getFaderDefaultValue(parameter) : value;
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
AbletonAutomationTargets,
|
||||
buildArrangementEnvelopes,
|
||||
buildClipEnvelopes,
|
||||
getFaderValueAt,
|
||||
getScaledNoteVelocity,
|
||||
} from './automation';
|
||||
import {
|
||||
chorusEffectValues,
|
||||
@@ -30,7 +30,11 @@ import {
|
||||
filterEffectValues,
|
||||
reverbEffectValues,
|
||||
} from './effects';
|
||||
import { convertGroupFaderValue, getFaderDefaultValue } from './faderPolicies';
|
||||
import {
|
||||
canonicalizeFilterFaderValue,
|
||||
convertGroupFaderValue,
|
||||
getFaderDefaultValue,
|
||||
} from './faderPolicies';
|
||||
import { AbletonMidiControllerTargets, buildMidiClipEnvelopes } from './midi';
|
||||
import { getPadEnvelopeState, getPadSoundState } from './padSound';
|
||||
import { getSimplerPlaybackState } from './playback';
|
||||
@@ -295,15 +299,10 @@ async function buildMidiClip(
|
||||
dur = nextNote.position / 96 - noteData.position / 96;
|
||||
}
|
||||
|
||||
const automatedVelocity = koClip.groupPattern
|
||||
? getFaderValueAt(koClip.groupPattern, FaderParam.VEL, noteData.position)
|
||||
: undefined;
|
||||
const velocity = Math.max(
|
||||
1,
|
||||
Math.min(
|
||||
127,
|
||||
automatedVelocity === undefined ? noteData.velocity : automatedVelocity * 127,
|
||||
),
|
||||
const velocity = getScaledNoteVelocity(
|
||||
noteData.velocity,
|
||||
koClip.groupPattern,
|
||||
noteData.position,
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -644,7 +643,10 @@ async function buildTrack(
|
||||
|
||||
if (exporterParams.includeArchivedSamples) {
|
||||
for (const parameter of [FaderParam.LPF, FaderParam.HPF] as const) {
|
||||
const staticValue = koTrack.faderParams[parameter];
|
||||
const staticValue = canonicalizeFilterFaderValue(
|
||||
parameter,
|
||||
koTrack.faderParams[parameter],
|
||||
);
|
||||
const defaultValue = getFaderDefaultValue(parameter);
|
||||
const hasAutomation = automatedParameters.has(parameter);
|
||||
if (hasAutomation || (staticValue !== -1 && staticValue !== defaultValue)) {
|
||||
|
||||
@@ -93,7 +93,7 @@ export const FADER_POLICIES = {
|
||||
toLive: (value) => Math.max(-0.5, Math.min(0.5, value - 0.5)) * 100,
|
||||
},
|
||||
[FaderParam.VEL]: {
|
||||
defaultValue: 0,
|
||||
defaultValue: 1,
|
||||
renderStrategy: 'note',
|
||||
targetScope: 'track',
|
||||
status: 'research',
|
||||
@@ -116,6 +116,14 @@ export function getFaderDefaultValue(parameter: FaderParam) {
|
||||
return getFaderPolicy(parameter).defaultValue;
|
||||
}
|
||||
|
||||
export function canonicalizeFilterFaderValue(
|
||||
parameter: FaderParam.LPF | FaderParam.HPF,
|
||||
value: number,
|
||||
) {
|
||||
const defaultValue = getFaderDefaultValue(parameter);
|
||||
return Math.abs(value - defaultValue) <= 0.001 ? defaultValue : value;
|
||||
}
|
||||
|
||||
export function convertGroupFaderValue(
|
||||
parameter: FaderParam,
|
||||
value: number,
|
||||
|
||||
Reference in New Issue
Block a user