Vibe hacking Ableton’s Push 3
When Ableton shipped Push 3 in 2023, they delivered a standalone instrument: new buttons, encoders, a colour display. What they did not ship was a spec.
Push 2 had the Push 2 MIDI and Display Interface Manual — LEDs, pixel formats, the lot. Push 3 got silence. So we did the obvious stubborn thing: opened a MIDI monitor and poked the hardware.
This is how we reverse-engineered it, added support to push2-python, and why that kind of work still matters if you care about hardware you can actually extend.
The documentation desert
Push 3 is a $2,000 instrument. Sixty-four velocity-sensitive pads, a 960×160 colour display, MPE, deep MIDI. If you want a custom controller, a live visualisation, a MIDI processor, or a teaching tool, you are on your own. Every interaction is a guess until it isn’t.
We rebuilt the protocol from a monitor log. Along the way: why two buttons share a CC, how the dual MIDI ports actually split, and why the display format is more annoying than it looks.
USB detection and Linux permissions
USB devices identify themselves with a vendor ID and a product ID. Ableton is 0x2982. Push 2 is 0x1967; Push 3 is 0x1969. Try 3 first, then fall back:
1 2 3 4 5 6 7 8 9 | |
On Linux the kernel often claims the interface at boot, which locks out user space. You have to detach it:
1 2 3 | |
macOS and Windows use driver models that do not need this. You learn that by failing on a Linux box first.
Two ports, two purposes
Push 3 exposes two MIDI ports over USB: User and Live.
Full LED control — pads and buttons lighting the way you asked — needs the User Port. Live is what Ableton Live attaches to, and it appears to withhold LED access on purpose so the DAW and a user program do not fight.
Standalone tools should try User, then degrade to Live.
The names are a mess, and they differ by OS. Python reports macOS as Darwin:
- macOS: “Ableton Push 3 User Port” / “Ableton Push 3 Live Port”
- Windows: “MIDIIN2 (Ableton Push 3)” / “Ableton Push 3”
- Linux (ALSA): numeric suffixes (
:1User,:0Live)
1 2 3 4 5 6 7 8 9 10 | |
MIDI detective work
Without a spec, this is archaeology.
Control Change messages use controller numbers 0–127, each with a value 0–127. Some CCs are standardised (mod wheel, sustain); the rest are whoever built the box. Note On / Note Off carry a note number and a velocity.
We logged the raw stream, then pressed everything:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Some mappings were boring in a good way. Add is CC 32. Swap is CC 33. Session, Save, Capture, Sets, Learn, Lock, New — each has a number.
Then it got weird.
The jog wheel shares a brain
CC 88 does two jobs.
Duplicate sends CC 88 with 127 on press and 0 on release. Jog-wheel rotation also sends CC 88: 1 for counter-clockwise, 65 for clockwise.
Same controller number, different meaning. The only tell is the value:
1 2 3 4 5 6 7 8 | |
Why? No idea. A manual would have said.
Touch and click are different
The D-Pad centre is touch-sensitive. Touching it sends Note 13. Clicking it sends CC 91. One piece of plastic, two MIDI types:
1 2 3 4 5 | |
If you only click, you never see the note. If you only graze it, you never see the CC.
Display hacking: BGR565 and frame rates
The display wants BGR565: sixteen bits per pixel, red and blue swapped relative to the RGB565 everyone else uses.
Send RGB565 and reds come out blue. A Python loop per pixel will not keep up, so we vectorized it:
1 2 3 4 5 6 7 | |
For video we skip Python. FFmpeg emits BGR565 directly, hardware-accelerated through VideoToolbox on macOS. Frames arrive as raw bytes, wrap in NumPy with no copy, and go straight to the display.
Result: 60 fps video on a MIDI controller.
Velocity to colour: 127 shades
Pads have 127 colours, one per velocity.
HSV is easier to aim than RGB: hue is the colour, saturation the intensity, value the brightness. Hue runs 0–0.85 so it does not wrap back to red; saturation stays maxed; brightness starts at 0.3 so a ghosted hit still reads:
1 2 3 4 5 6 7 | |
Every strike gets a colour tied to how hard you hit it.
Why this matters
The hardware already does these things. The missing piece was the map:
- Custom controllers and workflows
- Real-time visualisations
- MIDI processors and effects
- Teaching and experimental tools
- Talking to other hardware and software
Push 3 is a capable instrument. Writing the protocol down lowers the cost of the next person doing something Ableton did not design for.
The code is in push2-python. Push 3 support works. The process also made the obvious point: with a real manual, more people would have shipped more things, with fewer late nights on CC 88.
The tools are there. What you build with them is the interesting part.
Comments