Questions about variables

You have a question or need an advice about how to do something? Ask it here!
Post Reply
smashing
Posts: 5
Joined: 15 Jun 2023 12:50
Questions about variables

Post by smashing »

Hi there.

I'm working on some fairly advanced scripting, using control commands. Specifically I'm testing the operation of a script (built using the Control Command Builder) by pressing a key to activate the script. I'm working within Keyboard Event Mapping to do this.

There are 2 issues I'm struggling with, which do not seem logical. The 2 issues are related.

1. Inability to reset / initialize a variable

If I set a variable to e.g. 'none' as the first command in the script, any subsequent commands within the same script to set the variable to a different value, do not seem to register. So for example if I use SHOW_ALERT_WINDOW at the end of the script to display the variable, the variable shows as 'none' even though I set it to something else in the middle of the script. This only happens when using EXEC_COMMAND2 to set the variable within the script.

2. Setting a variable within a script using EXEC_COMMAND2 does not register until the next run of the script

If I set a variable within a script using EXEC_COMMAND2, and try to use that variable later in the same script, the value of the variable does not update until the next run of the script. Specifically it has the value from the previous run of the script.

For example, if on a 1st run of the script I set the variable to A, and on a 2nd run of the script I set it B, when I try to use the variable later on within the 2nd run of the script, it will resolve to A, and not B as expected. This is essentially the same problem as above.

While troubleshooting I tried inserting a 2 second delay within the script to see if it made a difference, and it did not. I also note that if I use the simpler (unconditional) EXEC_VAR_SET to set the variable the variable updates right away.

What is it about using a conditional command to set the variable, that makes it not update until the next run of the script?

Is there a way to use EXEC_VAR_SET that only sets the variable if a condition is true, and does not touch it if the condition is not true?

Here is the script in question... note that BL A (B, C and D) represent names of the mixer outputs.

Code: Select all

EXEC_VAR_SET BLAvol|*[EXEC:{MIXER_OUTPUT_VOLUME_GET Bl A}]
EXEC_VAR_SET BLBvol|*[EXEC:{MIXER_OUTPUT_VOLUME_GET Bl B}]
EXEC_VAR_SET BLCvol|*[EXEC:{MIXER_OUTPUT_VOLUME_GET Bl C}]
EXEC_VAR_SET BLDvol|*[EXEC:{MIXER_OUTPUT_VOLUME_GET Bl D}]
EXEC_COMMAND2 ${VAR:BLAvol}|Equals(1)|EXEC_VAR_SET NEXTdj|Bl B
EXEC_COMMAND2 ${VAR:BLBvol}|Equals(1)|EXEC_VAR_SET NEXTdj|Bl C
EXEC_COMMAND2 ${VAR:BLCvol}|Equals(1)|EXEC_VAR_SET NEXTdj|Bl D
EXEC_COMMAND2 ${VAR:BLDvol}|Equals(1)|EXEC_VAR_SET NEXTdj|Bl A
SHOW_ALERT_WINDOW Volumes|A ${VAR:BLAvol} B ${VAR:BLBvol} C ${VAR:BLCvol} D ${VAR:BLDvol} NextDJ ${VAR:NEXTdj}
MIXER_OUTPUT_VOLUME_SET Bl A|0
MIXER_OUTPUT_VOLUME_SET Bl B|0
MIXER_OUTPUT_VOLUME_SET Bl C|0
MIXER_OUTPUT_VOLUME_SET Bl D|0
MIXER_OUTPUT_VOLUME_SET ${VAR:NEXTdj}|1
If I run this script as shown, the alert window will show the correct values for BLAvol, BLBvol, BLCvol and BLDvol, but the value of NEXTdj is always the value from the prior run of the script.

Basically I have to run the script twice each time to get it to work.

The script incidentally captures the volume of each of 4 mixer outputs, each mixer output carrying the signal from a different DJ player (A,B,C,D).

In practice, there will only be one DJ player operating at full volume at any one time, and the idea is that when you press a key, the next DJ player (in sequence) will have its volume set to full, and the previous DJ player will have its volume set to zero.

As mentioned, the script works fine as it is, other than the fact I have to run it twice each time (by pressing the activation key twice). This makes it not usable for my needs.

Thanks in advance.
ProppFrexx Enterprise | Intel NUC 8 i7 7HVK | MOTU 24AO Audio Interface | 2 x Velleman WSI8055N | Wohler AMP1A-4S | 6 x Room Amps | 6 x Custom PCB boxes (for room volume control)
smashing
Posts: 5
Joined: 15 Jun 2023 12:50
Re: Questions about variables

Post by smashing »

Quick update. I found a workaround.

If I execute the EXEC_COMMAND2 commands asynchronously, the script works as desired.

Here's the updated code...

Code: Select all

EXEC_VAR_SET BLAvol|*[EXEC:{MIXER_OUTPUT_VOLUME_GET Bl A}]
EXEC_VAR_SET BLBvol|*[EXEC:{MIXER_OUTPUT_VOLUME_GET Bl B}]
EXEC_VAR_SET BLCvol|*[EXEC:{MIXER_OUTPUT_VOLUME_GET Bl C}]
EXEC_VAR_SET BLDvol|*[EXEC:{MIXER_OUTPUT_VOLUME_GET Bl D}]
EXEC_COMMAND2 ${VAR:BLAvol}|Equals(1)|EXEC_VAR_SET NEXTdj|Bl B
EXEC_COMMAND2 ${VAR:BLBvol}|Equals(1)|EXEC_VAR_SET NEXTdj|Bl C
EXEC_COMMAND2 ${VAR:BLCvol}|Equals(1)|EXEC_VAR_SET NEXTdj|Bl D
EXEC_COMMAND2 ${VAR:BLDvol}|Equals(1)|EXEC_VAR_SET NEXTdj|Bl A
EXEC_ASYNC MIXER_OUTPUT_VOLUME_SET Bl A|0
EXEC_ASYNC MIXER_OUTPUT_VOLUME_SET Bl B|0
EXEC_ASYNC MIXER_OUTPUT_VOLUME_SET Bl C|0
EXEC_ASYNC MIXER_OUTPUT_VOLUME_SET Bl D|0
EXEC_ASYNC MIXER_OUTPUT_VOLUME_SET ${VAR:NEXTdj}|1
I'm still curious why EXEC_COMMAND2 does not update right away as you'd expect, and if there's a way to use EXEC_VAR_SET that only sets the variable if a condition is true, and does not touch it if the condition is not true.
ProppFrexx Enterprise | Intel NUC 8 i7 7HVK | MOTU 24AO Audio Interface | 2 x Velleman WSI8055N | Wohler AMP1A-4S | 6 x Room Amps | 6 x Custom PCB boxes (for room volume control)
User avatar
radio42
Site Admin
Posts: 8350
Joined: 05 Apr 2012 16:26
Location: Hamburg, Germany
Contact:
Re: Questions about variables

Post by radio42 »

1. Inability to reset / initialize a variable
This is not correct. Variables are always global. I.e.you can set and initialize a variable at any time (even in other events). Once set, you can use it.
Here is a simple example:

Code: Select all

EXEC_VAR_SET Test|12345
SHOW_ALERT_WINDOW Test|Value = ${VAR:Test}
2. Setting a variable within a script using EXEC_COMMAND2 does not register until the next run of the script
This is also not really correct, but slightly yes (and this is by design and purpose). And also explains what you experience.
Many commands do execute asynchronously internally. Especially the EXEC_COMMAND2.
This means, that the criterion and condition is evaluated synchronous, but if matching, the resuting command needs to be executed asynchronously!
Meaning it is kind of queued in a new thread. Which effectively means, that the next command in our command sequence is executed, before the conditional command is finished!

The EXEC_ASYNC basically does the same. It also queues the command in a new thread.
Parallel threads are actually executed independent and asynchronously.
So it is not guaranteed, that they finish sequentially as they are started, even if this is a thread goal, but depends on your OS and other threads running.

So your solution is only by chance as you expect them, but not actually guaranteed to always work - but I assume mostly.
smashing
Posts: 5
Joined: 15 Jun 2023 12:50
Re: Questions about variables

Post by smashing »

ok - thanks for the quick reply. This helps in part to explain the trouble I was experiencing.

Am still left a bit confused why the 2 second delay test didn't solve it!
ProppFrexx Enterprise | Intel NUC 8 i7 7HVK | MOTU 24AO Audio Interface | 2 x Velleman WSI8055N | Wohler AMP1A-4S | 6 x Room Amps | 6 x Custom PCB boxes (for room volume control)
User avatar
radio42
Site Admin
Posts: 8350
Joined: 05 Apr 2012 16:26
Location: Hamburg, Germany
Contact:
Re: Questions about variables

Post by radio42 »

The script of commands are executed as one block. If this block of commands triggers an async execution of new commands, there is still a first-in-first-out queue of commands to ensure a most linear execution. Thus, when the initial block contains a SLEEP command, this kind of blocks other commands.

If you really want that entire block no be independent, you can start your entire block with an ASYNC command. This created an independent execution queue in a new thread by itself.

Example:
Assume the following sequences:
ScriptA:
..command 1…
SLEEP 2000
…command 2…

Script B:
..command 3…
SLEEP 2000
…command 4…

In this case, the order is 1, 2, 3, 4. Assuming no command internally is executed async (as for the conditional command).
If you now start each script with the ASYNC command, the order should be 1,3 and then probably 2,4.

Post Reply