Writing an Ableton Drum Rack from Node for Max, because the Live API can't

Idriss Sernn's icon

I spent months building a concatenative synthesis device for Live 12 in

TypeScript on Node for Max, and the part that took longest wasn't the audio.

The device analyses a corpus, cuts it into ~90 ms grains, and rebuilds a target

sound out of them. At the end you want the result on pads, playable. The obvious

route is the Live API: make a Drum Rack, load a sample into each pad. It cannot

be done. Browser.load_item wants a BrowserItem, and nothing turns a file path

into one — the browser tree only holds the User Library and folders the user

added. So the API route ends in "copy your sounds somewhere Live can see them and

go find them", which is a file browser detour by another name.

There is a straight road, and it's the one Live's own Convert commands drive on:

create_midi_track_with_simpler(clip), then Sample.insert_slice(t) on each

seam, then sliced_simpler_to_drum_rack(simpler). So the device writes ONE wav

with every chosen sound laid end to end and hands over the exact sample offset

each one starts at. Nothing is detected or guessed at the other end: we wrote the

file, we know where the seams are, one pad per sound — where slicing by transient

would have found two in a snare with a long tail.

A few things that cost me time, in case they save you some:

· the .adg is gzipped XML, and Live is unforgiving about element order

· a jweb window is a WKWebView on macOS: user-select: none on * kills the

caret in every text input, silently, while Blink exempts form fields

· with Live's audio engine off, node.script doesn't boot at all and the

scheduler is frozen — adstatus stays quiet, so the device has to say so

itself

· Max draws boxes first-to-last, so the FIRST box is the one in front

Happy to go into any of it.

Idriss Sernn