Add comprehensive test coverage for Ableton effects and automation parameters
This commit is contained in:
@@ -3,6 +3,7 @@ import test from 'node:test';
|
|||||||
import {
|
import {
|
||||||
buildArrangementEnvelopes,
|
buildArrangementEnvelopes,
|
||||||
buildClipEnvelopes,
|
buildClipEnvelopes,
|
||||||
|
convertFaderValue,
|
||||||
getFaderValueAt,
|
getFaderValueAt,
|
||||||
} from '../src/lib/exporters/ableton/automation';
|
} from '../src/lib/exporters/ableton/automation';
|
||||||
import { AblGroupPatternOccurrence, AblTrack } from '../src/lib/transformers/ableton';
|
import { AblGroupPatternOccurrence, AblTrack } from '../src/lib/transformers/ableton';
|
||||||
@@ -79,3 +80,37 @@ test('uses absolute automation targets for Session clip envelopes', () => {
|
|||||||
assert.equal(envelopes[0].Automation.Events.FloatEvent[2]['@Time'], 1);
|
assert.equal(envelopes[0].Automation.Events.FloatEvent[2]['@Time'], 1);
|
||||||
assert.deepEqual(envelopes[0].LoopSlot, { Value: {} });
|
assert.deepEqual(envelopes[0].LoopSlot, { Value: {} });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('uses each Simpler target duration and One-Shot release direction', () => {
|
||||||
|
assert.equal(
|
||||||
|
convertFaderValue(FaderParam.REL, 1, track, false, {
|
||||||
|
soundLength: 10,
|
||||||
|
maxValue: 2000,
|
||||||
|
invertValue: true,
|
||||||
|
}),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
convertFaderValue(FaderParam.REL, 0, track, false, {
|
||||||
|
soundLength: 10,
|
||||||
|
maxValue: 2000,
|
||||||
|
invertValue: true,
|
||||||
|
}),
|
||||||
|
2000,
|
||||||
|
);
|
||||||
|
|
||||||
|
const envelopes = buildClipEnvelopes(
|
||||||
|
occurrence,
|
||||||
|
{
|
||||||
|
[FaderParam.REL]: [
|
||||||
|
{ session: 23000, soundLength: 2 },
|
||||||
|
{ session: 23001, soundLength: 4, maxValue: 2000, invertValue: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
track,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(envelopes[0].Automation.Events.FloatEvent[2]['@Value'], 1500);
|
||||||
|
assert.equal(envelopes[1].Automation.Events.FloatEvent[2]['@Value'], 1000);
|
||||||
|
});
|
||||||
|
|||||||
67
tests/ableton-effects.test.ts
Normal file
67
tests/ableton-effects.test.ts
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
import {
|
||||||
|
chorusEffectValues,
|
||||||
|
compressorEffectValues,
|
||||||
|
delayEffectValues,
|
||||||
|
distortionEffectValues,
|
||||||
|
filterEffectValues,
|
||||||
|
reverbEffectValues,
|
||||||
|
} from '../src/lib/exporters/ableton/effects';
|
||||||
|
|
||||||
|
test('maps delay length and feedback inside Live ranges', () => {
|
||||||
|
assert.deepEqual(delayEffectValues(0, 0), { time: 0.001, feedback: 0 });
|
||||||
|
const maximum = delayEffectValues(1, 1);
|
||||||
|
assert.ok(maximum.time <= 5);
|
||||||
|
assert.equal(maximum.feedback, 0.95);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('maps reverb color around a neutral center', () => {
|
||||||
|
assert.deepEqual(reverbEffectValues(0, 0), {
|
||||||
|
decayTime: 200,
|
||||||
|
highShelfOn: true,
|
||||||
|
highShelfGain: 0.19999999999999996,
|
||||||
|
lowShelfOn: false,
|
||||||
|
lowShelfGain: 1,
|
||||||
|
});
|
||||||
|
assert.deepEqual(reverbEffectValues(1, 0.5), {
|
||||||
|
decayTime: 8000,
|
||||||
|
highShelfOn: false,
|
||||||
|
highShelfGain: 1,
|
||||||
|
lowShelfOn: false,
|
||||||
|
lowShelfGain: 1,
|
||||||
|
});
|
||||||
|
assert.equal(reverbEffectValues(0.5, 1).lowShelfGain, 0.19999999999999996);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('maps distortion and chorus controls to their documented roles', () => {
|
||||||
|
assert.deepEqual(distortionEffectValues(1, 1), { drive: 50, tone: 100 });
|
||||||
|
assert.deepEqual(chorusEffectValues(0, 0), { rate: 0.1, feedback: 0 });
|
||||||
|
assert.deepEqual(chorusEffectValues(1, 1), { rate: 10, feedback: 0.95 });
|
||||||
|
});
|
||||||
|
|
||||||
|
test('maps the filter cutoff to low-pass and high-pass halves', () => {
|
||||||
|
assert.deepEqual(filterEffectValues(0, 0), {
|
||||||
|
filterType: 0,
|
||||||
|
cutoff: 20,
|
||||||
|
resonance: 0,
|
||||||
|
});
|
||||||
|
assert.equal(filterEffectValues(0.5, 1).cutoff, 135);
|
||||||
|
assert.equal(filterEffectValues(0.5, 1).filterType, 0);
|
||||||
|
assert.equal(filterEffectValues(1, 1).cutoff, 135);
|
||||||
|
assert.equal(filterEffectValues(1, 1).filterType, 1);
|
||||||
|
assert.equal(filterEffectValues(1, 1).resonance, 1.25);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('maps compressor drive and speed across a usable range', () => {
|
||||||
|
assert.deepEqual(compressorEffectValues(0, 0), {
|
||||||
|
threshold: 1,
|
||||||
|
ratio: 4,
|
||||||
|
attack: 50,
|
||||||
|
release: 500,
|
||||||
|
});
|
||||||
|
const maximum = compressorEffectValues(1, 1);
|
||||||
|
assert.ok(Math.abs(maximum.threshold - 0.015848931924611134) < 1e-12);
|
||||||
|
assert.ok(Math.abs(maximum.attack - 0.1) < 1e-12);
|
||||||
|
assert.ok(Math.abs(maximum.release - 30) < 1e-12);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user