Global variable between presets

Sakis

2012-04-21 18:30:04

Hi,I have some trouble on a project I work in...

I have a preset named "preset A" in which "Note A" triggers a timer "Timer A" with 10ms delay and the timer triggers "Translator A" in which calculates a global variable "gw"
Also ,"Note A" when it has high velocity (pp>100) activates "Preset B" where I have "Translator B" which is triggered by "Timer A" and has a rule:
"if ge<=10 then gw=0".The preset B is deactivated after 100ms.

However it does not always works and I get in the Log window:
When it works:
...........................................
IN 1.2: On timer "Timer A"
condition satisfied: if ge<=10 then gw=0 *(this is from the rule of "Translator B" ,"Preset B")
assignment: (if ge<=10 then gw=0) = 0
OUT 0.10: MIDI 6 bytes: .. .. .. 90 26 00 *(this is the outgoing action of "Translator A" ,"Preset A" :.. .. .. 90 26 gw)
...........................................
When it doesn't work:
...........................................
IN 1.0: On timer "Timer A"
condition satisfied: if ge<=10 then gw=0 *(this is from the rule of "Translator B" ,"Preset B")
assignment: (if ge<=10 then gw=0) = 0
OUT 0.10: MIDI 6 bytes: .. .. .. 90 26 03 *(this is the outgoing action of "Translator A" ,"Preset A" :.. .. .. 90 26 gw)
...........................................
It seems in the second log window that "Translator A" calculated gw=3 and while "Translator B" in "Preset B" made gw to zero the output note had a velocity of "03" instead of "00".
Any help?I am on WinXP SP3 with MT version 1.72 1215.

DvlsAdvct

2012-04-21 19:56:27

Hi Sakis

That is a strange problem. Can you go through these actions and add a shot of the Log Window as a whole, so I can get a look at what's going on more clearly? There might be some sort of conflict happening within the timers which I can't see. If that doesn't work can you attach the preset so I can take a look?

Thanks
Jared

Sakis

2012-04-23 15:46:22

It seems to be a problem with my antivirus.I installed Avast and I had very high cpu usage.I disabled it but continued having the same issue(the calculation of "gw" although with no high cpu).But after a reboot(today) it seems working fine(strange).Thank you very much for your time and if I find a way to reproduce it I'll post it here.

DvlsAdvct

2012-04-23 16:03:31

Sure thing, Sakis. Good luck :)

Sakis

2012-04-30 16:27:28

Well...actually it wasn't the antivirus ,I checked again and I had to add a 5 ms latency on the outgoing action(which I totally forgot).So the problem still exists.
I made a test file ,so by pressing "shift" and messing with timers an outgoing message "B0 06 gw" comes.
I think it's timer's accuracy problem but it's only my opinion!
Attachments
TimerTesting.zip
(816 Bytes) Downloaded 257 times

DvlsAdvct

2012-04-30 16:46:56

Hi Sakis

I'll take a look at this tonight. :)

DvlsAdvct

2012-05-01 02:23:26

Hi Sakis

I'm not sure the example you gave me is of much help. The problem is all of your timers are linked together and tied to the same global variable. Although, looking at your example I think I may have figured it out.

The problem is that gw is getting set from a different preset which is calculating your global variable from a different set of translators. If you were to deactivate Preset A when Preset B is active that might solve your problem. Since Preset B is going off slightly later it might not be recognizing the numbers correctly. That make sense?

Sakis

2012-05-01 03:06:38

Yes it makes sense,since as you said "timers are linked together and tied to the same global variable"
I know it's rare case and I used other ways to make some calculations ,since I felt it wasn't straight-forwarding ,but shouldn't the debug window be more accurate and the "gw" take always one value instead of randomly changing?
I appreciate your help and your time :)

DvlsAdvct

2012-05-01 03:21:41

No no, I totally understand what you're saying. I think the problem is there are too many translators dictating the value of that one variable, though, at the same time. if you did the same thing but didn't have both presets open at once it might work. When I tested what you sent me I kept getting gw=127, mainly because the last preset set it as such, and the translator in preset 1 was setting it as 1. The timer delays you put in could have something to do with it as well.

If you send me the preset that's giving me the issue I think I could give you a hand cause it'll be an actual use-case, y'know?

And never a problem. This is why Florian keeps me around :)

Sakis

2012-05-01 13:31:54

DvlsAdvct wrote:And never a problem. This is why Florian keeps me around :)
Lol :D
DvlsAdvct wrote:.....When I tested what you sent me I kept getting gw=127, mainly because the last preset set it as such, and the translator in preset 1 was setting it as 1.
I get random values ,see the "printScreen" photo attached.
DvlsAdvct wrote:If you send me the preset that's giving me the issue I think I could give you a hand cause it'll be an actual use-case, y'know
I no longer use that kind of approach in the preset and I overwritten it,sorry!
DvlsAdvct wrote: The timer delays you put in could have something to do with it as well.
Yes,I had 2 timers hitting the same time a note out event with "gw" calculated(and as expected the note out was triggered once,nice!),but at the same time when a condition satisfied it enabled another preset which modified the "gw".As I said ,it was wrong approach but the log window got my attention and post it here....
Thanks again!
Attachments
TimerTesting.png
TimerTesting.png (27.71 KiB) Viewed 8385 times

DvlsAdvct

2012-05-01 15:58:25

I think a big part of the problem is the way these timers are being triggered. There don't look like there are many translators, so if you don't want to share the preset can you just type them up with the Code function on the forum? As I'm at my crappy day job I can look at it that way and see what's happening. If not I can look when I get home.

You aren't getting random values, though. You're getting 1 and 127, which seems to be set by the assignments in the timers.

It looks like the 1ms delay is what's causing the problem. So TimerA goes off and sets gw to 127, TimerB goes off, sets gw to 1 BUT it takes 1ms for the signal to go out and the conflict is causing it to read 127 as there's no delay on TimerA and it has already triggered, and the same thing going the other direction, where TimerA goes off but is conflicting with the 1ms delay. It might work better if preset 0 gets deactivated whenever preset 1 is turned on.

Make sense?

Sakis

2012-05-01 17:09:31

DvlsAdvct wrote:You aren't getting random values, though. You're getting 1 and 127, which seems to be set by the assignments in the timers.
Yes,by random values I meant not always 1 or not always 127.
DvlsAdvct wrote:There don't look like there are many translators, so if you don't want to share the preset can you just type them up with the Code function on the forum?
Sakis wrote:I no longer use that kind of approach in the preset and I overwritten it,sorry!
So ,it's not like I don't want to share it but I no longer have it!By the way could you tell me how to use the "Code function"(or give me a link for information?)
I thought I found a bug or something,that's the whole concept of the thread ,but since it's a normal conflict no worries :D

DvlsAdvct

2012-05-01 17:39:04

Yes,by random values I meant not always 1 or not always 127.
But I can't see that in the example you posted or the preset. I just get 1 and 127. The first example you posted I can see what you're talking about, though, I just can't replicate it.
So ,it's not like I don't want to share it but I no longer have it!By the way could you tell me how to use the "Code function"(or give me a link for information?)
I thought I found a bug or something,that's the whole concept of the thread ,but since it's a normal conflict no worries
I didn't know if you had a second or restructured example that was still giving you this issue, that's all. Can't fix a bug if we can't see it, is all.

And the "code function" is a button above the post entry window between Quote and List which:

Code: Select all

embeds your posts like this.  We use this to easily view MT code in the forum window
If you have any other problems we can fix please don't hesitate to bring them. Just trying to help :)

Sakis

2012-05-01 19:12:32

DvlsAdvct wrote:
Yes,by random values I meant not always 1 or not always 127.
But I can't see that in the example you posted or the preset. I just get 1 and 127. The first example you posted I can see what you're talking about, though, I just can't replicate it.
The first example is exactly the same with the second.Repeating my self :
In the picture you can see on line '000027':
IN 0.0: Keystroke: Shift
assignment: (gw=1) = 1
OUT 0.0: One-shot timer "testA": 0 ms delay
IN 0.2: Keystroke: Shift
assignment: (gw=1) = 1
OUT 0.2: One-shot timer "test": 0 ms delay
IN 0.1: On timer "testA"
assignment: (gw=1) = 1
IN 1.0: On timer "test"
OUT 1.0: One-shot timer "testB": 1 ms delay
IN 1.1: On timer "testB"
assignment: (gw=127) = 127
OUT 0.1: MIDI B0 06 01

So, the timer conflict is normal for getting 2 values instead of always one value(like the log in the picture until line '000026'.But I would prefer the log window be more accurate or show a warning or something.
Sorry for the trouble and thanks!

DvlsAdvct

2012-05-01 20:49:50

It's no trouble at all. We want this to work for everyone, y'know?

The problem I'm seeing, though, is that the variable is being set to different values in different translators, causing different values to be spit out. On line 000012 gw is being set to 127 from translator 1.1, and again on line 000025. Now, that 1ms delay seems to be causing a conflict in 000027 when it the next timer for 0.0 sends out again. ANd then again at 000036 setting the variable to 127, but the 1ms delay may be causing another conflict.

I don't think this is a bug, but instead an issue with the logic of the translators overlapping functions for each other on the same command. It also looks like, if your example preset is what this is coming from, that the same timer is triggering both of these values with no differentiation (the ge values from your initial post), so it's just overlapping again and again and again.

florian

2012-05-15 17:55:37

interesting thread. Such issues are called "race conditions" when a timer and other incoming actions compete for the same global variable. MT cannot really help you there, or detect these issues. In most cases, fortunately, the most recent value is the correct one, so everything works fine no matter if A or B managed to first set a global variable.

In your example, however, I suspect a different issue.

I cite the problematic aspect of your preset:

Code: Select all

IN 0.1: On timer "testA"
assignment: (gw=1) = 1
IN 1.1: On timer "testB"
assignment: (gw=127) = 127
OUT 0.1: MIDI B0 06 gw  with gw=1
Translator 0.1 is triggered (IN 0.1), then it sets gw to 1. Then it is seemingly interrupted by Translator 1.1 (IN 1.1), which sets variable gw to 127.
At last (as it seems), the outgoing action of Translator 0.1 is executed. You'd expect it to use the most recent value of gw, but instead it uses the previous value of gw.

I'm quite convinced this is due to MT's processing engine being multi-core:
What is actually happening is this:
Translator 0.1 is executed in the first thread. It sets gw to 1 and then constructs the MIDI message to be sent (using the current value of gw = 1). It then sends the MIDI message.
Concurrently (at the same time!) as the MIDI message is being sent, Translator 1.1 is executed (in a second thread). At the time the first Translator finished sending the MIDI message, the second translator has already updated gw to 127.

The log message of 0.1 of having sent is logged after the MIDI message is successfully sent.

I guess especially the last aspect can cause confusion, because the MIDI message is constructed before it's sent (obviously), but logged only after being sent. For me, this is the right way to do, because before it's sent I could only log "will be sent", which does not mean it's actually sent. And you're dealing here with problems in the sub-millisecond range...

Hope that explains! Still, this is complicated territory. Multithreading and concurrency is always a bit hard to get used to. But the benefits are faster processing, and better exploiting CPU resources.

Regards,
Florian

Sakis

2012-05-16 16:12:35

florian wrote:....
I'm quite convinced this is due to MT's processing engine being multi-core:
That explains all!Did some testing by restricting MT on one thread(never though of it!) and it runs as expected.Thanks!

florian

2012-05-19 00:27:46

nice
Florian