Cantabile Solo and Cantabile Performer Only
Bindings let you control nearly all settings in Cantabile (and any loaded plugins) from an external MIDI device like a keyboard, control surface or drum pad. Cantabile supports many different MIDI controller events and many different controllable elements within Cantabile.
Cantabile Performer can supports "reverse bindings" where a setting inside Cantabile can be reflected to an external MIDI device so that whenever the setting changes an appropriate MIDI message is sent.
Note: "Bindings" is the new name for what was called "MIDI Assignments" in earlier versions of Cantabile
Bindings are edited using the Bindings tab in Cantabile's main window:
You can switch to this tab either with the mouse, or by pressing Ctrl+D or by using Ctrl+Tab/Ctrl+Shift+Tab.
Learning Binding Source
The easiest way to create a new binding is to let Cantabile "learn" it. Click the "New Binding" button and choose the "(learn)" option.
A window will appear that shows all incoming MIDI events. Move or press the controller that you want to bind and it should appear in the list. Double click the event you want to bind and a new binding with that source controller will be created.
You can then use the drop downs in the other columns to configure what it's bound to. The bindings editor supports undo/redo, copy/paste, and move up/down commands
Learning Binding Targets
The other way to create a binding is by right clicking on the target setting you want to bind to. For example to create a binding to the master gain setting, right click on it an choose Create Binding:
You'll then be prompted to move the control you want to bind to with the appropriate target binding point selected:
Learning Plugin Parameter Binding Targets
To create a learn a binding to plugin parameter, open the plugin's editor and choose Create Parameter Binding:
While the Learn Binding window is open you can move any setting in the plugin editor and the associated parameter will be selected in the Bind To drop down. Here the Amplifier Attack knob was turned resulting in the "A_Attack" parameter being selected:
Depending on the kind of binding (MIDI -> Setting, Setting -> MIDI, MIDI -> MIDI etc...) different columns in the bindings editor may or may not be applicable.
Here is a random selection of bindings that demonstrate some of the different ways bindings might appear.
The following describes each column:
- Activity Indicator
- The LED indicator lights up when the binding is active - ie: when its responding to changes from the source.
- Enabled Checkmark
- The check mark can be used to enable/disable the binding
- Delays and Scheduling
- The "stopwatch" button can be used to configure delays and scheduling for when the target side of the binding should be invoked. (Cantabile Performer v4 only). See below for more information on configuring these options.
- Test Button
- The "play" button can be used to invoke simple command based bindings (not available on all bindings)
- The source of binding event. This could be an external MIDI device or an internal object such as the "Master Levels"
- Source Channel/Property
- The second part of the source column is used to select MIDI Channel number for MIDI sources, or the source property or trigger event for object sources.
- Event Kind
- The MIDI event kind to monitor (see below for more)
- Event Controller
- Depending on the event kind, there might be an additional controller number setting. (eg: for MIDI CC events, this would be the CC number).
- A condition that can test an incoming value for a specific range of values and generate a true/false result. (see Binding Conditions below)
- The object to be controlled by the binding
- Target Channel/Property
- The second part of the target column is used to select the MIDI Channel for MIDI targets, or the target property for object targets.
- For MIDI targets, the MIDI event to send (CC, Pitch Change, Note etc...)
- Depending on the type of source and target objects this might be a value to value mapping, or other options that control how the binding works.
Jump Prevention and Rotary Encoder (Relative CC) Support
See Binding Jump Prevention and Relative (Rotary) Encoder Support
The condition column lets you create bindings that test a source numeric value (eg: a CC value, a gain level, a state index etc...) for a range of values and use the result to drive a target that expects a switch type value (on/off or true/false).
Bindings can test a value using a simple comparison:
or a range:
As an example, suppose your external controller had 4 LEDs that were mapped to CC's 20, 21, 22 and 23 and you wanted to light up one of the LEDs to show which song state is currently selected. The following set of bindings would achieve this.
- Each binding monitors the currently selected state index (see "Source" column)
- The state index is compared to the values 1, 2, 3 and 4 (see "Condition" column) resulting in a true/false value
- When the value changes (from true to false, or false to true), the target is invoked
- The target sends a MIDI CC value to the appropriate controller with the value 127 for on, or 0 for off. ("Action" and "Value" columns)
Conditions can be used to test any numeric source binding point and drive any switch or command type target binding point. When the target binding point is a command (something to be invoked as opposed to accepting a value), you can choose whether to invoke the binding when the values becomes true, or when it becomes false using the drop down in the "Value" column
Bindings have a routing mode that determines how processing proceeds after the binding has been matched to an incoming event:
- The original event continues to be routed as if the binding didn't exist.
- The original event is suppressed. Subsequent bindings and other MIDI targets won't receive the event. This mode is useful when binding specific notes to action (eg: binding the lowest key on your keyboard to move to the next song)
- Block Until Complete
- The target of the event is invoked, and all incoming MIDI on the same MIDI port is queued for processing until target action has completed. This mode is useful when binding to slow actions where you want to make sure the action has completed before sending subsequent events. (eg: loading a song and then sending configuration events).
To set the routing mode of a binding right click on the binding and choose the routing mode from the menu.
Note: some binding targets support immediate and delayed versions of the same action. eg: "Set List -> Load Next Song (Delayed)" and "Set List -> Load Next Song (Instant)". The blocked routing mode doesn't work on the delayed versions of these actions as incoming MIDI will only be blocked and queued until the delayed load has been initiated, not completed.
Delays and Scheduling (Cantabile Performer 4)
In Cantabile Performer you can configure a delay between when a binding is triggered and when the target side of the binding is actually invoked.
The "before delay" is a delay between the time of the triggering event and the time the target side of the binding is invoked.
The "after delay" is a second delay that will be introduced between the time this binding is invoked and the next delayable binding is invoked. If there are no other delayable bindings after this one then this setting has no effect.
Bindings can be scheduled in several different groups within which the delay timings are calculated relative to each other.
ie: the pre-delay causes a delay between the last currently pending binding in the group and the post-delay causes a delay between this binding and any other subsequent bindings in the same group. For example, suppose you had two bindings each with a 500ms pre and post delay. If these were configured in the same group and they were triggered at the same time, they would be invoked as follows:
- in 500 milliseconds the first binding would trigger (500ms pre-delay on the first binding)
- in 1500 milliseconds the second binding would trigger (500ms pre-delay on the first binding + 500ms post-delay on the first binding + 500ms pre-delay on the second binding)
A third binding the the same group with a pre-delay of 0 would trigger at 2000 milliseconds (because of the 500ms post-delay on the second binding).
A bindings delay group is set using the "Schedule this binding's delays with" drop down.
- Nothing - only the pre-delay is used and is scheduled from the time the binding is invoked. This is a simple delay unaffected by other bindings.
- Globally scheduled bindings - all bindings in all racks and songs with this group selected will be scheduled relative to each other.
- Other bindings in this song or rack - all bindings in the same rack or song with this group selected will be scheduled relative to each other.
- Other bindings invoked by the same trigger - all bindings invokes by the same triggering event will be scheduled relative to each other.
The last "same trigger" option is only available on trigger bindings such as Song - On Load.
The "Block Other Operations Until Complete" option specifies what happens if certain major operations occur (such as song or state switch, engine shutdown etc...) while the binding is in the pre-delay period:
- When enabled, the operation will block until the binding has fired.
- When disabled, the binding will be canceled and wont fire.
For example suppose you have a binding configured to fire 10 seconds after a song loads. Then suppose you load the song and then immediately switch to another song (before the 10 second time out). If the binding is configured as blocking then Cantabile will block the song switch until the 10 second time expires, the binding will then be invoked and then the new song will be invoked. If the binding is configured as non-blocking the delayed action will be canceled and the song switch will happen immediately.
By default bindings are marked as blocking. If it's not important that the binding be reliably invoked then marking the binding as "non-blocking" will allow for faster song and state switching because the engine doesn't need to wait for the bindings to fire.
Cantabile Performer Only.
A binding can generate sys-ex data if the target is a MIDI port and the event kind is set to "SyeEx". For details on setting up sys-ex bindings, see the Sys-ex Expression reference.
Often you will want to configure bindings that work across all songs.
eg: it doesn't make much sense to create a binding in a song to load the next song in a set list since you'd need to create an identical binding in all songs for it work correctly.
For this reason, Cantabile has a "Background Rack" - a special rack that is always running in the background and whose primary purpose is for global bindings.
To create global bindings:
- From the View menu, choose "Background Rack"
- Switch to its Binding tab
- Create bindings as per any other rack
Note that not all binding targets are available from the background rack. eg: you can bind to a specific plugin in a song because that song might not be loaded when the binding is invoked.
Song, Rack and Background Rack Bindings
Each song and rack has it's own set of bindings and bindings are processed in the following order:
- Song bindings
- Bindings in racks loaded into the active song, in the order the racks are in the song
- All other rack’s bindings (except the background rack) but in an undefined order
- The Background rack’s bindings
The most important part of all this is that the Song bindings take precedence over the Background rack bindings.
Let’s say you have a button on an external controller that for all your songs you want it to perform some function. You could create a binding for that action in the background rack.
Now let’s say for that for one particular song you want to change that button to perform some other action. If you create that binding in the song and set its routing mode to suppress — the song’s binding will take precedence over the background rack bindings and effectively override it.
Special Event Kinds
Most event kinds are self explanatory as they simply reflect the associated MIDI event. For MIDI Continuous Controller events (CC's) however there are a couple of different ways they can be used - depending mostly on the type of physical control they're originating from:
To explain some of these:
- This is a normal MIDI CC event that can be assigned to a variable value (eg: a gain level)
- Controller (Fine)
- These bindings combine MIDI CC 0-31 with 32-63 to create a more precise 14 bit controller.
- Controller (Button)
- A momentary MIDI button that sends a value > 64 when pressed and < 64 when released. This kind of binding is edge-triggered in that it invokes the target when the value crosses from less that 64 to greater than 64.
- Controller (No Edge Button)
- Use this for MIDI buttons that send a non-zero value when pressed and no event or a CC value of 0 when released. ie: it triggers on any non-zero value.
- Controller (Switch)
- This is for non-momentary on/off MIDI buttons and switches that send a value >=64 when on and <64 when off.
Bindings to Routes
Unlike most other objects, routes do not automatically appear as assignable objects in the Bindings editor. This is because by default routes don't have a name and therefore can't be referenced.
To create an binding to an audio or MIDI route:
- Select the route in Cantabile's main window
- From the Edit menu choose "Rename", or press F2
- Type a unique name for the route and press OK
- Though the name won't show in the main window, the new name will appear in the Bindings
- From the bindings editor you'll now be able to create bindings for the route
All routes support binding to the enabled/disabled setting. Audio routes also support bindings to the route's audio gain level.
Cantabile Performer supports bi-directional bindings that establish as two way binding between the binding's source and target. Bi-directional bindings are generally used when binding from a motorized MIDI controller, or from a MIDI controller (knob) with an LED ring to provide feedback to the controller on the current state of the controller.
Bi-directional bindings have certain limitations, including:
- The source must be a MIDI source (ie: a MIDI input port)
- The source and target objects must have the same (or similar, see below) name
- The target must not be a MIDI target
- Not all MIDI event types are supported. Specifically, events that trigger an action (eg: Controller - Button) are not supported.
- The source side of the binding must have a specific channel selected (ie: Omni channel bindings aren't supported)
If the binding is configured as bi-directional, but the reverse binding can't be created due to one of the above reasons, an error message explaining the reason will be displayed when attempting to enable the bi-directional mode. The reason will also be displayed in the tooltip of the bi-directional binding button.
To enable bi-directional mode on a binding either:
- Right click on the binding and select the bi-directional mode from the menu, or
- Click on the bi-directional indicator button (shown below) to cycle through the various
Bi-directional bindings are typicall used is as follows:
- Go to Options -> MIDI Ports
- Make sure there is both a MIDI Input and MIDI Output port for the target device with the same (or similar, see below) names
- Create a binding from the MIDI Input device's CC number to the target value to be controlled
- Set the bi-directional mode - half for motorized faders, or full for LED rings
Bi-Directional Binding Mdoes
Bindings can be configured as either "disabled", "half" or "full" bi-directional:
- Disabled - the binding operates in forward (source -> target) direction only.
- Half Mode - the reverse binding is suppressed when the forward binding is changing the target value. This can be used with motorized faders if the fader jitters or doesn't move smoothly due to feedback from the reverse binding.
- Full Mode - the reverse binding is always active and is typically used with LED rings.
Bi-Directional Bindings and Similar Object Names
As mentioned above, the source and target objects of a bindings must be "similar" for bi-directional bindings to work. To find a similarly named object Cantabile uses the source object name with the following whole word, case sensitive replacements:
- "in" -> "out"
- "In" -> "Out"
- "IN" -> "OUT"
- "input" -> "output"
- "Input" -> "Output"
- "INPUT" -> "OUTPUT"
This allows for bi-diriectional bindings between port names like "Rack MIDI In" and "Rack MIDI Out"