# Driver for Ableton Push 1 - First Steps

**URL:** <https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166>\
**Category:** Software\
**Created:** [August 30, 2025, 9:17pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166 "2025-08-30T21:17:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![brumby](https://discourse.zynthian.org/letter_avatar_proxy/v4/letter/b/76d3ee/32.png) [@brumby](https://discourse.zynthian.org/u/brumby)\
**Post date:** [August 30, 2025, 9:17pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/1 "2025-08-30T21:17:27Z")

</div>

Hello Everybody,

I’m new with Zynthian and I am very happy with it. I want to thank you for that wonderful work.  
Its some early to anounce it, but I am working on a driver for the Ableton Push 1.

I bought the Push1 some days ago, because I hoped to use it in scale mode. But it seems to me with no own intelligence to use it as hardware keyboard. When I started, just the display was lit with a short text and no key was lit.  
So I’m fiddled around with it and began to hack together a driver for it.

Gui seems completely usable with knob1-knob3 like a “real” Zynthian Box. So I understood the importance of having real control knobs and not only a touchscreen.

I copied parts from “novation launchpad mk3 driver” to my driver controlling the sequencer seems possible though I lack understanding the complete conzept of it

I got the display working, which cost me so far the most work to understand.

Would the driver in a later state be interesting for the Zynthian project or is my work just for my personal delight in learning the inner concepts of Zynthian?

Whatever, thanks again for this big comunity work.

Brumby

 ![Ableton_push1_with_Zynthian-Driver](https://discourse.zynthian.org/uploads/default/original/2X/1/1a9c9df0e5fd7939cd63584a10aed285c0af2641.jpeg)

---

<div class="post-metadata">

**Author:** ![tunagenes](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/tunagenes/32/7279_2.png) [@tunagenes](https://discourse.zynthian.org/u/tunagenes)\
**Post date:** [August 31, 2025, 4:01am UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/2 "2025-08-31T04:01:03Z")

</div>

> [@brumby](#):
>
> Would the driver in a later state be interesting for the Zynthian project or is my work just for my personal delight in learning the inner concepts of Zynthian?

Welcome. Although I don’t speak for the project, I’m almost certain that we would welcome your driver and happily accept a pull request to make it part of the standard Zynthian package.

And kudos on getting the display working in your driver!

---

<div class="post-metadata">

**Author:** ![jofemodo](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/jofemodo/32/2_2.png) [@jofemodo](https://discourse.zynthian.org/u/jofemodo)\
**Post date:** [September 1, 2025, 2:45pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/3 "2025-09-01T14:45:03Z")

</div>

Hi @brumby !

Thanks for your kind words and congrats for your work with the new driver!

> [@brumby](#):
>
> Would the driver in a later state be interesting for the Zynthian project or is my work just for my personal delight in learning the inner concepts of Zynthian?

Of course, we will be pleased to include the ableton-push driver in the official repositories. Simply make a PR when you feel the driver is ready.

Thanks!

---

<div class="post-metadata">

**Author:** ![3tree](https://discourse.zynthian.org/letter_avatar_proxy/v4/letter/3/e5b9ba/32.png) [@3tree](https://discourse.zynthian.org/u/3tree)\
**Post date:** [September 4, 2025, 11:52am UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/4 "2025-09-04T11:52:55Z")

</div>

Hi @brumby great work! Selfish question one, do you have any idea whether it should work for the push 2 as well?

---

<div class="post-metadata">

**Author:** ![brumby](https://discourse.zynthian.org/letter_avatar_proxy/v4/letter/b/76d3ee/32.png) [@brumby](https://discourse.zynthian.org/u/brumby)\
**Post date:** [September 4, 2025, 1:16pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/5 "2025-09-04T13:16:03Z")

</div>

Hi @tunagenes

No, so far the driver only for the push 1 which was produced by akai for ableton.

Push 2 and 3 are produced by ableton themself, so I think the midi\_events are not the same to Push 1 devices.  
But: It shoudnt be very difficult to port the driver to Push2 because the concepts of pushs and launchpad are the same.

there are three things to evaluate:

- the midi event a key, pad or knob sends to the zynthian
- the midi events that zynthian has to be send to the device to control the LEDs
- the midi events that zynthian has to send to control the display  
going down this line step by step will give a workable driver. I found a github repository where informations for controlling Push 2 are collected.

For me, without a Push 2 it would be too time consuming / too hard to implement that without echo from a Push 2 device.

if you have little python skills, you could adapt the midi-events to control the zynthian UI very easily. If that helps it would be a first start for you.

---

<div class="post-metadata">

**Author:** ![brumby](https://discourse.zynthian.org/letter_avatar_proxy/v4/letter/b/76d3ee/32.png) [@brumby](https://discourse.zynthian.org/u/brumby)\
**Post date:** [September 11, 2025, 1:58pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/6 "2025-09-11T13:58:02Z")

</div>

So now I got into a problem:  
As I understand the function: def midi\_event(self, ev) should control with its return statement (True or False) if an event is further processed.

Is this the intended way? If so I screwed up my sources…

When my driver is loaded every event is canceled out, so you can’t play on the keyboard anymore.

1. ) What do I have to do, to let the event further be processed?

2.) How is it possible to translate an event in the driver to translate the midi\_note event for a scales extension my pad.

I searched, but didn’t find any advise. The Wiki on how to program a driver is in an early state…

---

<div class="post-metadata">

**Author:** ![tunagenes](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/tunagenes/32/7279_2.png) [@tunagenes](https://discourse.zynthian.org/u/tunagenes)\
**Post date:** [September 11, 2025, 2:42pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/7 "2025-09-11T14:42:06Z")

</div>

I don’t know the answers to your specific questions, and hopefully you’ll get them from others.

I’m wondering if you’ve seen @oscaracena ‘s driver as a working example:

> [@Akai APC Key25 mk2 driver](https://discourse.zynthian.org/t/akai-apc-key25-mk2-driver/9082):
>
> Hi Zynthianers! As some of you know, I’m working on a driver for the APC Key25. It’s being a very fun quest, and I’m enjoying it a lot! nerd_face The support for Zynmixer and Zynpad is already there, and also a second mode to handle the UI. I’m currently implementing a third mode, something like a step sequencer to work with the Zynpad + Pattern Editor. It’s still in a very early stage, but I would like to share a taste of it with you. Hope someone will find it useful, and any feedback/sugge…

---

<div class="post-metadata">

**Author:** ![brumby](https://discourse.zynthian.org/letter_avatar_proxy/v4/letter/b/76d3ee/32.png) [@brumby](https://discourse.zynthian.org/u/brumby)\
**Post date:** [September 11, 2025, 3:56pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/8 "2025-09-11T15:56:59Z")

</div>

Thank you. I found it. This driver is a wonderful work.  
I learned a lot from it.

I’m not sure, if you can use APC Key25s keyboard with this driver. It might be, you can use it also just as a controller for the GUI. If somebody uses this device it would be helpful to know if the keyboard as playing device is working.

---

<div class="post-metadata">

**Author:** ![niels](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/niels/32/5005_2.png) [@niels](https://discourse.zynthian.org/u/niels)\
**Post date:** [September 11, 2025, 8:28pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/9 "2025-09-11T20:28:11Z")

</div>

The reason the driver for APC Key 25 **mkII** works so nicely re. the keyboard (and sustain), is that the device is actually two devices. So the driver just works on the first device, and the second is left alone (except that some notes are **also** listened to from within the driver in order to get the StepSeq submode to work (assigning notes to pads, which can in turn be used to create patterns).

Now I am working on porting (by subclassing) that driver to its predecessor, which is just listed as a single device, with the keybed and sustain over MIDI channel 1 (zero based), and the rest over MIDI channel 0, so there I am encountering kind of the same challenges.

There is this class property (if that is correct Python parlance):

`unroute_from_chains = False`

This will leave all normal Zynthian plumbing intact. This in turn is **is not** interceptible however: when I e.g. set a breakpoint in midi\_event, the note will sound before.

And when you set it to `True`, I do not see a way to still let it be processed. It looks like you said, that returning `False` (or `True`) from the driver that it will be processed, but I just tried both, and I notice no difference.

What I am now doing is sending all channel 1 events directly to libseq, see below. It does not have any fancy handling for when a note on is sent, and then the chain switches (so no note off ever arrives) (and I don’t know yet how to get the last ‘MIDI playable’ chain (e.g. if you are on an instrument chain and then switch to an Audio chain, the last chain normally still receives the events). And this also does not reach live pattern recording. So this is all quite suboptimal, so having something like you described (return value from midi\_event dictating whether we **do** want subsequent processing or not) would be ideal\*.

```python
# Direct keybed to chains
if (channel == 1):
    chain = self.chain_manager.get_active_chain()
    # print(chain.midi_chan)
    # @todo: find out how to get 'last' active chain, for now: just back out.
    if chain.midi_chan is None:
        return
    status = (ev[0] & 0xF0) | chain.midi_chan
    self.zynseq.libseq.sendMidiCommand(status, ev[1], ev[2])
    return

return super()._on_midi_event(ev)`

```

\*For my case, what would also work is if we could declaratively ‘unroute’ only a certain channel.

---

<div class="post-metadata">

**Author:** ![jofemodo](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/jofemodo/32/2_2.png) [@jofemodo](https://discourse.zynthian.org/u/jofemodo)\
**Post date:** [September 12, 2025, 11:11am UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/10 "2025-09-12T11:11:35Z")

</div>

> [@niels](#):
>
> \*For my case, what would also work is if we could declaratively ‘unroute’ only a certain channel.

We could consider this “feature” 😉

---

<div class="post-metadata">

**Author:** ![niels](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/niels/32/5005_2.png) [@niels](https://discourse.zynthian.org/u/niels)\
**Post date:** [September 12, 2025, 3:04pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/11 "2025-09-12T15:04:07Z")

</div>

May very well do so, but could you also shed some light on the meaning (if any) of the return value of driverClass.midi\_event()?

---

<div class="post-metadata">

**Author:** ![brumby](https://discourse.zynthian.org/letter_avatar_proxy/v4/letter/b/76d3ee/32.png) [@brumby](https://discourse.zynthian.org/u/brumby)\
**Post date:** [September 12, 2025, 4:34pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/12 "2025-09-12T16:34:42Z")

</div>

> [@niels](#):
>
> ```auto
> chain = self.chain_manager.get_active_chain()
> # print(chain.midi_chan)
> # @todo: find out how to get 'last' active chain, for now: just back out.
> if chain.midi_chan is None:
> return
> status = (ev[0] & 0xF0) | chain.midi_chan
> self.zynseq.libseq.sendMidiCommand(status, ev[1], ev[2])
> 
> ```

@Niels: Thank you, that was very helpful.

I got Push 1 working now as a Controller for zynpad and GUI and aditional as a 3-dimensional Keyboard with changeable scales.

---

<div class="post-metadata">

**Author:** ![tunagenes](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/tunagenes/32/7279_2.png) [@tunagenes](https://discourse.zynthian.org/u/tunagenes)\
**Post date:** [September 12, 2025, 4:47pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/13 "2025-09-12T16:47:27Z")

</div>

> [@brumby](#):
>
> 3-dimensional Keyboard with changeable scales

Congratulations! Could you expand-explain a bit more what you mean please?

---

<div class="post-metadata">

**Author:** ![brumby](https://discourse.zynthian.org/letter_avatar_proxy/v4/letter/b/76d3ee/32.png) [@brumby](https://discourse.zynthian.org/u/brumby)\
**Post date:** [September 12, 2025, 5:21pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/14 "2025-09-12T17:21:20Z")

</div>

![Push 1 in Major mode - 9bed0c94-48d3-45b5-8c47-e7ce5737a4aa](https://discourse.zynthian.org/uploads/default/original/2X/3/3dbd96349ab5fa5d1c64c87831acce84cc0c8b03.jpeg)

Sorry, my fault, I mean 2-dimensional.  
I mean this style of setup like in the photo. I knew it from launchpad.  
Every blue key is tonic from the choosen scale, up and downwards is a fourth, to the left and the right next tone in scale.

I also experimented with an isomorphic setup in Wicky-Hayden Style which looks very promissing for me. But there are buttons missing for complete Wicky-Hayden-Setup.

I am very bad piano player, so I am messing around with different keyboard styles, to see if one fits better to me.

---

<div class="post-metadata">

**Author:** ![tunagenes](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/tunagenes/32/7279_2.png) [@tunagenes](https://discourse.zynthian.org/u/tunagenes)\
**Post date:** [September 12, 2025, 8:06pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/15 "2025-09-12T20:06:57Z")

</div>

No worries, I had fun thinking about what 3d could mean, for example a sphere made out of circle of fifths - but that’s a whole nother thread.

If you’re string-fretboard oriented you might consider Linnstrument, it does cost \>$1000 though. I guess you could adapt Push driver to it if you were so inclined. I would like to build-use Wicky-Hayden too.

---

<div class="post-metadata">

**Author:** ![brumby](https://discourse.zynthian.org/letter_avatar_proxy/v4/letter/b/76d3ee/32.png) [@brumby](https://discourse.zynthian.org/u/brumby)\
**Post date:** [September 21, 2025, 9:50am UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/16 "2025-09-21T09:50:08Z")

</div>

Hello everybody

@tunagenes 🙂 Yes, I think I did that.

I did a pull request with:

- keystation pro mk1 driver
- ctrldev\_base\_scale
- ableteon push 1 driver

I’m not sure if I didn’t make that wrong:  
I got this message:  
**Merging is blocked**

- You’re not authorized to push to this branch. Visit [https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches](https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches) for more information.

---

<div class="post-metadata">

**Author:** ![tunagenes](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/tunagenes/32/7279_2.png) [@tunagenes](https://discourse.zynthian.org/u/tunagenes)\
**Post date:** [September 21, 2025, 12:37pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/17 "2025-09-21T12:37:01Z")

</div>

Did you see the instructions in the wiki:

> **[Ctrldev - ZynthianWiki](https://wiki.zynthian.org/index.php/Ctrldev)**

I think the key point is: “which is what you should have forked” - did you do that?

with the overall process described here:

> **[Zynthian Development - ZynthianWiki](https://wiki.zynthian.org/index.php/Zynthian_Development)**

If so we might need to actually see the steps you did leading up to the pull request.

---

<div class="post-metadata">

**Author:** ![niels](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/niels/32/5005_2.png) [@niels](https://discourse.zynthian.org/u/niels)\
**Post date:** [September 21, 2025, 3:13pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/18 "2025-09-21T15:13:05Z")

</div>

Okay @jofemodo , first I thought the use case might be too narrow for such a request, but now I came up with a second one, so here’s your feature request after all:

> <https://github.com/zynthian/zynthian-issue-tracking/issues/1473>
>
> \# Describe the issue
> 
> Ctrldev drivers currently either unroute MIDI events from …the regular Zynthian flow, or let the regular Zynthian flow go through, with no way to stop it.
> 
> For the Akai APC Key 25 (mk 1), this poses a problem: the keyboard is in the same device, but in another MIDI channel as the pads, buttons and knobs. We want the keyboard to just do its regular thing, i.e. play notes to the current chain, be susceptible to MIDI recording and live pattern recording etc. I kinda have playing notes to current chain under control, but the rest seems unwieldy, if not impossible.
> 
> Unrouting only some channels declaratively could help with this. Channel 1 could go through, while channel 0 would be unrouted.
> 
> In other drivers this may also be helpful. Think of Korg nanoPad2, where each pad is programmable re channel/note/cc/pc, and you might want one scene to control the interface, and another e.g. to play notes, call up snapshots with PC or whatever.
> 
> See also https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/10
> 
> Another, finer grained, but probably slower, solution could be to let the return value of \`.midi\_event()\` dictate whether the MIDI signal should be routed or not. Because that would need refactoring, the return value could be fed to an instance-provided method, e.g. \`.unroute(val)\` that returns True (default) if it should be unrouted.
> 
> \# To Reproduce
> n/a
> \# Configuration
> n/a
> \## Hardware
> \`\`\`
> Raspberry Pi 5 Model B Rev 1.0
> Audio: ZynADAC
> Display: ZynScreen 3.5 (v1)
> Wiring: MCP23017\_ZynScreen
> I2C: MCP23017@0x20
> Profile: v4\_studio
> \`\`\`
> \## System
> \`\`\`
> Debian GNU/Linux 12 (bookworm)
> Build Date: 2024-10-02
> Memory: 76% (3083M/4049M)
> Internal Storage: 29% (17G/59G ext4)
> Temperature: 46.1ºC
> Overclock: Medium
> \`\`\`
> \## MIDI & UI
> \`\`\`
> Tuning: 440 Hz
> Master Channel: Off
> Preload Presets: Off
> ZS3 (SubSnapShots): On
> Power Save: 10 minutes
> Audio Levels on Snapshots: On
> \`\`\`
> \## Software
> \`\`\`
> zyncoder: vangelis (f4fed76) 
> zynthian-ui: ft-akai-apckey25-mk1 (143cc0b)
> zynthian-sys: vangelis (e3ed2f4)
> zynthian-data: vangelis (6ac209e)
> zynthian-webconf: vangelis (f070940)
> \`\`\`

---

<div class="post-metadata">

**Author:** ![jofemodo](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/jofemodo/32/2_2.png) [@jofemodo](https://discourse.zynthian.org/u/jofemodo)\
**Post date:** [September 21, 2025, 3:27pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/19 "2025-09-21T15:27:14Z")

</div>

Hi @brumby !  
Please, remove the not related files from your pull request:

```
launch.json
zynthian.sh
zyngine/zynthian_state_manager.py

```

Thanks!

---

<div class="post-metadata">

**Author:** ![jofemodo](https://discourse.zynthian.org/user_avatar/discourse.zynthian.org/jofemodo/32/2_2.png) [@jofemodo](https://discourse.zynthian.org/u/jofemodo)\
**Post date:** [September 21, 2025, 3:47pm UTC](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166/20 "2025-09-21T15:47:22Z")

</div>

Hi @brumby!

I see you are sending MIDI events (notes) from the driver. This is a bad idea and it’s not going to integrate very well with the rest of zynthian stack:

- First, latency and jitter will be horrible. The reason is that python ctrldev drivers don’t process the MIDI stream in real-time. Ctrldev driver code is executed out of the super-strict jackd real-time process, so you are in the wild and the latency and jitter is going to depend of the CPU load.

- Second, the events you send are losing the “device origin”. I mean, this events will reach all chains, ignoring the checked/unchecked MID-IN devices.

I would suggest you move your “scales” code to a LV2 plugin that can be executed in real-time. Indeed, we could consider to define LV2 ctrldev drivers that could be inserted between the device and the zynthian router. This would be very powerful, but we need to have a well-defined API for this.

Cheers,

[Next page](https://discourse.zynthian.org/t/driver-for-ableton-push-1-first-steps/12166.md?page=2)
