Skip to content

More Than a Live API Wrapper

A lot of projects that connect an AI to Ableton Live are thin wrappers: they take the Live API more or less as-is and forward its calls to the model. That's easy to build, but it pushes every rough edge of a low-level, decade-old API straight onto the AI — and the AI then pushes that friction onto you.

Producer Pal takes the opposite approach. Since the beginning of 2025 it has been continuously refined — every time the AI stumbled over an awkward interface, a confusing value, or a missing capability, that rough edge got smoothed over. The result is a set of tools designed to be intuitive for both the AI and the human, and in some cases to offer features the Live API doesn't provide at all.

Three examples show the range: one small and tidy, one deep and full of arrangement trickery, and one that reaches a feature the API doesn't even admit exists.

A small example: colors as #RRGGBB

Ask the Live API for a track or clip color and you get back a number — something like 16711680. To set a color, you hand it a number too. That's a packed 24-bit integer: red, green, and blue each occupy one byte (0x00RRGGBB). It's perfectly logical for a C++ engine and perfectly opaque to everyone else. No AI (and no human) thinks "bright red" and reaches for 16711680.

Producer Pal wraps that raw number in the #RRGGBB hex syntax everyone already knows from CSS. The AI works with #FF0000; Producer Pal does the bit math on both sides of the boundary (live-api-extensions.ts):

js
// Live API integer → "#RRGGBB"
const r = (colorValue >> 16) & 0xff;
const g = (colorValue >> 8) & 0xff;
const b = colorValue & 0xff;

// "#RRGGBB" → Live API integer
this.set("color", (r << 16) | (g << 8) | b);

Tiny as it is, this is exactly the kind of refinement that adds up. Every tool that touches color — creating tracks, recoloring clips, theming scenes — speaks #RRGGBB, so the AI never has to reason about bit-shifting, and you can ask for "make the drums dark purple" and have it just work.

There's an extra bit of polish here too. Live snaps colors to a fixed palette of about 70 swatches, so the color you ask for isn't always the color you get. A thin wrapper would silently hand back a different number and leave the AI confused. Producer Pal reads the color back after setting it, and when Live has quantized it, it tells the model so in plain language (color-verification-helpers.ts):

Requested clip color #FF0000 was mapped to nearest palette color #FF3636. Live uses a fixed color palette.

Now the AI understands why the color shifted, instead of treating it as a bug.

A big example: splitting clips in the Arrangement

The simple cases are nice. The interesting ones are the features Live's API doesn't have — where Producer Pal has to build the capability itself.

Splitting an arrangement clip is the headline example. In Live's UI you just hit ⌘E to cut a clip in two. But the Live API exposes no split operation at all. There is no split_clip, and the properties you'd reach for to fake it are walled off:

  • You can't shorten a clip by writing its end_time — for warped, looped clips the arrangement length is effectively immutable once the clip exists.
  • You can't create an audio clip in the arrangement with a specific length — create_audio_clip only exists in Session view.
  • The one lever that does move clips around — dropping a new clip so it overlaps an existing one — only trims from the edges. If a new clip overlaps the middle of an existing one, Live truncates at the overlap and throws away everything after it. It does not split into a "before" and an "after." (These constraints are documented in the project's Arrangement-Operations notes, hard-won by probing real Ableton behavior.)

So Producer Pal builds split out of the one primitive that does work reliably — edge trimming via an overlapping clip — applied carefully (arrangement-splitting.ts):

  1. Duplicate the original off to a "holding area" far past your real content, where nothing can collide with it.
  2. Trim each segment out of copies of that clip by dropping a short temporary clip at exactly the boundary, letting Live's edge-truncation do the cut, then deleting the temp clip.
  3. Move each finished segment back to its final spot in the arrangement.
  4. Re-scan the track afterward, because the Live API invalidates clip references the moment you start duplicating and deleting.

The net effect, for a clip split at beats 4 and 8:

Original:   |=================|   beats 0–16
            0    4    8      16

Result:     |===|             segment 0  (right-trimmed in place)
                 |===|        segment 1  (duplicated, trimmed both sides, moved)
                      |======| segment 2  (left-trimmed, moved)

Why there's a generated silent WAV file

Here's the part that surprises people. To trim an audio clip's edge, Producer Pal needs a temporary audio clip to drop on the boundary — and Live won't create an audio clip without a real audio file to point at. There's no "empty audio clip."

So Producer Pal generates its own: a tiny silent WAV file — 0.1 seconds of 44.1 kHz, 16-bit mono silence, about 8.8 KB, written once to a temp directory and reused. It's built by hand, byte by byte (RIFF header, fmt chunk, and a data chunk that's simply all zeros):

js
const buffer = Buffer.alloc(44 + dataSize);
buffer.write("RIFF", 0);
// ... fmt chunk: PCM, 1 channel, 44100 Hz, 16-bit ...
buffer.write("data", 36);
// remaining bytes are already zero — i.e. silence

Silence is the whole point: the temporary clip exists for only a fraction of a beat before it's deleted, but if anything ever went wrong and it did play, it would make no sound. Its only job is to be present at a position so Live's edge-trim behavior fires; its contents never matter.

The file's path is generated by the Node.js server when the device loads and threaded into every tool request as part of the request context (silenceWavPath), so the Live API side always knows where to find it. (For MIDI clips none of this is needed — create_midi_clip happily makes an empty clip of any length directly in the arrangement.)

A feature the API doesn't admit to

Both examples so far started from something the Live API tells you about. The most surprising refinement came from the opposite case — a capability the API doesn't advertise at all.

Every object in the Live API can describe itself: ask a track for its info and it reports its properties and functions. That self-description, plus Ableton's reference documentation, is the map almost every tool builds from. A track's map lists arm, mute, solo, its routing — but not input monitoring, the In / Auto / Off switch sitting on every track in Live's mixer. It's absent from the introspection dump and from the official documentation. By every signal the API gives you, there is simply no way to set it.

While chasing exactly that feature — which appeared not to exist — Producer Pal's development resorted to guessing plausible property names anyway. current_monitoring_state turned out to be real: read it and you get back a number (0 = In, 1 = Auto, 2 = Off); write it and the track's monitoring actually changes. It just isn't listed anywhere. That undocumented, un-introspectable property is now the monitoringState control on Producer Pal's update-track tool.

A thin wrapper could never have offered it, because a thin wrapper only knows what the API admits to. (And it's still missing from both the docs and the reflection today — a re-probe of a running Live Set while writing this page found the property works exactly as before while remaining invisible to introspection.)

A language for music, not just API calls

The three examples above are all about meeting the Live API where it is. The single largest investment in Producer Pal sits a level above the API entirely: the notation the AI actually composes in.

Asked to write MIDI directly, an LLM has to emit raw note data — pitch numbers and times in abstract beats — which is error-prone and unmusical. So Producer Pal gives it two purpose-built notations to think in instead:

  • bar|beat notation — a text-based music notation where time is counted the way musicians count it (1|1 = bar 1, beat 1), pitches are names (C3, F#4), and durations are note values (n/4, n/8), mapped onto exact positions in clips and the arrangement across any time signature.
  • Transforms — a small expression language for shaping notes and audio with math: LFO shapes, ramps, randomized ranges, and per-note or per-clip variation, where a single string can broadcast across many clips at once.

Both are full domain-specific languages with their own grammars and parsers — the kind of thing nobody builds for a thin wrapper. They're a big enough topic to deserve their own deep-dive here someday; for now, see the features page for more on both.

Why this matters

None of this — the bit math, the holding area, the generated silent WAV, the property Live never told us about — is visible when you use Producer Pal. You just ask for a split, or a color, and it happens. That's the point. Every one of these refinements exists so the AI meets a clean, predictable interface instead of the Live API's raw edges, and so you get capabilities a thin wrapper simply can't offer. It's the accumulated result of more than a year of smoothing rough edges, and it's most of what separates a genuinely usable tool from a quick API bridge.

For how the two engines underneath actually carry this work back and forth, see The Bridge.

Released under the GPL-3.0 License.