Update Ableton MIDI exporter to support locked envelopes and improve robustness
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
import type { AblMidiEvent } from '../../transformers/ableton';
|
import type { AblMidiEvent } from '../../transformers/ableton';
|
||||||
|
|
||||||
export type AbletonMidiControllerTargets = Record<string, { '@Id': number }>;
|
export type AbletonMidiControllerTargets = Record<
|
||||||
|
string,
|
||||||
|
{ '@Id': number; LockEnvelope?: { '@Value': number | string } }
|
||||||
|
>;
|
||||||
|
|
||||||
type AutomationPoint = {
|
type AutomationPoint = {
|
||||||
time: number;
|
time: number;
|
||||||
@@ -36,10 +39,13 @@ export function buildMidiClipEnvelopes(
|
|||||||
events: AblMidiEvent[],
|
events: AblMidiEvent[],
|
||||||
controllerTargets: AbletonMidiControllerTargets,
|
controllerTargets: AbletonMidiControllerTargets,
|
||||||
) {
|
) {
|
||||||
const target = controllerTargets[`ControllerTargets.${CHANNEL_PRESSURE_TARGET}`]?.['@Id'];
|
const target = controllerTargets[`ControllerTargets.${CHANNEL_PRESSURE_TARGET}`];
|
||||||
if (target === undefined) {
|
if (!target) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
if (target.LockEnvelope) {
|
||||||
|
target.LockEnvelope['@Value'] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
const points: AutomationPoint[] = [{ time: SENTINEL_TIME, value: 0 }];
|
const points: AutomationPoint[] = [{ time: SENTINEL_TIME, value: 0 }];
|
||||||
let previousValue = 0;
|
let previousValue = 0;
|
||||||
@@ -70,7 +76,7 @@ export function buildMidiClipEnvelopes(
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
'@Id': 0,
|
'@Id': 0,
|
||||||
EnvelopeTarget: { PointeeId: { '@Value': target } },
|
EnvelopeTarget: { PointeeId: { '@Value': target['@Id'] } },
|
||||||
Automation: {
|
Automation: {
|
||||||
Events: { FloatEvent: floatEvents(points) },
|
Events: { FloatEvent: floatEvents(points) },
|
||||||
AutomationTransformViewState: {
|
AutomationTransformViewState: {
|
||||||
|
|||||||
@@ -83,14 +83,18 @@ test('decodes only the captured EP Channel Pressure record shape', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('builds native Live 10 Channel Pressure steps with raw values', () => {
|
test('builds native Live 10 Channel Pressure steps with raw values', () => {
|
||||||
|
const controllerTargets = {
|
||||||
|
'ControllerTargets.129': { '@Id': 45123, LockEnvelope: { '@Value': 0 } },
|
||||||
|
};
|
||||||
const envelopes = buildMidiClipEnvelopes(
|
const envelopes = buildMidiClipEnvelopes(
|
||||||
[midiEvent(192, 2, 20), midiEvent(96, 2, 75), midiEvent(96, 2, 20)],
|
[midiEvent(192, 2, 20), midiEvent(96, 2, 75), midiEvent(96, 2, 20)],
|
||||||
{ 'ControllerTargets.129': { '@Id': 45123 } },
|
controllerTargets,
|
||||||
);
|
);
|
||||||
const envelope = envelopes[0];
|
const envelope = envelopes[0];
|
||||||
const events = envelope.Automation.Events.FloatEvent;
|
const events = envelope.Automation.Events.FloatEvent;
|
||||||
|
|
||||||
assert.equal(envelope.EnvelopeTarget.PointeeId['@Value'], 45123);
|
assert.equal(envelope.EnvelopeTarget.PointeeId['@Value'], 45123);
|
||||||
|
assert.equal(controllerTargets['ControllerTargets.129'].LockEnvelope['@Value'], 1);
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
events.map((event: any) => [event['@Time'], event['@Value']]),
|
events.map((event: any) => [event['@Time'], event['@Value']]),
|
||||||
[
|
[
|
||||||
|
|||||||
Reference in New Issue
Block a user