Driver for Ableton Push 1 - First Steps

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

6 Likes

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!

3 Likes

Hi @brumby !

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

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!

3 Likes

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

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.

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…

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:

1 Like

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.

1 Like

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*.

# 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.

2 Likes

We could consider this “feature” :wink:

1 Like

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()?

@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.

1 Like

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

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.

1 Like

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.

Hello everybody

@tunagenes :slight_smile: 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

Did you see the instructions in the wiki:

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

with the overall process described here:

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

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:

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

launch.json
zynthian.sh
zyngine/zynthian_state_manager.py

Thanks!

1 Like

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,

2 Likes