Improve ableton export logic and update documentation
This commit is contained in:
@@ -298,6 +298,7 @@ function abletonTransformer(data: ProjectRawData, exporterParams: ExporterParams
|
||||
const groupTracksForDrumRack = tracks
|
||||
.filter((track) => track.group === group && track.sampleName)
|
||||
.filter((track) => getTrackNoteValues(track).length <= 1)
|
||||
.filter((track) => !track.lane?.clips.some((clip) => clip.midiEvents.length > 0))
|
||||
.map((track) => ({
|
||||
...track,
|
||||
drumRackSendingNote: getTrackNoteValues(track)[0] ?? track.rootNote,
|
||||
|
||||
@@ -23,7 +23,7 @@ function sanitizeFileName(value: string): string {
|
||||
}
|
||||
|
||||
const NOTES: Record<ExportFormatId, string> = {
|
||||
ableton: `When samples are included, pads used at one consistent pitch are automatically organized into Drum Racks, while chromatic pads remain on separate MIDI tracks. Recorded fader automation is exported for LVL, PTC, LPF, HPF, FX, ATK, REL, PAN, TUNE, VEL and MOD. Choke groups work between pads in the same Drum Rack. TIM automation, the EP effects and stretching algorithms remain approximations.`,
|
||||
ableton: `When samples are included, suitable single-pitch pads are automatically organized into Drum Racks, while chromatic or expressive pads remain on separate MIDI tracks. Recorded fader automation is exported for LVL, PTC, LPF, HPF, FX, ATK, REL, PAN, TUNE, VEL and MOD. Choke groups work between pads in the same Drum Rack. TIM automation, the EP effects and stretching algorithms remain approximations.`,
|
||||
dawproject: `Unfortunately, the DAWproject format does not currently support the "Sampler" instrument, so you will need to manually assign the samples in your DAW.`,
|
||||
midi: `The simplest format supported by any DAW. But you have to assign the samples manually.`,
|
||||
reaper: `Only basic sampler features are supported`,
|
||||
|
||||
@@ -6,9 +6,11 @@ import {
|
||||
FaderParam,
|
||||
Group,
|
||||
GroupFaderParam,
|
||||
MidiPatternEvent,
|
||||
Note,
|
||||
Pad,
|
||||
PadCode,
|
||||
PatternEventKind,
|
||||
ProjectRawData,
|
||||
} from '../src/types/types';
|
||||
|
||||
@@ -222,6 +224,26 @@ test('classifies a pad from its distinct pitches across every exported scene', (
|
||||
assert.ok(result.tracks.some((track) => track.padCode === 'a1' && !track.drumRack));
|
||||
});
|
||||
|
||||
test('keeps pad-specific MIDI expression on an individual track', () => {
|
||||
const data = project();
|
||||
const rawData = new Uint8Array([0, 0, PatternEventKind.Midi, 0xd0, 100, 0, 0, 0]);
|
||||
const event: MidiPatternEvent = {
|
||||
type: 'midi',
|
||||
kind: PatternEventKind.Midi,
|
||||
position: 0,
|
||||
source: 0,
|
||||
flags: 0,
|
||||
rawData,
|
||||
data: rawData.slice(3, 7),
|
||||
};
|
||||
data.scenes[0].patternEvents.a?.events.push(event);
|
||||
const result = abletonTransformer(data, { includeArchivedSamples: true });
|
||||
const a0 = result.tracks.find((track) => track.padCode === 'a0' && !track.drumRack);
|
||||
|
||||
assert.ok(a0);
|
||||
assert.equal(a0.lane?.clips[0].midiEvents.length, 1);
|
||||
});
|
||||
|
||||
test('does not create selector-note racks when samples are excluded', () => {
|
||||
const result = abletonTransformer(project(), {
|
||||
includeArchivedSamples: false,
|
||||
|
||||
Reference in New Issue
Block a user