I ran out of global variables

Dingo66

2013-06-28 21:21:19

Hello from Germany,

im using Allen & Heath IDR-48 iLive Mix Rack and want try to control it with a 8 channel Behringer BCF2000 DAW controller. The iLive software can just send and receive 48 channels over a midi port without any possibility to switch between banks/presets or manipulate in other way, but the BCF2000 will only react on the channels, which are present on the actual bank/preset (as example PRESET2: Channel 9-16). All other channels will not be cached, so after switching between bank/preset 1,2,3,... and so on, the faders dont have the right position.

My idea is to use MT as cache. If i will switch banks, MT will send the right fader position every time. I begun already to program it with MT demo version, but after some channels i ran out of available global variables - but it works :c)

32 channels with:
channel Faders, mute buttons, PAFL buttons, aux/send faders, Encoders for PAN/PreAmp, 48V, PAD and so on... are a lot of variables for caching.
g0-gz until n0-nz are not enough variables for this.

But i need to store all banks of all data, if i want switch between them.

Is there andy solution / workaround / idea?
3-letter variables - gaa ?
Multi Dimension variable - ga[1]?
Any other place to store some data?

@KrisMurawski

2013-11-01 12:54:12

hello there dingo66, there are two workarounds I know that meet all your needs .
 
I found two ways to deal with this limited number of variables problem. Those are not so easy to implement but furtunately it's not rocket-sience too and what's good both work like a charm. So we can get much more out of MT. Certainly it was so in my case.

Just want to say that yesterday I was trying to write a more detailed explanation on how to make it work but I found it not so easy to do this way. So here I post shorter decription and ideas and if you still interested in, or someone else, just bring this topic to life and I will share what I know maybe more clearly.

First workaround: - Multiple instances of midi translator.
In this case you need to build setup of independent MT instances (in you case 3 or 4 should do the job) communicating one another. Check loopMidi by Tobias Erichsen as it's imho the best multi-client virtual midi cables solution. And now in short: the communication between iLive, MT instances and BCF goes somethong like this:
- iLive must pass data to at least two instances of MT (multi-client midi cable)
- in each of these MT instances you'll be going to store different sets of data
- now these instances must communicate/sendto to the next instance I call "Bridge". Bridge is crucial in this setup because from here we'll be connected/communicating to real hardware both ways (on BCF2000 in/out port) and usually there is no way to connect real hardware multiple times to multiple instances without "Cannot open MIDI input/output device" error.
- now connect BCR to the Bridge (it opens BCF both ports once)
- Now in Bridge we have to build translators that will send requests to instances where data is stored.
- On requests (ex. when selecting next bank on BCF) those instances will send stored data back to bridge and bridge will pass it to BCF to update faders positions and led states.
- In short that's it.

Second workaround: - Bitmanipulation to store value the way it takes only one byte not whole variable, so one global var can store up to four values (in case of bome's midi translator.)

What that mean is that you can store multiple values in a single global variable and then recall/restore them to local vars (oo,xx,pp etc) or another global as well. Then we can use it to build outgoing midi messages(to feed BCF updates) or to assign this value to another variable if needed.
- Theoretically it lets you store up to 1152 values in 288 variables (4byte/values x 288vars)
- In cases where you are going to store just "state" of control not value (for example: channel mute on/off state) this "state" will use just one bit not whole byte so we can pack a lot more into one var.
- To write value into selected byte we'll use a binary operator XOR but byte need some initial preparation prior to this. It's just tree lines of code to clear byte and store value.
example (byte1)
km=km|127 ; clear
km=km^127 ; clear
km=km^pp ; write
- To pull value out form selected byte we'll use a binary operator & (AND) and for bytes2,3,4 we need to divide it to get real value
example (byte1, byte2, byte3, byte4)
oo=ia&127 - pulling vaule, stored to "oo", for byte1 it's real value of the hat
pp=ia&32512 - pulling vaule, stored to "pp"
pp=pp/256 - getting real value
qq=ia&8323072 - pulling vaule, stored to "qq"
qq=qq/65536 - getting real value
rr=ia&2130706432 - pulling vaule, stored to "rr"
rr=rr/16777216 - getting real value

Cheers,
Kristopher

i@mJONNY

2017-01-29 21:28:19

that's ingenious kris'

any chance ya can share an example of workaround 2, that shows how one variable (a state var) is used to store the states of.. 4(?) parameters?

Bookmarking for when I'm in the presence of smarter peeps!

sjcaldwell

2017-01-29 22:02:36

I do midi channel mapping in my project controlling 16 channels with a global variable and each channel representing 1 bit.
I can selectively turn on all or none of the channels.

Here is a post with my config file.

https://www.bome.com/forums/viewtopic.php?f=3&t=12248

@KrisMurawski

2017-01-30 21:34:51

i@mJONNY wrote: any chance ya can share an example of workaround 2, that shows how one variable (a state var) is used to store the states of.. 4(?) parameters?
I've put some logic for bitwise manipulation together. This should clear things up a little.
bitwise_manipulation_example.bmtp
(4.03 KiB) Downloaded 183 times
Just to remember:
- with this approach from the attached example, you can only store values from between 0-127 range inside each of those 4 bytes, it is critical so it's your job to keep an eye on this
- as it is a standard midi resolution it should do the job nicely
- so do not write bigger values that 127, this approach can't handle that
- and one more thing is to keep those strange integers intact, they are responsible for storing/reading your real value (pp) to correct places inside a given global var (gb in this example, change it to whatever you want as well as those pp, rr, ss etc)
- use this approach as template/snippet to construct your logic, copy, paste, change those vars but keep the integers intact
- in this example the value you want to store is pp from incoming midi message, change it however you like of course

If you use Log Window you can check what's happening to your var/values to make sure that everything is fine and works as intended.
Hope that helps.
Kris