Detecting the increase or decrease of an input

Meh

2013-08-16 15:43:20

Hi,

I am using MIDI Translator to translate MIDI Control Changes into MIDI notes for use with a lighting console. I am wondering if MT is able to output different MIDI notes depending on whether the incoming MIDI is either increasing in value or decreasing? This would be very helpful for control of lighting parameters where I am using one MIDI parameter to increase or decrease a lighting parameter.

I have created a work around of splitting the incoming MIDI in half by rules… for example 0-64 sends a note which decreases the parameter and 65-127 sends a different note which increases the parameter. While this works it's not very intuitive or easy to use.

Any help would be greatly appreciated.

Many thanks,

Steve

DvlsAdvct

2013-08-20 14:22:12

Hi Meh

Yes, what you want to do is absolutely possible using MIDI Translator Pro. You can use Rules to augment your MIDI signals so different signals will send if a knob is moving up or down. If it's an endless encoder sending relative messages it is even easier. :)

Let me know if you need any help
Jared

Meh

2013-08-20 15:17:49

DvlsAdvct wrote:Hi Meh

Yes, what you want to do is absolutely possible using MIDI Translator Pro. You can use Rules to augment your MIDI signals so different signals will send if a knob is moving up or down. If it's an endless encoder sending relative messages it is even easier. :)

Let me know if you need any help
Jared
Hi Jared,

Would you be able to help me in writing a rule to send different signals depending on if a knob is moving up or down?

Thanks,

Steve

DvlsAdvct

2013-08-20 15:21:56

Of course. Is it an absolute or an endless encoder?

Meh

2013-08-21 13:58:22

It's an absolute encoder.

DvlsAdvct

2013-08-21 14:16:00

Alright, so try this entry for the encoder.

Code: Select all

Translator 1: Absolute Encoder
Incoming: MIDI B0 0E pp 
Rules: 
gd=pp-ga
ga=pp
if gd>=0 then Goto "Up"
if gd<0 then Goto "Down"
Label "Up"
qq=65
Exit rules, execute outgoing action
Label "Down"
qq=63
Exit rules, execute outgoing action
Outgoing: B0 0E qq
So what we're doing is taking the incoming signal from the knob and subtracting it from the position the knob was in previously. I set it as a specific Relative message of 65 or 63, but that might need to be changed to 127 and 1, depending on the software. Does that make sense?

Meh

2013-08-21 14:55:11

Great!

If I wanted to have the Up action output Note 1 and the Down action to output Note 2 is it as simple as changing the lines under each "Label" call to "90 01 pp" and "90 02 pp" respectively?

DvlsAdvct

2013-08-21 15:00:20

You would add another local variable, we'll go with rr. It would look like:

Code: Select all

Translator 1: Absolute Encoder
Incoming: MIDI B0 0E pp 
Rules: 
gd=pp-ga
ga=pp
if gd>=0 then Goto "Up"
if gd<0 then Goto "Down"
Label "Up"
qq=65
rr=01
Exit rules, execute outgoing action
Label "Down"
qq=63
rr=02
Exit rules, execute outgoing action
Outgoing: B0 rr qq

Meh

2013-08-21 15:05:53

Thank you! I'll give this a go.

TomViolenz

2014-06-26 16:39:16

DvlsAdvct wrote:You would add another local variable, we'll go with rr. It would look like:

Code: Select all

Translator 1: Absolute Encoder
Incoming: MIDI B0 0E pp 
Rules: 
gd=pp-ga
ga=pp
if gd>=0 then Goto "Up"
if gd<0 then Goto "Down"
Label "Up"
qq=65
rr=01
Exit rules, execute outgoing action
Label "Down"
qq=63
rr=02
Exit rules, execute outgoing action
Outgoing: B0 rr qq

Hey thanks this solution helped me with my (similar) problem :-)

But after having tried to first solve it myself and now seeing the solution, I can't help but be a little confused. :?
If anyone wants to clear that up, I would welcome the explanation.

So here is what I did with the suggestion from above and which works nicely:

Code: Select all

Incoming: B5 4F pp
gx=pp-gy
gy=pp
if gx>=0 then Goto "Up"
if gx<0 then Goto "Down"
Label "Up"
rr=79
exit rules, execute Outgoing Action
Label "Down"
rr=80
exit rules, execute Outgoing Action

Outgoing: B5 rr 7F


The part that I have a problem with, and that I had done wrong the whole time before, concerns this:

Code: Select all

Incoming: B5 4F pp
1:gx=pp-gy
2:gy=pp
3:if gx>=0 then Goto "Up"
4:if gx<0 then Goto "Down"
In 1: a global variable gx is set equal to the sent value of my encoder minus an as yet undefined global variable gy.
So I would think that at the time the equation is solved the first time gy should be 0. Meaning gx=pp. With pp in almost all cases being greater than 0 (even if I turn the encoder down) line 3: should be executed. Meaning at least the first tick should trigger "Up" instead of "Down".

This does not happen, why?
I get it on the second pass, when line 2: has been executed once and gy defined as the pp from pass one.
But why the first time?

I don't get it, what am I missing and what value does a global variable have before it has been defined for the first time.

I would be thankful for any light to be shed, but it's not directly a support case, so I understand if you don't find the time :-)

Cheers Tom

DvlsAdvct

2014-06-26 19:14:47

Hi Tom

Your confusion is related to how global variables work. So, the order of operations is gx is calculated and then gy is calculated. The next time the translator is triggered it has already calculated gy, so it does the math for gx. Think of it like a loop

calculate gx
calculate gy
calculate gx
calculate gy

Make sense? Even though the gx is calculated first it can't be calculated without gy, so technically the first message you turn the knob nothing happens, but you'd never notice. Since the value is stored every time the knob is turned and remembered for the next time it is turned you don't want gy calculated until after gx's value has been recognized.

Does that make sense?

TomViolenz

2014-06-26 20:30:53

Thanks, that cleared it up and was some important knowledge for further using global variables. :D
I think I have already done some very convoluted translator rules, because I always wanted every variable to be calculated or defined before it was to be in a state where I needed it to be (like at an if /then decision)
Is the same true for local variables within a translator? And can you use local variables if you let a timer cycle the translator, or is that forgotten when the timer calls the same translator again?!

Thanks :)

DvlsAdvct

2014-06-26 20:51:17

Local variables are forgotten once the translator is triggered, so it's more useful for static formulas based off of different incoming messages. I would avoid using local variables for timers since they may appear to work at first while testing they will definitely fall apart in real use.

So, global variables are stored and can be recalled after the translator completes; local variables are forgotten and need to be redefined every single time.

Make sense?

TomViolenz

2014-06-27 00:17:25

Yes, got it on timers :-)

But just to clarify the other question, within the translator itself can a local variable be used in a line above the line where it gets specified (like in the example above for the global variable), or does that only work for global variables because only they can actually loop? (thinking about it, it' probably the later, right?! :) )

Cheers, and many thanks :D

DvlsAdvct

2014-06-27 00:34:15

The simple answer is that if you ever need to loop a translator or cross reference among multiple translators you need to use global variables.

TomViolenz

2014-06-27 00:57:48

That's what I started to think too after I had typed out the question. Thanks for the confirmation :-)