Changes to Bindings in 3695

Hey All,

I’ve just put up build 3695 which has some major internal changes to the way bindings are dispatched for load song and load state bindings.

The biggest change is that these operations now always block other MIDI bindings from triggering until the load is complete.

Consider two bindings like this:

What this is trying to do is use one MIDI event to invoke two actions - firstly to load a song from the set list and then to load a specific state (presumably in the newly loaded song).

Unfortunately, what happens in the current builds is both bindings will execute at the same time resulting in:

  1. The first binding starts a song load
  2. The second binding immediately starts a state load on the current song (not the song about to be loaded).
  3. Kaboom, because the second binding might be talking to a song that’s no longer around.

In build 3695 I’ve changed it so that the second binding won’t be invoked until the first one has finished - regardless of the Routing Mode setting on the binding.

So, you might be wondering what the point of the “Block until complete” routing mode is now…

Most of the time it’s no longer necessary. The one exception is when you want to send two MIDI events where the first is switching songs or states, and the second is to invoke a binding in the newly loaded song. In this case you need to set the first binding to blocking mode so the second MIDI event isn’t handled until the first is finished.

Putting it another way:

  • With these new changes MIDI events are immediately matched to the currently loaded set of bindings as they arrive. If multiple bindings match the bindings are queued and executed in order.

  • When a binding that has blocking mode is matched, the MIDI events are queued until the blocking binding has finished - after which any pending MIDI messages are then matched against the new set of bindings.

It’s a subtle difference but most of the time you shouldn’t need to think about it - just set the routing mode to Continue or Suppress as suits your needs. It’s just in this one special case as described where you might need the old blocking mode.

As mentioned this is a core change to the way Cantabile dispatches bindings. I’ve also tightened up the way the busy mode, UI reentrancy blocking and other related areas are handled. In other words, this build should be considered very experimental for now. If you’ve got time and you’re so inclined please give it a test and let me know if there’s any weirdness.



Thanks @brad ! I will be happy to test this, especially since I have been experiencing this issue. However, I’m not sure I understand the meaning of “suppress” in this example:

The menu item is titled, “Block until complete (and then suppress)”. What is being suppressed in this case? I had always thought this meant to not process any other bindings for this event, but now I think it must mean that the first binding will not be triggered again until all the the other bindings for the same event are processed. Is that correct?

Thank you,


Hi @dbrendon ,

There are two distinct use case here.

  1. Sending one MIDI event and triggering multiple actions
  2. Sending two MIDI events to trigger two actions (say a program change to load a song and then a CC to configure a plugin in the new song)

In case 2 you’d want the song load to finish before looking at the second event and deciding which bindings to invoke. That’s what blocking mode is used for.

In my original post I used both examples but wasn’t really clear about it. The first use case is your situation and is covered by the new automatic blocking behaviour. The second use case was what I meant in the example you quoted me from and is where you’d use the blocking mode.

The “Block until complete (and then suppress)” does this:

  1. Starts the invocation of the target action (eg: loading a song)
  2. Blocks and queues all further incoming MIDI events until the target action has completed - at which point it starts matching subsequent MIDI events against the new set of loaded bindings.
  3. Suppresses the original MIDI event (the one that caused the song load). It is neither matched to any subsequent bindings nor is it forwarded for regular song MIDI route processing.

Note that this means blocking mode can’t be used in use case 1 since it suppresses the event before it gets to subsequent bindings with the same source controller.

What’s not supported is sending one MIDI event and having it trigger both a song load and also a binding in the newly loaded song.


1 Like