So I know we don’t yet have the ability to handle bidirectional MIDI (it’s on our list) but there is a way to do it with scripting. I have a MIDI Fighter Twister (look it up if you’re not familiar, it’s a nice controller) which has endless knobs. You can have widgets learn the knobs with no problem but right now, you can’t update the Twister knobs from widgets.
However, if you use the following script in your rackspace you can
In this example, I’m assuming you have (a) created a MIDI Out Block that’s associated with your MIDI Twister (or whatever controller you have where you want this trick to work) and (b) you have created some widgets and given them script names K1, K2, K3 and K4
var
TTT : MidiOutBlock // You need a MIDI out block associated with the MIDI device of your Twister
// Send MIDI value out to twister based on position of a widget
function UpdateTwisterWithValue(ccNumber : integer, widgetValue : double)
var
cc : ControlChangeMessage
value : integer
value = Round(widgetValue * 127) // Convert widget value between 0 and 1 to a MIDI value between 0 and 127
cc = MakeControlChangeMessage(ccNumber, value);
TTT.SendNowExternal(cc);
end
// Ultimately these will get declared automatically
// For now, assuming you have four knobs with script names K1, K2,K3,K4 define them here
var
K1 : Widget
K2 : Widget
K3 : Widget
K4 : Widget
On WidgetValueChange(newValue : double) from K1
UpdateTwisterWithValue(71, newValue) // 71 is CC value for K1
end
On WidgetValueChange(newValue : double) from K2
UpdateTwisterWithValue(1, newValue) // 71 is CC value for K1
end
On WidgetValueChange(newValue : double) from K3
UpdateTwisterWithValue(2, newValue) // 71 is CC value for K1
end
On WidgetValueChange(newValue : double) from K4
UpdateTwisterWithValue(3, newValue) // 71 is CC value for K1
end
function UpdateTwisterOnActivate(w : Widget, ccNumber : integer)
var v : integer;
cc : ControlChangeMessage;
v = Round( w.GetWidgetValue() * 127);
cc = MakeControlChangeMessage(ccNumber, v);
TTT.SendNowExternal(cc);
end
On Activate
// Get the current widget value when we open this rackspace and set twister
UpdateTwisterOnActivate(K1, 71);
UpdateTwisterOnActivate(K2, 1);
UpdateTwisterOnActivate(K3, 2);
UpdateTwisterOnActivate(K4, 3);
end
This looks very useful. I use a Novation Zero SL MkII for sending Panic message and controlling the B5 drawbars. I will give this a try with the rotary encoders and switches. I particularly like the OnActivate function.
Very powerful script! I’ll adapt now to my x-touch mini…
One more request: could it be possible to have some “global variables”? I’ll try explain my use case ant the request…
I find that instruments playability derive from translating interaction between hardware (keyboard controller, midi controller, pedal) and software in a CONSISTENT and continuous way (if I play a real hammond the volume/expression is a defined value that is mantained if I “play with drawbars” for example…)
a midi fighter twister (or a x-touch mini) is a fully “dual-way” controller (value can be sent from the controller, and controller can receive value and adapt/show the new value) --> this script get all things done and give consistency between value shown and value used
I now think a “hardware with no return possible” controller, eg a footpedal for expression/volume (connected to a keyboard)… in that case I can change expression/volume (for example say I set to 64, 50% of value), I change my rack/variations, and I would like to have 2 choice…
use the value saved in the widget (and that is possible with “recall on load / recall on activate”)
OVERRIDE SAVED VALUE in the widget (with same/consistent name) contained in the newly selected rack/variation with THE ACTUAL GLOBAL VALUE (last one received from the controller)
I think it could be achieved with a “global variable” that can be saved globally…
MAYBE it is possible doing so with 2.0.4b (…and I’ve failed to realize with my demo scripts…)
Obviously I think it could be done at higher level in RIG configuration, defining a property for each defined Midi Control that say “override saved value with last received value”… but also scripting is a solution…
By the way… ROCK SOLID beta!!! …I’ve added more VST in my home setup and NO PROBLEM arises…
Yes I intended across all rackspaces… because, if I’ve correctly understood, a script live in a single rackspace and so the “script-global-variable” live only inside the scope of that rackspace.
But it would be useful also to have some “globally global” variable… so to use in ALL script defined for ALL rackspaces to implement persistence of some important parameters…
This would be useful because I’ve tested now on 2.0.4b that script ARE ALREADY duplicated with rackspaces duplication… so a “global-global” variable implementation of values persistence is quite simple to achieve…