Index in Switches Script

Discuss Lemur and share techniques.
FineCutBodies
Newbie
Posts:8
Joined:14 Jan 2017 11:55
Location:Los Angeles, California
Contact:
Index in Switches Script

Post by FineCutBodies » 19 Jan 2017 04:12

Hi,

Maybe it's just me, but couldn't find any information if there is a way to determine in script which Switch was changed on a Switches object's OnExpression callback?

I have 16 Switches in a matrix and I can make a separate OnExpression callback for each like:

OnExpression (x[0] is changing) >> noteout(0,x[0]*16 + 0,127,1);
OnExpression (x[1] is changing) >> noteout(0,x[1]*16 + 1,127,1);
...
OnExpression (x[15] is changing) >> noteout(0,x[15]*16 + 15,127,1);

But all the scripts are doing the same calculation based on the number which switch was changed. So basically this should be one script if I would be able to have a callback where I get a variable that tells me what Switch was changed.

Just for the simplicity I would like to send out different midi noteOn messages for every switch's both states as you can see on the example above.


Thanks for all your suggestions in advance,
Kevin

phase_change
Regular
Posts:114
Joined:31 May 2015 18:45
Location:Austin, TX

Re: Index in Switches Script

Post by phase_change » 19 Jan 2017 04:59

I'm going to be straight with you, I don't have any idea what you're talking about, and I'm not sure you do either.

Let's break down what's happening in your script and what you want to happen.
When x changes, you are sending out a NoteOn message. When x is on, x=1. When x is off, x=0.
So when you send a NoteOn message for the first switch when it is on, you have noteout(0,16,127,1). When you send a NoteOn message for the first switch when it is off, you have noteout(0,0,127,1). This means when the switch is on, target = 0, note = 16, velocity = 127, channel = 1 and when switch is off, target = 0, note = 0, velocity = 127, channel = 1 etc. Do you see why this doesn't work? You just turned note 16 on and note 0 on, but haven't turned anything off. A NoteOn turns a note off by setting velocity for a note = 0.

You can create an expression that is an array and update each value as 0 or 1 to represent the state of your 16 switches.

Is OnExpression really a callback? Isn't it just a triggering event?
Have you tried turning it off and on again?

FineCutBodies
Newbie
Posts:8
Joined:14 Jan 2017 11:55
Location:Los Angeles, California
Contact:

Re: Index in Switches Script

Post by FineCutBodies » 19 Jan 2017 05:57

Thanks for your answer, but trust me I know what I do and yes you are right, that's exactly what the script has to do (and more, but that's not related here) :) no need for noteoffs, as these messages are triggers on the other side.

Yes, I can solve it other inelegant ways (currently my project works perfectly), but my question was if there is a way to write one trigger script that can determine "i" and then I don't have to write 16 different scripts or some other ugly workaround. On the other hand why would it be helpful to update an array to represent x? For me it seems the array 'x' represents itself nicely, my problem is that I'd like to know the index that triggered the script when any elements of 'x' changed.

Sorry if the word callback confused you, but for me it seems a Lemur trigger is a callback mechanism as it will be called whenever an event happens.

phase_change
Regular
Posts:114
Joined:31 May 2015 18:45
Location:Austin, TX

Re: Index in Switches Script

Post by phase_change » 19 Jan 2017 06:14

Oh...
My mistake, you do understand what you're trying to do and I am the only one that doesn't. Why can't you use a for loop?

You said
So basically this should be one script if I would be able to have a callback where I get a variable that tells me what Switch was changed.
Variables in Lemur are called expressions. You can store an array as an expression. You have 16 switches with 2 states. You could use an array w/ 1's and 0's or you can store a single value in the expression from 1-32 or 0-31 or w/e. This is not necessarily how I would go about solving the problem, I'm just trying to provide you with the information I think you're looking for based on what you wrote.

Callbacks as I understand are when a function is called via another function. I would call this triggering event a method. I'm probably projecting a conversation I had with a noob that was into JS and asking ab what Php was where he asked if it was a server callback language and unconsciously assuming you also are a noob b/c of that. Something happens inside my brain where an impulse of electricity shoots off and makes my eyebrow twitch when I think about that conversation. I wasn't confused by that, though. I'm more confused by the other things you said/lack of information. That was a legitimate question... is this technically a callback or a method?

*Edit* I realize local variables in a script are also called variables, but I'm p sure if you use y in script A then try to use y in script B, it won't work, but if you create an expression it will.

*Edit #2* A thought on elegance - Does it matter? What's the CPU usage at? Do you really have so much going on with 16 scripts and 16 switches that it's over 1%? What is the framerate and how close do you really need this to be to 60 fps? If you're not using the internal clock, it's probably not v important. The reason I use for loops in Lemur is generally b/c I'm lazy and hate typing.

*Edit #3* The more I think about this the more I see the problem you're running into. Maybe if you're finding that you can't get this to work without a workaround or inelegant solution, the problem is using switches and noteout() like this is like trying to force a square peg through a round hole. Firstof(x) won't work because more than one switch can be on at the same time, a for loop is going to trigger multiple noteout()s whenever x changes. If you're not triggering notes, why use NoteOn? If there's no off data, would you be better suited using a different midi message like a program change? Why does it have to be 16 switches used in this way? Why not use 32 and set to radio mode? Then firstof(x) would work. What happens when you've turned every switch on and off at least once? Why is anything happening in your app after this - you've already turned everything on and nothing off? I guess without more information about how you're applying this, it's hard to give you advice that is helpful.
Last edited by phase_change on 19 Jan 2017 08:15, edited 1 time in total.
Have you tried turning it off and on again?

FineCutBodies
Newbie
Posts:8
Joined:14 Jan 2017 11:55
Location:Los Angeles, California
Contact:

Re: Index in Switches Script

Post by FineCutBodies » 19 Jan 2017 07:58

I know the lack of context can be misleading and sorry for it, I just tried to minimize the "problem" to see if there is an easy answer for it, as couldn't find anything in the documentation or on the forum.

Yeah your for loop also would work, I just don't want to send out 16 (or 64 in worst case if my matrix is 8*8) midi messages whenever I need to send out one, but sure it's a solution. Another a bit better solution if I have an array called 'last_x' that is mirroring all the state of 'x' and a for loop scans it for changes then sends out only the corresponding messages. And yes, maybe it's the only way and I can't reach the trigger index from an OnExpression script, but the Lemur documentation is not clear on this subject and thought maybe it's just me can't find how I can reach the index that triggered an OnExpression script.

This is the best option as I see it now, but if I could get the index in the script then I shouldn't use extra array and loop:
Screenshot 2017-01-18 23.53.02.png
This works best
Screenshot 2017-01-18 23.53.02.png (11.55KiB)Viewed 1952 times
But I'd be happy to reach the index of the triggering switch. Currently 'i' should be a constant and not an argument of the script so you need to make a script for every switch in the Switches object.
Screenshot 2017-01-18 23.13.44.png
this is not working obviously
Screenshot 2017-01-18 23.13.44.png (7.07KiB)Viewed 1952 times
Regarding the speed optimalization, it's not a problem, I don't think about it because of speed, but because if I have 64 switches in a Switches object then I'll need 64 (almost) similar onExpression trigger scripts but if there would be one script that is triggered whenever any of the switches would change state this script would be called and would give the switch index to the script in an parameter like the pic above.

Anyway thanks for the thinking together!

FineCutBodies
Newbie
Posts:8
Joined:14 Jan 2017 11:55
Location:Los Angeles, California
Contact:

Re: Index in Switches Script

Post by FineCutBodies » 19 Jan 2017 08:05

phase_change wrote:*Edit #3* The more I think about this the more I see the problem you're running into. Maybe if you're finding that you can't get this to work without a workaround or inelegant solution, the problem is using switches and noteout() like this is like trying to force a square peg through a round hole. Firstof(x) won't work because more than one switch can be on at the same time, a for loop is going to trigger multiple noteout()s whenever x changes. If you're not triggering notes, why use NoteOn? If there's no off data, would you be better suited using a different midi message like a program change? What happens when you've turned every switch on and off at least once? Why is anything happening in your app after this - you've already turned everything on and nothing off? I guess without more information about how you're applying this, it's hard to give you advice that is helpful.
1, why Note on? >> I use Program Change messages and CCs for other things, so noteOns are working perfectly as triggers (nothing to do with notes on the other side, just using them as controller triggers)
2, my app is looking for triggers and not on/off messages so it doesn't really keep track of states. I need states for my Lemure GUI only.

thanks again for being helpful. And again it works for now and I can find several ways to solve it, I was just curious if I miss something and make it more complicated than it should be :)

phase_change
Regular
Posts:114
Joined:31 May 2015 18:45
Location:Austin, TX

Re: Index in Switches Script

Post by phase_change » 19 Jan 2017 08:21

My brain hurts at this point - so I'm going to have to get back to you on this later. I can really quickly tell you why screenshot 2 isn't working. If you define "i" in the script it's a local variable. If you create an expression called "i" it's going to act like what I would call a global variable in other scripting languages (not sure if it is technically called that here, would be interested to know if I'm wrong.) You can't trigger a script on expression with a local variable - has to be global.

Last question for the night and it's me taking a stab at this: You aren't using something like Max with toggle objects are you?
Have you tried turning it off and on again?

FineCutBodies
Newbie
Posts:8
Joined:14 Jan 2017 11:55
Location:Los Angeles, California
Contact:

Re: Index in Switches Script

Post by FineCutBodies » 19 Jan 2017 08:34

phase_change wrote:My brain hurts at this point - so I'm going to have to get back to you on this later. I can really quickly tell you why screenshot 2 isn't working. If you define "i" in the script it's a local variable. If you create an expression called "i" it's going to act like what I would call a global variable in other scripting languages (not sure if it is technically called that here, would be interested to know if I'm wrong.) You can't trigger a script on expression with a local variable - has to be global.
I know it's not working, I just gave it as an example that how good it would be if I could get 'i' as an argument :) So no worry, the first script works well...
phase_change wrote:Last question for the night and it's me taking a stab at this: You aren't using something like Max with toggle objects are you?
I've been working a lot in Max, but not this time. It triggers Cubase Logical Editor Commands & Kontakt scripts on the receiver side. :)

oldgearguy
Regular
Posts:315
Joined:02 Nov 2013 11:19

Re: Index in Switches Script

Post by oldgearguy » 19 Jan 2017 10:45

couple things -
are the switches in the matrix set up as radio buttons? (i.e. - only 1 on at a time?)
If so, you can do an "OnExpression (x) any" and then do a firstof(x) to get the one that is on. firstof() returns the index (0 based) of the first non-null item in an array. If you wanted to do processing for what turned off as well, then this doesn't help too much.

If not (you can have more than one on at a time) then you can still do an "OnExpression(x) any" but you have to save off the array of values into an expression defined outside the script so the info stays around between frames.
Your example above is exactly that and I don't think there's any better shortcut.

phase_change
Regular
Posts:114
Joined:31 May 2015 18:45
Location:Austin, TX

Re: Index in Switches Script

Post by phase_change » 20 Jan 2017 00:20

FineCutBodies wrote: I know it's not working, I just gave it as an example that how good it would be if I could get 'i' as an argument :) So no worry, the first script works well...
I just told you how to make it work, not that it's not working. Create an expression called 'i'.
Have you tried turning it off and on again?

Post Reply