From previous definitions, we have:
* all required Software State Sets
* we get "BtnMonMode" set correctly when we changed modes (btw., Sets Surrent State can be changed on the Overview tab manually, the only way to test something till proper mapping to surface is done)
* in the Level mode, "Level(_Ch)" Set is updated from desired strip Level, with "Level( 8 )" implementing 2sec CLIP HOLD functionality.
So we can proceed with our 8 buttons. But to make the preset more organized, I have defined some functions:
_fBtnSelectPar(_Ch)
The LOCATE section, so I define what I want to monitor/control depending from the "_Ch".
All Actions are defined with "Note:Any", in this preset I need it working when the button is pressed AND when it is released. The reason is explained when we come to LEDs. When you do not need that workaround required for some controller, you can keep all Actions with default "Note:On" condition.
I first choose Strip "Strip" WAI + "<_Ch>" , "Mute" parameter. "Strip" defined currently focused pane (Track/Bus), WAI we see in Sonar, +"<_Ch>" will make the trick to select the strip depending from the button number. Note that what is counted is the State Number, starting from Zero (0). State name has no influence. So, when we set "_Ch" to "1" and then use "WAI" + "_Ch", we choose the first strip in WAI ("WAI" + 0). You can think differently, to avoid the confusion with mathematic. "Rename" States for "_Ch" from "1", "2", "3"... to "a", "b", "c", ... etc. When you say "WAI" + "a", you assume it is going to be the first strip in WAI, right? And it is so! If we use numbers "as is", "WAI" + 1 will be the SECOND strip in WAI. Mathematically correct, but not what we expect to get :o
To master advanced configurations in AZ Controller, you are going to use "state shifts" often.
People have a tradition to associate "the first" element with number "1", that is what you normally also see on surfaces/tracks/inputs/etc. But in arithmetic that creates a confusion between absolute position and "shifting". After you locate "the first" strip in WAI, if you ADD "1" to it, it is going to be the second strip. Only in case you add zero ("0") it STILL will be the first strip.
Programmers have "solved" that paradox counting from zero. So, "the first" track is "track zero". But for "other people", they are normally "converting to and from" both conventions. For example, MIDI Channel "1" is really transfered as "0". But I have not seen "MIDI Channel Zero" in any text so far. In practice, it is not even possible to transfer "MIDI Channel 16" as "16" since the place reserved in the protocol for the channel is limited, and maximal number which can be transfered there is "15".
State shifts in AZ Controller are always using State position and completely ignoring state names. You could define "_Ch" states as "1","1","1","X","Hello!","Hm...". That will NOT change the preset functionality. And States are counted from the top, starting from Zero (0). NAMING states from "1" invisibly makes "common human numbering" working arithmetically correct. So that "_Ch" = '1', WAI + "_Ch" in the TEXT form looks logical and produce expected result. But in case you specify the shift manually, f.e. "WAI" "+1", that is the SECOND WAI strip. The first strip is "+0" (default value when you configure). Keep that in mind.
For Solo mode I change "Mute" parameter to "Solo", while keeping located strip the same.
Finally for Level mode I put Current State of "Level(_Ch)" (it is "_Ch" dependent, so correct for "_Ch" in question) into Text. I will explain why and how it works later.
Note that in the Level mode, LOCATION with such definition is still "Strip Mute" (Level is not Solo, and the first action had no conditions). That is not a problem till we by mistake try to use it, and we do not.
_fBtnSendLED(_Ch)
That function is our feedback to the surface. It should indicate correct for current mode status for "_Ch" button. First we set "_LED" to "On" or "Off", depending from mode. I set it from LOCATION value first (we always call this function after previous). (almost) All parameters in Sonar are numbers between 0.0 and 1.0. "Mute off" is 0.0, "Mute On" is 1.0 ( "Pan center" is 0.5). So if we "map" a Set with 2 States (again, everything is calculated with the State position, not name), it will get the first State for values under 0.5, and the second State for values over 0.5. With Solo/Mute, "Off" in Sonar -> value 0.0 -> the first State in "_LED" -> "Off". In AZ Controller, it LOOKS like we map Sonar "Mute Off" to "_LED" "Off" directly, but behind the scene it takes described conversion route.
"Last action:Failed" is a fall-back case, I have promised to explain it before. Out LOCATION could be unsuccessful. F.e. we try to select "WAI + 5" track in a project which has only 1 track. "Undefined" location has "Undefined" MUTE value. So the previous Actions can not map the value since the value is unknown. So the previous action is "failing". That result is saved inside "Last action" System Set and is available for following Action Conditions. Note that it will be overwritten as soon as some other Action will be called, so you can use this Set IMMEDIATELY after the Action in question only.... With one exception: the Set is not overwritten in case there was NO attempt to execute an Action, that can happened if Action Condition was not met. And I have used that in the "_Level :: Level Monitor" feedback list. I was checking that comparison was successful first and set "Level(_Ch)" to "On" in this case. Then I am checking it was not successful, and set it to "Off". The trick is that in case "Compare" was unsuccessful, there was no attempt to "Set to On" and so "Last action" was not changed, staying "Failed". In case it was successful, "Set to On" was called and it has OVERWRITTEN "Last action". But setting some Set to concrete State is ALWAYS successful, so while overwritten, "Last action" will be still "Ok". If I change the order, so I first test for "Failed" and then for "Ok", it will NOT work! If "Compare" fail, "Set to Off" will be executed and it will succeed! Next check will be for "Ok", and it will ALWAYS succeed: either from Compare or from "Set of Off". So in practice, if you use "Last action" check try to do this immediately after the Action is question, till you 100% sure what you are doing.
Why have I mentioned before that "Last action:Failed" in some situations is better then "Selection:Invalid"? The second looks like more "solid" solution and is not position dependent... "Last action" is just more "bullet proof". Even in case LOCATION is correct, so "Selection" is "Valid", the Action in question theoretically CAN fail. Depending on the Action, it can call Sonar (f.e. to get the value). And Sonar can refuse to return the result... With existing parameters that happens rare, but happens. But what can happened more often is that AZ Controller "think" the parameter is valid (so "Selection" is "Valid"), but in reality is is not. There are several reasons for that, partially Sonar can report inaccurate information, especially during project loading/unloading, partially AZ Controller, to not disturb Sonar too much, is not collecting all possible information about parameters availability.
So, the practical consequence: "Selection:Invalid" and "Last action:Failed" are equivalent when used in the FEEDBACK (Sonar is asked during CHECK phase in this case, setting "Selection:Invalid" if that was not possible), while "Last action:Failed" is preferred method in REACTION. In reality the difference is so subtle, that I use "Selection:Invalid" even in REACTION, when "Last action" will significantly complicate the Action List.
Next two Actions work in Level mode and just map "Level(_Ch)" State to "_LED" State (overwriting whatever was set in the previous actions).
After that, depending from "_LED", i SEND MIDI to the surface. I use a "trick" with "<Use Ctrl MIDI>". It will only work in case LEDs expect the same MIDI messages as corresponding button sends. It is almost always the case, but there are exceptions (f.e. Presonus Faderport). The "Control" is the topmost control from which the execution is started. For REACTION, it is the control which is called on incoming MIDI, so we will use exactly that MIDI message (we obviously modify the value which we "send back"...). For FEEDBACK, that is the control where the Monitor is defined. Again, that is going to be our "Btn" with MIDI assigned. So, it will work inside this "function" Control correctly (which has no MIDI assignment by itself)
Notice "Note:Any" conditions for all these Actions. I have mentioned before that I implement a workaround needed for many surfaces. And I will explain that, but not yet.
Next Actions duplicate "_LED" indication to AZ Controller internal Display. Here you can see possible solution to send different "On" messages in different modes. In case your buttons/pads have multicolor LEDs, you can use that logic to let say show "Green" on muted, "Grey" on solo, "Red" on record armed. Internal Display has no indication problem, so no workaround is needed and these actions have usual "Note:On" condition.
_fBtnSetValue(_Ch)
Here we first set the value in Sonar (the function is called after "_fBtnSelectPar(_Ch)"), but only for Mute and Solo modes.
And then we call already described "_fBtnSendLED(_Ch)". We call is as a workaround here, but there is not yet time to describe why.
Notice that Set Value Actions have "Note:On", while "SendLED" has "Note:Any" condition. We set the value only when the Button is pressed (and do not set is when the buttons is released).
Continued in the next post...