Bidirectional bindings do not work well with x-touch mini

Hello everyone!
I’m new to Cantabile and I’m having problems with mapping X-touch mini controller to VST plugin parameters.

This controller features endless encoders to naturally I wanted any changes in plugin parameter to be reflect back to controller as well.

So I created a pair of MIDI->VST and VST->MIDI bindings. This technically works but parameter adjustment via the knob is very inconvenient: went turning the knob smoothly the parameter is not adjusted as smoothly but jumps around back and forth by small steps while incrementing/decrementing. As if there is some conflict between these 2 bindings - when rotated knob sends MIDI CC to Cantabile it’s immediately translated to VST parameter change but then the reverse binding fires too and encoder led status reflects this but know was rotated a little more since and that probably confuses Cantabile.

I’m pretty sure someone else encountered this problem, but couldn’t find any solution…

Hi qyron and Welcome to the Forum!

Could you post the bindings you use for both directions? On a BCR2000 a typical binding set would look like this

The master input gain and rotary encoder CC97 with feedback for LED ring

Cheers,

Dave

Yeah, I’m following the same scheme.

Here I’m trying to map between some slider in Garritan CFX piano VST and and endless encoder on X-Touch mini:

Here is a video of the slider on VST GUI when I’m turning the knob back and forth: https://youtu.be/GtqCBPV1yZw

If I temporary disable VST->MIDI binding while leaving MIDI->VST one on, the slider moves smoothly because now there is no “fight” between the bindings.

Hi qyron,

The video is good reason to be irritated! I didn’t get that it was the VST slider jittering. This is not I believe a Cantabile issue but related to the Aria Player & CFX library. The many synth layouts I use with the BCR all use the same standard 0 > 1.0 knobs and no sweat. Sorry it’s not behaving but you have it set right as far as Cantabile bindings go.

Cheers,

Dave

I checked some more VSTs (Pianoteq, some guitar VSTs) and now I tend to agree with you. Only Garritan has this jumpy behavior, other VSTs parameters (and also Cantabile’s sliders) are adjusted smoothly as I turn my knobs.

Worth mentioning, that Gig Performer, another VST host I evaluate, also has bidirectional bindings and works smoothly with Garritan. Its implementation however is slightly different than Cantabile’s - upon defining a binding it has a special “sync” button that automatically defines reverse binding. May be the fact that both bindings are handled together is related and GP somehow works around bad implementation of Garritan.

1 Like

Hi qyron

Thanks so much for the mention of that I will put a marker here in this thread so @brad is aware of this information.

Cheers,

Dave

I’ll need to look into this and perhaps pickup a x-touch midi to work it out for sure, but usually jitter problems with bi-directional bindings are related to a non-inverse equivalent mapping between the MIDI CC value and the float value accepted/reported by the plugin.

Some things to double check…

  • Make sure the range mapping on each of the bindings is the same
  • Make sure Options -> Keyboard and Controls -> MIDI Control Curve is set to “Cantabile (New)” as some of the other curves had issues which this curve was designed to fix.

Failing that, could you send me a debug log showing the CC values send/received.

  1. Start Cantabile
  2. Go to Tools -> Options -> Diagnostics
  3. Enable Log MIDI In Events and Log MIDI Out Events
  4. With the bi-directional bindings enabled, reproduce the problem.
  5. From the Tools menu, choose Open Settings Folder
  6. Close Cantabile

From the folder opened in step 5, send me the file log.txt, log-previous.txt, settings.json and a copy of the song or rack with the bindings and I’ll check it ou.

Brad

2 Likes

Brad, I’m attaching the files you asked for.

Apart from this Garritan CFX all other plugins play nice with bidi bindings in Cantabile so I’m 99.99% sure that the problem lies in the plugin.

Cantabile 3.0 (x64).zip (48.2 KB)

Brad, did you have a chance to look at logs I attached here?

I tried more piano VSTs and noticed same “jumpy” behavior in other plugins such as Keyscape, and Wavesfactory Mercury. Pretty frustrating.

Hi qyron,

Try @brad , it will give him a bump :slightly_smiling_face:

Cheers,

Dave

@brad
I got my hands on Midi fighter twister which is another MIDI controller featuring endless encoders. I’ve experimented with bindings of both Midi fighter twister and X-Touch mini for some VST plugins (Keyscape, Garritan CFX, Wavesfactory Mercury), captured logs and MIDI in/out values and came to conclusion that Cantabile behaves correctly in all cases.

Unfortunately it’s plugins that report incorrect parameter value (after it’s set with binding) which being mapped to incorrect midi value creates this effect of “jumpiness”.

This problem happens for X-Touch in all 3 plugins I tried when binding in Absolute. In Relative mode (X-Touch needs to be configured accordingly) however the problem is gone and bidirection bindings work smoothly.

The only plugin I couldn’t make work is Keyscape. I saw it reporting back parameter values which look values that Cantabile sends to it multiplied by some value . This totally breaks X-Touch mini.

Also from what I saw, Midi fighter twister has some “smart” protection mechanism against this jumpiness - when midi value reflected back to it differs from value that it’s just generated it just ignores it. This mechanism prevents “jumpiness” and even allows it to work in Keyscape.

The only thing I couldn’t figure out is what Gig Performer does differently that allows him to work correctly with X-Touch and all these plugins. Unfortunately there are no verbose log mode to it and also there is no outbound MIDI monitor (and external midi monitors such as Midi-OX refuse to work on Windows together with VST hosts) so I couldn’t debug it.

1 Like

My guess is that because of its implementation it can simply ignore plugin value change value when it knows it’s making the change itself. I’d like to add something similar it’s trickier because Cantabile has separate bindings for each direction - perhaps time to revisit that, not sure.

@brad
I’ve continued my experimenting with X-Touch mini and Cantabile bidirectional bindings. This time I tried to map controller buttons to toggle plugin on/off switches. The buttons toggle between MIDI values 0 and 127 so default binding settings were expected to work. The buttons also have led lights to indicate on/off state so MIDI reflection is important here.

I tried “Garritan CFX” (uses Aria player), “Wavesfactory Mercury”, “The Grandeur” (last 2 are KONTAKT libraries) and in all cases button didn’t work but this time I think the problem is with plugins. What I observe is when I press button, MIDI value 127 triggers binding and is translated to 1.0 plugin value. However plugin (both of them) sends value 0.0 back for some reason.

Here’s excerpt from Cantabile log for Mercury (bound to reverb switch):

 MidiDeviceIn - Ch:11 Controller:  31 = 127      
00032906        0   [20096:2]: MidiInjector - Ch:11 Controller:  31 = 127      
00032916       10   [07088:2]: Binding Input Port - X-TOUCH MINI - Ch: 11 - Controller - 31 (in Mercury) => Kontakt 1 - 32: MP OnOff - Mercur - source triggered with value 127 for time (now)
00032916        0   [07088:2]:   - invoking immediately
00032917        1   [07088:2]: Binding Input Port - X-TOUCH MINI - Ch: 11 - Controller - 31 (in Mercury) => Kontakt 1 - 32: MP OnOff - Mercur - invoking target with value 1
00032917        0   [07088:2]: Binding Kontakt 1 - 32: MP OnOff - Mercur (in Mercury) => Output Port - X-TOUCH MINI - Ch: 11 - Controller - 31 - source triggered with value 0 for time (now)

I also tried on Pianoteq 6 and there it works OK. So while I’m pretty sure the plugin is one to blame here I’m also upset that there is no workaround for this. I also have a feeling that every KONTAKT library will have this issue, on any MIDI controller. May be you can try to reproduce it?

Also tried “Controller (Switch)” binding type which seems are specifically made for these type of buttons. For “MIDI=>plugin” binding it works essentially as normal binding but for “plugin=>MIDI” it allows toggle action which worked in a weird way for me: when toggling plugin parameter with button it worked OK but when togging inside plugin (with mouse) the button light didn’t update properly.

Worth mentioning that Midi Fighter Twister behaved the same way which aligns with the fact that the problem lies in plugins, not MIDI controller. Also I checked how buttons work in Gig Performer - and everything worked OK in all plugins, probably because of the trick @brad described.

Hi @qyron,

I’ve had a look at this with Kontakt with one of the instruments in the standard library and as best I can tell it’s working fine. I wonder if this is something that needs to be implemented in the nki file itself?

As an experiment can you try loading the Bling Bling Kit from the Kontakt Factory Library under 7 - Drum Kits and try binding to the Sel By MIDI switch (param 9) and see if the behaviour is the same as what you’re seeing elsewhere?

@brad

I tried this library and patch and see the same results. Here is what log file (just binding-related lines) look like when I press button 4 times:

00022148        5   [09228:2]: Binding Input Port - X-TOUCH MINI - Ch: 11 - Controller - 31 (in temp) => Kontakt 1 - 9: Midi - Bling Blin - source triggered with value 127 for time (now)
00022148        0   [09228:2]:   - invoking immediately
00022148        0   [09228:2]: Binding Input Port - X-TOUCH MINI - Ch: 11 - Controller - 31 (in temp) => Kontakt 1 - 9: Midi - Bling Blin - invoking target with value 1
00022148        0   [09228:2]: Binding Kontakt 1 - 9: Midi - Bling Blin (in temp) => Output Port - X-TOUCH MINI - Ch: 11 - Controller - 31 - source triggered with value 0 for time (now)
00022148        0   [09228:2]:   - injecting midi: Controller param: 31 value: 0, for time: 3179456892

00033588        8   [09228:2]: Binding Input Port - X-TOUCH MINI - Ch: 11 - Controller - 31 (in temp) => Kontakt 1 - 9: Midi - Bling Blin - source triggered with value 127 for time (now)
00033588        0   [09228:2]:   - invoking immediately
00033588        0   [09228:2]: Binding Input Port - X-TOUCH MINI - Ch: 11 - Controller - 31 (in temp) => Kontakt 1 - 9: Midi - Bling Blin - invoking target with value 1
00033588        0   [09228:2]: Binding Kontakt 1 - 9: Midi - Bling Blin (in temp) => Output Port - X-TOUCH MINI - Ch: 11 - Controller - 31 - source triggered with value 1 for time (now)
00033588        0   [09228:2]:   - injecting midi: Controller param: 31 value: 127, for time: 3179456892

00035132        4   [09228:2]: Binding Input Port - X-TOUCH MINI - Ch: 11 - Controller - 31 (in temp) => Kontakt 1 - 9: Midi - Bling Blin - source triggered with value 0 for time (now)
00035132        0   [09228:2]:   - invoking immediately
00035132        0   [09228:2]: Binding Input Port - X-TOUCH MINI - Ch: 11 - Controller - 31 (in temp) => Kontakt 1 - 9: Midi - Bling Blin - invoking target with value 0
00035132        0   [09228:2]: Binding Kontakt 1 - 9: Midi - Bling Blin (in temp) => Output Port - X-TOUCH MINI - Ch: 11 - Controller - 31 - source triggered with value 1 for time (now)
00035132        0   [09228:2]:   - injecting midi: Controller param: 31 value: 127, for time: 3179456892

00036490        4   [09228:2]: Binding Input Port - X-TOUCH MINI - Ch: 11 - Controller - 31 (in temp) => Kontakt 1 - 9: Midi - Bling Blin - source triggered with value 0 for time (now)
00036490        0   [09228:2]:   - invoking immediately
00036490        0   [09228:2]: Binding Input Port - X-TOUCH MINI - Ch: 11 - Controller - 31 (in temp) => Kontakt 1 - 9: Midi - Bling Blin - invoking target with value 0
00036490        0   [09228:2]: Binding Kontakt 1 - 9: Midi - Bling Blin (in temp) => Output Port - X-TOUCH MINI - Ch: 11 - Controller - 31 - source triggered with value 0 for time (now)
00036490        0   [09228:2]:   - injecting midi: Controller param: 31 value: 0, for time: 3179456892

So in after first press I see invoking target with value 1 followed by source triggered with value 0 and after 3rd press I see invoking target with value 0 followed by source triggered with value 1 . 2nd and 4th press behave correctly. This pattern repeats if I press the button repeatedly. My Kontakt version is 6.2.2.

I’ve had another look at this and I’d argue that this is a bug in the plugin.

I added some code to get the parameter back immediately after it’s set and it’s returning a different (presumably the old) value:

eg:

Here, the parameter has been set to 0 but the plugin is returning it as 1:

(value is the value Cantabile has just passed to the plugin, newValue is what the plugin is returned as the parameter value after it’s been set).

and here’s the opposite:

I say this is arguably a bug in the plugin because I don’t think the VST spec indicates when setting a plugin parameter has to stick, but it should be immediate IMO. My guess is that the parameter returns correctly after the next audio cycle, but I’m not going to change Cantabile to cater for this weirdness.

ie: take it up with NI and include my contact details if you like.