I have recently attempted to construct a “state controller” for my FCB1010 foot controller and thought I would document the issues I had during the development. I am doing this purely because I am keen to see Cantabile do well. I love using Cantabile and it forms the core of my live performance set up.
My Set Up
I play Guitar and keys.
Keyboard controller Nektar Impact LX61.
Foot Controller Behringer FCB1010 with a Eureka Prom 3 chip in IO mode. Laptop HP Twin Core i7
Sound Card Focusrite Scarlet 2i4 2nd generation
I primarily use the FCB1010 for controlling Guitar Rig 5/BIAS FX VSTs. I do also use it for stepping through song states for some tracks.
I use buttons 1 – 5 as Stomp Box controllers, pressing once for on and once for off and each button operates independently of the rest.
I use buttons 6 – 10 as program settings so only one button can be “active” at a time.
I use the UP/Down buttons to increment/decrement a “Bank number” so bank 1 allows buttons 6-10 to indicate program 1-5 and bank 2 to indicate programs 6-10 and so on.
I use the numeric LED display to indicate current Bank Number.
None of this logic is performed by the FCB1010. All it does is send CCs on button press/release or pedal movement and it will receive CCs with values to turn LEDs on and off
The Eureka Prom chip enables two way comms with the host:
So the challenge was to get cantabile to integrate with this controller according to my requirements above.
FCB 1010 Midi Output Map
Pedals 1 to 10 on press send CC104 with a values 1 to 10
Pedals 1 to 10 on release send CC105 values 1 to 10
FCB1010 Midi Input Map
Pedal LED 1 to 10 on CC106 values 1 to 10
Pedal LED 1 to 10 off CC107 values 1 to 10
There is an LED number display that can be controlled by CC values. I used this to display the Bank number controlled from the Up and Down Pedals.
Design and Build
I created an FCB Control Rack in the Background Rack to process CCs to and from the FCB1010 and to forward control messages to a Guitar Rack containing Guitar Rig and Bias plugins. I also output information to Onscreen Keyboard button to see what Bank Button and Program Number were being produced during development.
Problem 1 - Binding Targets
An obvious solution for the effects pedals (buttons 1-5) was to set up a rack for each button with two states (on and Off) using bindings on Rack State Load to send FCB LED on/off CCs and Guitar Effect CCs on the appropriate rack state change.
So now I wanted to set up a binding to toggle the rack state (on/off) from an incoming FCB1010 CC104 value 1 (footswitch 1 – see Midi Output Map above) but bindings won’t allow a CC value to be set up as a Target (Remember the footswitches all send the same CC104 but different values).
So I had to set up a Controller Map midi filter to convert each incoming CC and value to a different CC. For example CC104 value 1 = CC1, CC104 value 2 = CC2 etc.
Problem 2 – Controller Map midi Filter
When setting up the filter I wanted to add a line in the filter for each of the 5 pedals but got in a mess with this because I couldn’t get the second line to work. I think this was something to do with the Out of Range options causing the data not to be passed on to the next filter line. In fact I couldn’t understand the Out of Range filter options at all for the context of what i was trying to do but found a reference in the documentation somewhere that implied it is for slider or knob processing.
As a workaround I had to set up separate midi routes for each button on the controller with a single filter line in each.
Problem 3 – Initialisation Process
I wanted to set up an initial state of Bank 1 and Program 1 which is easy to do from Rack load. This meant sending 8 LED CC instructions plus a Bank number to the FCB1010.
I thought it would be more efficient to send these CC messages in a single text stream so tried to find a way of doing this. All I could find was a Sysex target in a binding which attached the sysex F0 F7 around my text. The FCB1010 can’t process sysex so I tried adding a filter to remove the F0 F7 which I believe is when I kept getting the crashes you saw. In the end, I thought this was too messy so ended up with individual bindings for each LED.
At one stage during this stage of development I was thinking I’d like to see a binding for “On start Up” or “engine Start” for initialisation processes but can’t remember the detail of that one right now but it’s classic program start up stuff where you want to initialise program variables etc (ah, the “variable” word, more of that later J ).
Problem 4 – Binding Program Change Value
I can’t remember the exact details of why I wanted to do this but was trying to set up a binding with a specific program number on a binding Target for an event happening on a midi route but you don’t allow program values to be entered if the source for a binding is a midi route. I assume that’s because you have a CC to Program midi filter for that.
Problem 5 – Bank No (No access to variables)
I needed the concept of a global variable that gave me Bank Number. I needed to add or subtract 1 from the Bank Number each time the Up/Down pedals were pressed.
Bank number would be used as input to the Button Bank midi filter (thanks for that one Brad) Bank A as a multiplier. Then use the buttons 6-10 for Bank B which would calculate the correct Program number to send to the Guitar Rack.
I tried using the onscreen keyboard buttons to act as a variable and to “remember” the Bank Number but ran into problems with timing on this when due to multi threading perhaps. In the end I had to use Rack States to indicate Banks 1 – 10. The and down buttons would load next or previous states and bindings on state load would send a bank number to the Button Bank Filter.
Problem 6 – Calculating Bank Number from Program Number)
I have a requirement to set a pre defined Guitar preset on song load. So, for example, if I wanted to preset guitar program 11 on Song load, I wanted this to be reflected on the FCB1010 as Bank 3 with Program button 6 LED lit.
So the problem was to convert the incoming program number for a song to Bank and button. Perfect for a divide modulo 5 solution (5 programs per Bank). This gives you the Bank number and the remainder gives you the program switch number. However, the only way I could think to achieve this was setting up Program maps in Midi filters to give you a Bank number. So map PC 1 – 5 to PC 1, PC 6-10 to PC 2…etc
The resultant PC was used to load the Appropriate Bank State in the rack which would generate the Bank Number needed. That resulted in 50 maps for 10 Banks I allowed for. It also gave me limitations as to the number of Banks I could have. A calculation of a variable would offer no upper limit in theory. Not a huge issue in itself but I don’t like that sort of artificial limit when programming.
So I got all this up and running eventually but it was a challenge. Don’t get me wrong, I loved every minute of it as an exercise for a retired IT professional. Trying different ways to do things with the tools given you in Cantabile is great fun.
However, it proved to operate noticeably slowly with a lag between foot press and LED operation. I guess the code path length in Cantabile is quite long what with all the filters and bindings used to achieve the requirements.
I have since reverted to using Bome Midi Translator(BMT) instead to achieve the same result and it processes very quickly seemingly instantaneously. Also, whereas trying to use cantabile took me approximately four days, I was able to achieve the same in BMT in under a day, and that include having to read the user guide to refresh my memory about certain techniques.
What made it quick to code was the Rules logic available in each “Translator” and the access to local and Global variables.
The processing speed comes, I believe, from the ability to stop processing the Translators (bindings) when a desired condition is met and that a simple calculation in the BMT rules replaced many Binding and midi filters.
I’m not sure if you guys are familiar with BMT but the parallels to translators and bindings are obvious. What is really fantastic about BMT is that the Input and Output section of a translator (the same as Source and Target of bindings) is so fully functional with just a few selections to hand. With the addition of the rules section in between the Input and Output sections, there is nothing you can’t achieve. If you take a look at BMT, please note the Timer function on the input and Output stages of a Translator. It’s more than it first appears because on an output stage you can set a timer for 0 milliseconds say and with a given name. On the Input stage you can trigger on that Timer name. It gives you a fantastic way of kicking of a series of events from one trigger. I found that hugely powerful.
So, for Cantabile, which is everything I’ve ever wanted regarding VST’s and Songs and Set Lists, if we had the equivalent of BMT sitting in bindings, my god, what a powerful beast that would be. I guess what I’m trying to say is that the current combination of of bindings, midi routes and midi filters is a little too prescriptive and clunky to use but the BMT model I find simple and powerful.
I sincerely hope you don’t think of this document is a moan but more of a help. The requirement to incorporate control of a midi control device into Cantabile in clever and powerful ways I would have thought quite common so not sure if others struggle as well.
I know that something like the changes of this nature may give users upgrade issues with regard to an operating model but how about something like offering the BMT style services from a new object you can add e.g. Rules object… Just thinking out loud and more than likely not for long enough.
Anyway, that’s it.
Many kind regards to you all