Author Topic: Blinking Status Leds? [solution explained]  (Read 19460 times)

Offline azslow3

  • Administrator
  • Hero Member
  • *****
  • Posts: 1679
Re: Blinking Status Leds?
« Reply #15 on: May 07, 2015, 12:04:16 AM »
so i thought about sharing the idea in form of a preset, because your example for the blinking Led´s was really helpful
(i think better than a complete preset, which is not simple to understand).
but my preset as a whole is far from complete and would cause more confusion then help -
so is there a way to get only some selected logic exported?
copying the preset and deleting the rest is even more work than creating it new.
There is no exporting/copy. It is in long term plan (I want be able to "copy" control as text, to put inside post for example and be able "paste" it back from text). But in practice, small ideas can normally be shown as separate preset build from scratch within 1-2 minutes.

Quote
And because the thread is still about Status-Led´s another question:

i´ve got 2 Led´s, which i want to show the "WAI"-position.
e.g. for WAI 1-8 i want Led1, for WAI 9-16 i want Led2, for 17-24 both,...
(could be expanded with blinking, but 32 tracks is enough for now)
how do i get the WAI-position into a state?
You will not believe, the question has puzzled me for a half an hour!  :o
But the answer is in attachment  ;)

Explanation. Open internal display (Show/Hide in the Options tab) to test.
We need 2 State Sets, both with the same states. One is "the real" one, which we are going to monitor and send LED when changed. another one is "temporarily" one, which we are going to set in monitoring every cycle.

Look at _funcWAI function (in Logic). It first try to set "WAI-16" track, if WAI is really 17+ it will be valid track. So, we set tmpWai to "17" and that is final action (in function!). If that is not valid, we check WAI -8 and set "9" if that was successful. Otherwise we set "1" unconditionally (so it works even the project has no tracks at all).

Now look at WAI Monitor in Logic. First is State Monitor for real "Where is WAI", in which we set LED/Display (note priority 1, we want it executed AFTER timer in the same monitoring cycle). But to make it work, we need periodical timer. So, we call _funcWAI BEFORE timer. In that mode, the function will be executed every time the timer triggers and set tmpWAI to what it should be. We could not just put all actions from _funcWAI there. We rely on "Final" actions, and final actions before Timer will prevent timer execution. In case of "final" in _func, it just exit the function, not the list.

Now look at Feedback WAI Monitor::Timer. We "map" tmpWAI to real one (with "Set engine state" set, so the changes are "permanent"). That is going to happened every time the timer works, but in case there is no change in "Where is WAI" state, "State monitor" is not triggered and so we do not send LED many times per second.

In Feedback WAI Monitor::State Monitor I update display. You are going to update LEDs.

I know, it is hard to understand. But you have asked for somehow not trivial plug-in reaction, and so the answer is also not trivial  :)

Offline MarKo

  • Power user
  • Full Member
  • *
  • Posts: 249
Re: Blinking Status Leds?
« Reply #16 on: May 07, 2015, 11:50:28 AM »
You will not believe, the question has puzzled me for a half an hour!  :o
But the answer is in attachment  ;)

hehe - i would´nt have asked if i had´nt thought that you (and AzCtrl) always have a solution!
But it´s nice to have questions, which can puzzle even you - at least for a short time ;)

Quote
I know, it is hard to understand. But you have asked for somehow not trivial plug-in reaction, and so the answer is also not trivial

I assumed that this will not be trivial.
So it´s a good example of what complex stuff can be done with your PlugIn. I can´t think of other solutions, which would allow the same.

For me, this means now quite some time & work to understand, but i think i got the main idea. I´m at the office now, i hope to try it in the evening.
And i´m sure i have to come back with more questions.

Many thanks for your continuing help!

Offline azslow3

  • Administrator
  • Hero Member
  • *****
  • Posts: 1679
Re: Blinking Status Leds?
« Reply #17 on: May 07, 2015, 04:19:54 PM »
"Rethinking" about my solution during the day (it was late evening yesterday when I have created it), I come to the conclusion that one "Where is WAI" Software Set is sufficient. So, you can replaces all "tmpWhere is WAI" with "Where is WAI" and remove that "temporarily" set.

"AZ Controller Expert exam" question: do you understand why?  ;)

Note that you still need the mapping in monitor, this time it looks really strange: "Where is WAI: Track 1-8 -> Where is WAI: Track 1-8, set engine state". That "fix" monitored value of this set to permanent one. That operation looks so ugly in case of many states in the set, that I have added such operation to the "Set State" Action (<Set to monitored>). But the version with the change is not released yet (can be found in the "Test versions" section).

Offline MarKo

  • Power user
  • Full Member
  • *
  • Posts: 249
Re: Blinking Status Leds?
« Reply #18 on: May 07, 2015, 11:39:23 PM »
i have a lot of "Rethinking" now!
so please, no expert questions today :o
it´s just working as you described (both versions) - thank you!
but i need to play with that example...

Offline MarKo

  • Power user
  • Full Member
  • *
  • Posts: 249
Re: Blinking Status Leds?
« Reply #19 on: May 08, 2015, 09:06:52 PM »
Ok, i´ve been "rethinking" now and hope to (partially) understand.
The "_FuncWAI" is completely clear, i think i perfectly understood the state-logic, no problem there.
As you know i could successfully implement some of my other wishes.

But i´ve still problems understanding timers and general sequence of actions.
E.g. i really can´t understand how/from where the action "WAI Monitor" get´s triggered first.
Of course there is timer at the and of the list - but how does it start initially???

If i build a list of actions just as "function" (like _funcWAI), i understood this just like a "sub" in programming logic. And as you have explainend, i can "exit" them (with final), and the "calling" Action-list will proceed. i hope i see this correctly?
But how/from where gets the list "WAI Monitor" called?

And regarding your "expert question": first problem is, i don´t understand why you initially introduced the "tmpSet".
And although you explained - esp. i can´t really get the meaning of "set engine state".
Even if the tmpSet is not necessary in this case - you must have had a reason to try it like that, which i´d like to understand.

This strange feedback event:
Quote
"Where is WAI: Track 1-8 -> Where is WAI: Track 1-8, set engine state".
That "fix" monitored value of this set to permanent one.
this triggers the "WAI Monitor"?
i get the same loop in my brain - how get´s this called first???

Offline azslow3

  • Administrator
  • Hero Member
  • *****
  • Posts: 1679
Re: Blinking Status Leds?
« Reply #20 on: May 08, 2015, 10:32:51 PM »
I have tried to explain how it works in the documentation, but that is really "advanced" topic. The knowledge of "conventional" programming does not help here, it really prevent you understand there are other approaches.

I think you understand, that Timer Monitor is executed periodically. But what you see in the "Feedback" Tab for it is the SECOND half of the execution process. Before it is executed, the system execute EVERYTHING what exist in the Logic Tab where the monitor is declared up to the monitor declaration. But you do not want it is REALLY executed, so it is executed special way, a kind of "dry run". Lets look at simple example:

Fader (Logic Actions List):
Select current track volume
Set value (from fader)
Set state "Is fader moved" to "Moved" (initially "Not moved").
Monitor parameter name (in Feedback action of which we for example put the track name to internal display).

What will happened in case we just periodically call "Monitor parameter name" feedback action without doing something special? It will always display "some" track name, let say the track which was current during the time we have moved the fader last time. But that is NOT what we want! We want display the name of track which WILL be modified WHEN we move the slider. So, real current track, even in case we have changed it by mouse in sonar.

So, we have to somehow execute the whole action list before calling our monitor actions, to select real current track every time we monitor.

But we can not do that directly... Select current track will modify system wide current parameter, Value will set the volume (to which value?), and "Is fader moved" will be set to "Moved". We have not moved the fader yet, so the result will be wrong.

And so, we create "virtual" environment just to IMITATE what is going to happened if the fader is moved. Select current track set temporarily "current" track, Value does nothing and "Is fader moved" is set to "Moved" temporarily as well. Then the Monitor actions are executed using this "future" environment and all these changes are discarded!

So, the example works as "naturally"  expected, showing real current track name without state or volume modification.

But in out case, we want to "save" the fact WAI was changed. So we need some way to say the system that some part of the "virtual"/"temporarily" environment should become "reality". And we do this by "Set engine state" flag, instructing that while we are still in "monitoring" we want set "real" thing.

Since you have programmed before, may be you can understand better by example how it is really written in C.
Each "Action" (for example Set State) has 3(!) different execution methods. And each State Set has 2(!) current states. So,
"Set State"::Logical execution method is "Set Current State to XXX"
"Set State"::Dry run execution method is if "Set engine" is NOT set, "Set Tmp Current State to XXX" (nothing otherwise).
"Set State"::Monitor execution method is "Set Tmp Current State to XXX" and(!) in case "Set engine" is set, also "Set Current State to XXX".

Note that "Logical" and "Dry run" work with actions from "Logic tab" while "Monitor" work for action in the Feedback list.

Without this technology, we have to double all actions (in logic and in monitor). And even then, we will need some kind of explicit "If the track is changed" thing. With this technology, the system check if the parameter WAS NOT changed since the last check ("dry run" is executed every time), and so "Parameter Monitor" WILL NOT call feedback actions if the track is still the same!

May be still sound crazy, but the result looks so compact and logical for me  :)


Offline MarKo

  • Power user
  • Full Member
  • *
  • Posts: 249
Re: Blinking Status Leds?
« Reply #21 on: May 08, 2015, 11:09:03 PM »
Quote
I have tried to explain how it works in the documentation,

i know, i also re-read it and i really appreciate your explanations, but it leaves me unsure...

Quote
I think you understand, that Timer Monitor is executed periodically.

Of course i understand timers, but something in this area is unclear to me: how is it started?
you won´t call every action-list with every timer-tick?
so why gets a specific action-list called the first time?
it´s clear for logical controls, which are bound to MIDI - but for independent _funcActions?

Quote
May be still sound crazy, but the result looks so compact and logical for me  :)

I´m sure that you invented some serious genius logic, because i see all the possibilities.
i just hate it that it´s not so logical to me >:(

Offline azslow3

  • Administrator
  • Hero Member
  • *****
  • Posts: 1679
Re: Blinking Status Leds?
« Reply #22 on: May 08, 2015, 11:43:38 PM »
Of course i understand timers, but something in this area is unclear to me: how is it started?
you won´t call every action-list with every timer-tick?
You will be surprised... Every action list with "Ultra" timer/monitor in it IS executed every CS timer tick (13 times per second)!

If you think that is a lot, imagine Sonar in fact execute all plug-ins (FXes, Synth, PCs, internal routings) much more times per second.
Just imagine, you want have 5ms "round trip time", then EVERYTHING should be executed at lease 1/0.005=200 times per second!.
And that includes complicate DSP algorithms of Guitar Amps and other non trivial CPU consuming tasks. Compare to that, single loop
in C which just checks some conditions is nothing. Even some complicated presets like MCU, with 100s of monitors still not "visible" on CPU monitor.

I wish Sonar had "asynchronous" API, so I could ask "please let me know when the current track is changed". That is not the case, the only way is to "scan" for all changes all the time. I have optimized many routine scans, and there are still many possibilities.

Quote
I´m sure that you invented some serious genius logic, because i see all the possibilities.
i just hate it that it´s not so logical to me >:(

Look at it from conventional point of view. You plan tomorrow morning. You set alarm clock for 8AM, you need 30 minutes to get up and prepare the breakfast.
Imagine you have the breakfast now... What time is it? Around 8:30AM. Is it dark outside? No, I see the sun.

Do you think the answers are "logical", even so it is 23:33 PM and it is dark behind the window at the time of PLANNING?

My system has exactly the same "look in the future" logic. You describe what WILL happened and then can use the information. In the example, you write "If I move the fader, current track is going to be (let say) 3". And so, you can ask the question "What is going to be the track name which volume is changed once I move that fader?".

The same is with WAI monitoring. You define "Logical Control". In case you activate it (which really never happens in out case, but you can assign it to some MIDI), it will detect where current WAI is. We put timer with question "What is WAI in case we activate that control?" and just save the result.


Offline azslow3

  • Administrator
  • Hero Member
  • *****
  • Posts: 1679
Re: Blinking Status Leds?
« Reply #23 on: May 09, 2015, 12:04:45 AM »
I can imagine (understand the process) how metal string of E-Guitar inducted current in the coil, which is then transfered to ADC which digitize it, digital elements put that information into the buffer, the buffer is composed to packet, the packet is transfered throw USB, chipset trigger interrupt, CPU switch to kernel mode, extract information and put into sound buffer, Sonar take the buffer, call VST, collect VST output, put it into buffer, ask kernel to transfer it throw USB into the DAC, which change the current on speaker and so change the magnet field, which trigger physical movement producing sound waves... But does everyone who want to use Sonar should understand the process in "down to the bit or even electron" details? Definitively not. "It works and sound nice", that is the only thing most musicians know  ;)

So, I propose you choose the level of AZ Controller "black magic" and do not dive deeper. I can try to explain you the process on any deepness level. But I think that will just destruct you from the final goal - making great music!

Offline MarKo

  • Power user
  • Full Member
  • *
  • Posts: 249
Re: Blinking Status Leds?
« Reply #24 on: May 09, 2015, 06:48:16 PM »
Hi Alexey,

It seems i can not describe my logical problem...
I wasn´t so much worried about performance, i know what´s going on to calc realtime fx and all the like (in videoprocessing even much more).
And i don´t want to bother you with unneccessary questions - if i can´t get it, i´ll take the "black magic" as it is. But i always like fully understanding, so i can build the logic myself, and don´t have to ask for every idea that i want to try.

So if you are not too bored, please give me one more try.
Could you list the real executing order in this WAI-Example?
I mean step by step the different cycles including priorities and feedback (just in short words).
Perhaps i see then the light.

Offline azslow3

  • Administrator
  • Hero Member
  • *****
  • Posts: 1679
Re: Blinking Status Leds?
« Reply #25 on: May 09, 2015, 08:09:51 PM »
My intention in no way was an attempt to stop your questions! You are welcome and I can write about the staff all the day long. I just do not want you get mad from my long posts in bad English  ::)

So, the execution order.
1. I have separate Monitors list with all monitors from all controls. So, every time Sonar call me (~13 times per second) I check either some monitor is "armed". For ultra, the arming is "1", Fast, Normal are "2", "6". "Once" and "State" monitors are not armed till requested explicitly, "State" monitor is armed when persistent state is changed (I have already explained that each State Set has "current" state which is system wide and persisting and "current monitoring" state, reset before any monitor execution to corresponding "current").
2. WAI Monitor::State monitor is executed once initially (armed during preset loading) and then stay unarmed till the state is changed.
3. WAI Monitor::Timer "Normal" is armed all the time, so every 6 cycles its arming counter drop to 0 and it is time to execute it.
4. The monitor execution procedure is the following:
4.a it takes the Logical Control (WAI Monitor) and execute it in "dry run mode", which means
4.b "State Monitor" action does nothing in "dry run mode"
4.c "Call _funcWAI" is called in "dry run mode", so
4.d WAI Track -16 set "current monitoring parameter" to "WAI Track -16 volume". If current WAI track is less then 17, the result is "invalid" and so "Selection" set "current monitoring state" is set to "Invalid". Let say current WAI track is 9, so that is the case.
4.e Set "Where  in WAI -> Track 17-24" is NOT executed since "Selection:Valid" Action Condition is not true.
4.f WAI Track -8 set "current monitoring parameter" to 9-8 = 1 (first track volume). That is Valid parameter, and so "Selection" is set to "Valid"
4.g "Where in WAI -> Track 9-16" is executed in "dry run" mode, that means "current monitoring" state for "Where in WAI" is set to "9-16". The action also has "Final" flag set, so the execution of funcWAI is terminated and returned to "WAI Monitor" list (from where it was called)
4.h "Timer" is reached, its Action Conditions is checked (it has no visible, but there is still one implicite Note On). We see that it should be executed. That is "Our" timer monitor, so "dry run" execution is terminated, with result that we should call the monitor.
4.i Feedback Action list of "WAI Monitor::Timer" is executed in "Monitor" mode (not logical, not "dry run", it is third!).
4.j "Where in WAI: 1-8" is not satisfied, so skipped.
4.k "Where in WAI: 9-16" is satisfied.  So, thanks to "Set engine state" flag, both "current" and "current monitoring" states for "Where is WAI" are set to "9-16". If "current" state was already 9-16, nothing happens. But if it was 1-8, it checks either there are some "Where is WAI" Set State Monitors. We have one! "WAI Monitor::State Monitor" is State Monitor for "Where is WAI". So, it is armed (with "1"). The action is "Final", so that stop Timer monitor execution. Since that is Timer monitor, it is rearmed with usual delay, "6" cycles in case of "Normal" speed.
5. If you remember, we are still in all monitors/timer check procedure. If our Timer and State Monitor have the same "priority", the order in which we check them is undefined. But since Timer has priority "0" and State Monitor "1" we know State Monitor is not checked yet in this cycle. So, the system check it.
6. We have armed State Monitor in 4.k, so it should be executed.
7. The system start "WAI Monitor" Logical Control "dry run" (yes, again!)
8. There is no actions before "State Monitor" itself, so its conditions are checked (satisfied) and Feedback actions are executed.
9. "Where is WAI" "current monitoring" state (which is the same as "current", as set prior "dry run" execution) is put to Text buffer
10. The Text buffer is displayed.
11. There is no other actions, there in no more monitors, State Monitor is disarmed, all monitors check cycle is ended.
12. The system continue to work from (3).

If you put all that in "C", the procedure is not going to be significantly shorter. We have to get current WAI, check it against our predefined values (9,17), check what we have displayed last time and in case it is different display new value. The preset has 11 lines (actions) for that. Can you write that procedure in "C" or other "normal" programming language in less then 11 lines?  8)

One more note. The location of the "State Monitor" in Logical Actions list is not important. We could put it into separate Logical Control. We could put it between "Call" and "Timer" or after "Timer" as well. But in that case, it its "dry run" the "Call" is executed again. In that particular example, it will not influence the result, but it will "waste" CPU cycles. That is why I always put "State monitors" as the first in the Logical Actions. Since it does "nothing" by itself (in all 3 modes!), it can not significantly slow down other "dry runs" (in this example, the Timer "dry run"). So I do not create separate Controls for that monitors which just "bloat" the number of controls in the list (there can be 100 or event more, one per real hardware message plus functions)

Offline MarKo

  • Power user
  • Full Member
  • *
  • Posts: 249
Re: Blinking Status Leds?
« Reply #26 on: May 09, 2015, 09:45:42 PM »
Thank you very much for this detailed description, I really think it helps (after studying it again).
You mention the position of StateMonitor: that was one thing, i was unsure and experimenting, because sometimes i had the impression that the result was faster (a Cycle earlier), if it´s after the call to _funcWAI.
But i´m sure that was just imagination, because it´s always async (can be anytime in the next 6 Ticks - correct?)

Now we´ll see how i can proceed with that infos.

Offline azslow3

  • Administrator
  • Hero Member
  • *****
  • Posts: 1679
Re: Blinking Status Leds?
« Reply #27 on: May 09, 2015, 10:52:57 PM »
Yes, State monitor has no influence on when system detect the change. Only timer speed. Also in case they have different priorities, the sequence of processing withing one tick is always predictable.