AZ Controller plug-in for Cakewalk SONAR > Tutorials

Buttons or Pads with LEDs: mastering the feedback and software modes (advanced)

(1/3) > >>

Warning: that is an advanced material. I assume the reader has already went throw Quick Start, ACT MIDI Explained and the User Manual. This is not a step by step tutorial, it is an explanation how to use AZ Controller to make complicated configurations.

A part of the tutorial explains general approaches for integrating surfaces into DAWs, with possible tricks, usual problems and workarounds. MIDI Surface integration is never "automatic", if you "plug&play" your controller and it works perfectly, SOMEONE had to spent a lot of time to allow that. This tutorial explain what this SOMEONE had to do with buttons or pads and LEDs (near/under) to make it work smoothly for the end user. With AZ Controller you can dive into the process with minimal or no prior programming experience, dive deep. This tutorial supposed to help you make nice working surface for the time you are back to the music creation, instead of horror memories about useless spent night and a hardware brick wasting your desk space. The explanations are not easy to understand, I know. A button is always just a button, on lamp or on most sophisticated surface. Making in "smart" is not a simple task.

Note: you need AZ Controller v0.5r4b344 or later to use attached preset.

The goal
In "uni-directional" approach, when we want some controller does something inside the DAW, we deal with "what to do when XY is pressed/turned/moved?" question. As soon as our controller has some "feedback", f.e. LEDs, rings around encoders or moving faders, we should define the answer for additional questions: "what to do when something is changed in Sonar?" and "how to correctly glue the indication done inside the device with the indication we want?"

Attached preset defines 8 buttons (Btn1-8) for strips, 2 "bank" (BankUp/BankDown) buttons  and 1 (ModeSwitch) button. It is assumed all buttons are "momentary", so they send "On" when pressed and "Off" when released (either Note or CC). In case you do not have such controller, you can use any MIDI keyboard keys for tests. This tutorial is about the "feedback", but you can use AZ Controller Display (from the Options tab) to see the effect. In case you have some controller with buttons/pads which have LEDs and these LEDs are "reacting" on the same MIDI messages corresponding button/pad is sending (f.e. AKAI MPK Mini, MidiMix, etc.), the preset should work "as is". Otherwise you will need to modify "LED sending" actions, I will explain that later.

The preset functionality
* 8 strip buttons control and indicate Mute status for 8 WAI strips
* strips follow strip focus in Sonar, so if you switch between Tracks and Buses in Sonar, WAI and controls will follow
* short pressing ModeSwitch button switch between Mute and Solo
* long pressing ModeSwitch (more the ~0.5sec) switch 8 buttons to "level monitor" mode for the strip in focus. The rightmost button/LED is supposed to be "CLIP", so it "holds ~2sec" (to better expose the signal clipping). ModeSwitch LED is On in Mute, Blinking in Solo and dark in Level mode.
* BankUp/Down buttons move the WAI region (and so controlled strips) in Mute/Solo modes and change focused strip in the Level mode. If BankUp is pressed with BankDown, the the mode is changed: Mute/Solo/Level/Mute/Solo/etc.

AZ Contoller concept
The preset uses all "advanced" features of AZ Controller, including Functions, Dependent Software State Sets and Monitoring. So before I start explaining the preset, I want outline the "big pictures"of AZ Controller logic.

If you are working with Sonar, even in case you has never "programmed", you have to deal with the "signal processing" concept. When you add several FXes into FX bin, turn on some ProChannel modules or  insert a Software Synth, you establish some signal processing chain.

There are several properties in that concept, and even if you have never thought about them explicitly, you probably perceive them as "natural" and use them all the time:
* audio FXes deal with an audio signal  on there input and produce an audio signal on there output, normally modified. MIDI FXes do the same with MIDI signals. A Soft Synth takes MIDI signals as the input and produce an audio signal as the output. Guitar processors have audio AND MIDI signals on input.
* you organize FXes into FX bins. Each strip (and each clip if required) has a separate FX bin.
* FXes can work in a sequence, in parallel or "cooperative". When you add EQs to 2 independent tracks, they are working parallel and independently with different signals. When you put EQ and then Compressor into the save strip, they are working in a sequence. And you probably have noticed that the order is important, EQ before Compressor and EQ after Compressor, even with the same settings in both, produce different result. When you do side chaining or insert a "console emulator", effect instances in different strip start influence each other, they "cooperate" to produce the sound you want.
* you can group FXes into FX chains and then use such a chain as a FX

When dealing with Conrtrol Surfaces:
* as the input you can use MIDI/OSC signals and many Sonar parameters (strip volumes, transport state, now time, automatable FX and SoftSynth parameters, etc.) and as the output you want to get changes in Sonar parameters (transport start recording, volume on some track is lowered, cut frequency of of FX is increased, etc.), execution of Sonar commands (the same as keyboard shortcuts and menus, like saving the project, undo, zoom, etc) and in case you surface has feedback (LEDs, display, rings on encoders, motor faders) you want some MIDI/OSC is sent back to the surface. There are many limitations in Sonar, so you CAN NOT use as the input/output: any audio signal (except monitoring current level), any information recorded on tracks (recorded MIDI or audio, clip boundaries, FX bins in clips, etc). And while you can send MIDI to external device, you can not "inject" it into MIDI track (without using external MIDI loopback).
* on place of FX for musical content processing, AZ Controller has Actions. The same way as FXes can be simple or complicated, Actions also can be simple (f.e. "Play" command) or complicated (f.e. get current value for strip Volume and adjust it by 1%). You put FXes into FX bins. You put Actions into Action lists.
* Actions inside one Action list are executed in a sequence. As with FXes in a bin, the order is important since next Action can use the result of the previous Action. Unlike FXes, each Action can use any available information as the "input". Different Action lists are "independent". But you can use the result from one Action list in another, as long as it is made persistent. As with side chaining and audio/MIDI loops, you should take care there are no strange dependencies, especially "looping dependencies". The effect will be the same with with a mic pointing toward the monitor once you turn echo on - in case of Control Surface, you will get no crazy sound, but Sonar itself will become "crazy" (and it can crash).
* as with FX chains, it is possible to use a list of Actions as one Action. But implementation is a bit different:

"Functions" in AZ Controller
In Sonar, if you want to use a list of FXes as one FX, you should explicitly put them into "FX chain". You can not just in FX bin of the Track 2 say "please use the whole FX bin from Track 1" (could be handy, is not it?)

CW distinguish between "FX Bin", "FX Chain" and "ProChannel". But in practice, all three are just lists of FXes. In AZ Controller, there is no separate "FX chains" to use as a distinct FX. Any Action List can be used as an Action in another Action List.

There is special Action "Call". As the only parameter it has the name of some other Action List.

After some degree of complexity, "functions" (as FX Chains) can be time and brain savers. As an exercise, you can "unwrap" (copy the function content into caller's list) f.e. "Btn1" control. You will see that while avoiding such thing as a "function", that makes the preset almost unreadable.

For programmers: "functions" in AZ Controller have no parameters and return no value (except "success" when the function execution was ended with an Action with "final" flag). I still name them with "parameters", f.e. "_fBtnSetValue(_Ch)", just to comment that this function uses "_Ch" Software Set.

Action lists and Logical Controls
In AZ Controller, you can find Action Lists at two different places. In the Logic tab and in the Feedback tab. I will explain the different later, once I clarify what is Monitoring, but it is worse to mention already now that an Action list is either a property of Logical Control or a Monitor. And only Logical Control Action List can be used as a "function" (even when called from the Monitor Action List!)

Logical Control IS an Action List. It can have an assignment (MIDI and/or OSC) and it can be attached to some Hardware control (throw Hardware Context). Why Hardware Control is not the same as Hardware Context and Logical Control is yet another "thing" is explained in the Manual (in short, physical Surface Hardware Control can send different MIDI signals in different Hardware presets, but for many operations it is required to know that both signals are coming from the same knob/slider). In this preset, that is not the topic, all Hardware Controls have exactly one Hardware Context with Logical Control attached to it.

The "primary" purpose of Logical Control is to define the reaction on incoming MIDI signal (so what to do when you operate some control on your surface). For readability, such controls are named without "_" at the beginning, f.e. "Btn1".

The "secondary" purpose of Logical Control is to be used as a "function". In the preset such controls are named starting from "_f", f.e. "_fModeSwitch()".

Logical Controls can be used for yet another purpose, for Monitoring. In this case, I name them starting from "_" but without "f" following, f.e. "_BtnMode".

Important, that you should assign some MIDI to all control WITHOUT "_" and you should NOT assign MIDI to any control WITH "_".

Continued in the next post...

Monitoring concept in AZ Controller
Monitoring in AZ Controller is difficult to explain and understand. "Monitors" and how they work have no direct analogs in conventional programming, so programming experience will not help to understand it (till you have programmed in Forth, Prolog and worked with LabVIEW).

Unfortunately, the concept is essential to create complicated presets in AZ Controller. So, please read this part twice, ask questions, try some simple monitors till you are convinced that you have more or less learned it.

Fortunately, the concept just mimics "common sense". It is not coming from any "theoretical Informatica"/"the theory of controlling systems" (as some other "projects" I have to deal with...). So I will start with musical examples.

Let say you want record some vocal with a mic. You first LOCATE the mic, then you CHECK that the mic is connected and in case it is not connected, you CONNECT it. You can not check the mic connection before you have found the mic and you do nothing (will not reconnect) in case it is already connected. So the sequence in which you operate is fixed (here it is obvious, but in AZ Controller you just see some "text" which describe location, check, conditions to do something and what you want to do. Too easy to put things in wrong order and then spend hours looking at the result...)
Then you start recording the vocal and adjusting the input gain. You first OBSERVE current level, then CHECK it is ok and if required CORRECT it. The difference with the first example is that you do this PERIODICALLY. Usually with several ITERATIONS of several OBSERVE/CHECK/CORRECT sequence.
When you are about to physically change the gain, you OBSERVE the current value of the gain for the channel to which you mic is connected and then ADJUST  the current value of the gain for the channel to which you mic is connected

Another example. You want cut some resonance frequency on snare. You OBSERVE the sound while TEMPORARY busting narrow band change the frequency to LOCATE required spot, CHECK that is what you was looking for and then ADJUST PERMANENTLY by cutting 1-2dB, widening the band. Interesting there not only OBSERVE/LOCATE/CHECK/ADJUST sequence but also the fact that during this process involves TEMPORARY EQ parameters modification, which you do not want see persistent inside your project.

Lets look at that examples from Control Surface perspective. What we want it does for us?
First we want to see current level, which we can not adjust directly. So, in case we have some level indicator on our surface, we want:
1) LOCATE the current level for the channel to which you mic is connected
2) CHECK it is different from what we have shown the last time on our surface (as with re-connecting mic, we do not want "redo" things)
3) (if the level is different) SEND new level to the surface

In case we have an encoder on our surface for digital gain control, with a ring indicator, we probably want:
1) LOCATE the current value of the gain for the channel to which you mic is connected
2) CHECK it is different from what our ring already shows
3) (if the value is different) SEND new ring value to the surface

And once we want adjust the gain, when turning the encoder we want:
1) LOCATE the current value of the gain for the channel to which you mic is connected
2) ADJUST that value, using direction information sent from the encoder

So we have 2 cases: we just want monitor something and we want monitor and adjust something.

Now look at lengthy text in italic in the LOCATE section of the last 2 lists. Lets combine both lists:
1) LOCATE the current value of the gain for the channel to which you mic is connected (if we are REACTING on encoder, we want that location is done for "real", remember the example with EQ, if we are just OBSERVING, we want the location is TEMPORARY)
2) FOR OBSERVATION ONLY: CHECK it is different from what our ring already shows, if yes -> SEND new ring value
3) FOR REACTION ONLY: ADJUST that value, using direction information sent from the encoder

In AZ Controller, you can use exactly that sequence (look at "Btn1" Logical Control definition in the preset). How AZ Controller "knows" either we want OBSERVING or REACTING? It depends from WHERE this list is called:
* When it is called as the REACTION on incoming MIDI signal from the encoder, the list is executed in REACTION mode (saving LOCATE result permanently and ignoring CHECK and corresponding SEND).
* When it is called PERIODICALLY during the monitoring cycle (see later), the list is executed in OBSERVING mode, not saving LOCATE result and ignoring ADJUST section (even if you put it before CHECK).

Execution modes
Lets look at execution modes more systematically. Two of them I have already mentioned, there there is the third one... In examples before, "SEND" is executed in the FEEDBACK mode. Corresponding Action Lists are defined int the Feedback tab, but "functions" (which are Logical Control Action Lists) can be called from there. Important that ALL Actions are executed using current mode, independent where these Actions are defined.

So we have:
1) REACTION mode. Used when the execution is triggered by incoming MIDI signal
2) OBSERVATION mode. Used during monitoring cycle for actions which stay before the CHECK.
3) FEEDBACK mode. When the check is passed and the Feedback list is called.

Logical Control Action List can theoretically be executed in ALL 3 modes: as the REACTION on MIDI or as a function called from such reaction list; as OBSERVATION when CHECK (the Action name is "Monitor") is defined inside the list; as FEEDBACK when called as a function from the feedback section.

Feedback Action List is ALWAYS executed in the FEEDBACK mode. Feedback lists can not be called as functions and there is no MIDI assignments for them.

Every defined in AZ Controller Action behave differently in different execution modes. The rules are:
1) in REACTION mode, all Actions except "Monitor" have effect, Location and Software Set State changes are permanent. "Monitor" (CHECK) Action is ignored in this mode.
2) in OBSERVATION mode: "Monitor" Action is special, since OBSERVATION is called for each Monitor separately, only Actions which stay BEFORE the Monitor is question are executed. All other "Monitors" are ignored. All Actions, except Temporary Location selection, Temporary Current State changes and Temporary Text are ignored.
3) FEEDBACK mode is similar to OBSERVATION, but some additional Actions are allowed (like MIDI send). In general, only Actions which modify something within AZ Controller or send MIDI/OSC are allowed and all Actions which set something in Sonar are ignored.

Special is the interpretation of "Set engine state" flag, for Actions which have it:
1) in REACTION mode it is completely ignored
2) in OBSERVATION mode, Actions with this flag set ARE IGNORED (without that flag, they modify Temporary Current State)
3) in FEEDBACK mode, Actions with this flag set modify PERMANENT Current State (while still using Temporary Current State on the Input and modifying it as the result).

Except rare cases, everything should work "as expected". For example, in the LOCATE/CHECK (and may be SEND)/ADJUST list mentioned before, AZ Controller will do what was described in the brackets without "extra steering". "Set engine state" in the FEEDBACK will be usual "manual" adjustment to the automatic (the system just can not decide on itself either some State change should be permanent or not), but I had only several very special configurations where something else was required (like "Set ending state" in OBSERVATION or "looping back" MIDI in FEEDBACK to execute Sonar Commands as the reaction on monitoring).

Yet another controlling case
There is the third case of OBSERVING and ADJUSTING I want to mention: when we want monitor something but adjust something else. F.e. when we send some command which produce no feedback ("undo"), but do not want "waste" LED and use it for different purpose (as a part of level monitoring). In the preset there is such case with the ModeSwitch: it indicates its own "status" and it changes other buttons mode. ModeSwitch status depends from BtnMode, but they are not the same. Such case can be seen as a "control without feedback" combined with "monitoring only". And as such is not "different" from the first (just monitoring) case. It can be confusing since there can be 2 different LOCATEs:
In fact (1+2) are independent from (3+4). The only common part is the relation to physically close to each other control and LED (and so, most of the time, MIDI signal used).

Continued in the next post...

Monitoring cycle
How fast you can check parameters in the DAW? Do you able to read number when they are changing once per second? What about 10 times per second? Keep the answers in mind while interpreting following numbers. Also note that it is not about the audio discretization frequency, not even about reaction on your keys/controls (the REACTION is executed is "semi real time").

Monitoring happens PERIODICALLY. It happens every 75ms (or whatever set in Sonar preferences, with lower limit of 50ms. But PLEASE do not change the default. That can confuse ALL Control Surface plug-ins). When you define a Monitor, you also specify its "speed". The "Fastest" speed is "Ultra", so every 75ms or ~13 times per second. Lets call such period a monitoring cycle.

Each cycle, AZ Controller checks either its time to execute OBSERVATION/FEEDBACK for each defined Monitor. All Monitors except "Timer once" (executed on special request with "Reset monitor" and defined delay) and "State monitor" (executed at next possible occasion in case the Current State of the specified Software Set is changed) have the "Speed" parameter. "Ultra" means every cycle. All other "speeds" are slower.  In reality, with modern computers and what we do with control surfaces, that is negligible compare to any single FX in your project. So in the preset you can see that all Monitors are defined with "Ultra" speed.

If it is time to execute the monitor, AZ Controller start the OBSERVATION execution of the Logical Control Action List where the Monitor is define, till the Monitor Action in question is reached. Then monitor conditions are checked and the Monitor Feedback Action List is executed when desired (using FEEDBACK execution mode).

For each Monitor the OBSERVATION execution happens in "sane" environment,  reverting changes in the Temorary Current States (Text/Location) may be made by observations/feedbacks already checked Monitors to the current Permanent Current States (Text/Location).

Each Monitor is checked/executed only ONCE during one "cycle". So if some Monitor is already checked (and may be executed), it will not be checked again during the same cycle, even in case its "monitoring conditions" are changed. So the next important topic is:

Monitor priority
This parameter defines in which order monitors will be checked/executed during ONE CYCLE. Again, the "speed" defines how often (in cycles) the monitor is executed and the priority order monitors within one cycle.

All Monitors with priority "0" are checked/executed before Monitors with priority "1", and so on. You would normally organize Monitor Priority depending from which Software Sets are used during Monitoring and either these Sets can be changed by other Monitors.

F.e. in the preset we are monitoring currently focused in Sonar strip type. And we save the result into "Strip" Set (permanently!). This monitor has priority "0" since there are no dependencies. Then we use "Level" monitor to set "Level(_Ch)" Set. Which strip we look at depends from "Stip" Set, so this monitor has priority "1". Finally, "BtnX" Monitor depends from "Strip" (in Mute/Solo mode) AND from "Level(_Ch)" (in the Level mode) Sets, so we should set its priority to "2".

Monitors with equal priority are executed in "random" order. If you do not set the priority correctly, sometimes your preset will work correctly and sometimes not. Think about side-chaining wrong track, when it is almost in sync with intended (but not always).

Monitor CHECK procedure
So far I have described that when its time to check the Monitor (depending from its Speed in cycles and the Priority withing a cycle), Logical Control Action List where the Monitor is defined is executed up to the Monitor Action using OBSERVATION mode. What happens as next?

The system should decide either we should execute Monitor's Feedback Action List or not, depending from the observation results and the Monitor specification.

First of all, Action Conditions for the Monitor Action are checked. Actions during the OBSERVATION could change current States for Sets in question (as explained before, these changes are TEMPORARY and DISCARDED after monitoring). If some condition is not met, the Monitor CHECK is not executed. The procedure ends (for this Monitor) like the OBSERVATION was not executed at all, so nothing is "saved".

If the Action Conditions are OK, the Monitor enters the CHECK procedure. What is really checked is define in the Monitor options:
* for "Timers" nothing is checked, the decision is always "EXECUTE FEEDBACK".
* other Monitors check specified values, either parameter values, names or Automation flags, the text (for Command Monitor) or strip level. The check is done for CHANGES. If the value in question is CHANGED (compare to the last time it was CHECKED), the decision is "EXECUTE FEEDBACK". If it not CHANGED, the FEEDBACK is not executed.

CHANGED means the following:
1) if that is the first time the Monitor is CHECKED, the value IS CHANGED. That correspond to the "initialization". The Monitor can be "reset" at any time (with Monitor Reset Action) to "forget" the result of previous checks.
2) if Sonar parameter in question is different, the result IS CHANGED. Even in case the value is the same. F.e. if you monitor focused track Solo and you switch focus to another track, with the same status for Solo, the result is still IS CHANGED. The same in case ACT Dynamic Mapping focus is change to different plug-in.
3) if the type of the Monitor is changed (used in the example preset), the result is always IS CHANGED.
4) finally, if the the value is different, the result is also IS CHANGED.

Reversed: the CHECK is negative and the FEEDBACK is not executed in case the type of the Monitor, the Parameter (including originating Strip/FX/etc) and the value are the same as during the last CHECK.

Monitor FEEDBACK execution
If the decision during the CHECK was "EXECUTE FEEDBACK", Monitors Feedback Action List is executed in FEEDBACK mode. Note that Temorary Current States / Text / Location are NOT reverted between OBSERVING and the FEEDBACK. They are reverted AFTER the FEEDBACK.

Are you puzzled by my monitoring explanation? Please take a break, may be read the text one more time next day. Read the rest, check the example preset.

Dependent Software Set
The last "advanced" feature used in the preset. Simple Sets have only "one Current State". Dependent Sets have different "Current State" for each State in another Set.

For programmers: these are one dimensional arrays  8)

For other: let say you want define "Plugged" Set with States "Yes" and "No", which describe either you instrument is plugged or not. You can do this by defining different Sets: "GuitarPlugged", "MicPlugged", "'KeyboardPlugged". Each from these Sets can have own current State. But you also can define the Set "Instruments", with "Guitar", "Mic" and "Keyboard" and say the (one) "Plugged" set depends from the Instrument. So you can then use:
Insturment -> Guitar
Plugged -> Yes
Instrument -> Mic
Plugged -> No

That approach reduce the number of Sets and simplify function definitions, as you can see in the example preset.

Continued in the next post...

The explanation for the preset

As I have written, I am not going to describe everything in "click by click" mode, assuming you already know how to create controls, states, add actions, etc. But I will try to explain in which sequence I have created this preset and WHY I have defined things that way.

This example is not of kind "do it like me". That is just one from possible approached to achieve the goal stated at the beginning.

I normally start by defining the "Strip" Set, with "Track" and "Bus" States.
Then I define "_Strip" Control with "Timer" and the "Strip" State Monitor, first with "0" priority, second with priority "1" (it depends from the first) and "Ultra" speed. All Monitors in that preset have "Ultra" speed, so I will not mention that again (when you add Monitors they have "Normal" speed by default). 

In the Feedback for the Timer, I "Recall" "focused" Strip, saving its strip type into the "Strip" set (do not forget "Set engine state", we are in the FEEDBACK mode!). With that definition, "Strip" (Track/Bus, Sonar does not expose hardware output focusing to Control Surfaces) is always the same as currently focused in Sonar strip type, which can be changed by Mouse, this or other Surface.

Save/Recall Action is a powerful tool which can be used for "scratch ACT" and other "on the fly" control assignments. Here it is used just to follow the strip type focus.

In the "_Strip::State monitor" Feedback, I set WAI following the Strip type. Note that both Actions just set the WIDTH, but not the position of the WAI. Also the first WAI is "initial" (not really required since the State monitor will be called after loading, but historically I set it...). Without WAI indication, it is hard to predict what your surface is currently controlling. Note that you can control ANY strip, not only WAI strips. But that is a good idea either use "Focused" or "WAI related" strips since both can be quickly changed by mouse.

In this preset we will use several Sets
"_Ch" set to simplify the configuration using "functions". With States 1-8 (or whatever number of strips you are going to control in parallel). The name prefixed with "_" to remind me the use of this Set. Such Sets, while they have permanent Current State, I use locally only (I do not use permanent Current State)

"Level(_Ch)" with "Off"/"On" States. Note that it DEPENDS from "_Ch". So we effectively have the place to save current LED situation for each button.  Usually it is not an issue to just update LEDs when required, even if they already have "correct" lighting. But unlike "stable" parameters like Solo or Mute, the level is normally changed all the time during recording/playback. And I do not want to update all LEDs all the time. If you have some old big surface with hardware MIDI connection, like old Digital Mixer, updating all controls all the time can be a big issue, not only MIDI throughput is limited but also internal hardware/firmware can be saturated by incoming messaged.

The next Set is "BtnMode". As specified in the Goal, with "Mute", "Solo" and the "Level". It can be extended with "Echo", "Rec.Arm", etc. with minor modifications in the preset.

"BtnMonMode" is special. When it has States, the always have the meaning "Value", "A.Read", "A.Write", "Command" and "Level", in that order. Names of states are not important, just the position. This Set will control which TYPE button monitors have at any particular moment. I use "Value" for Mute/Solo and "Command" for Level (not "Level" type, as I have started to explain for "Level(_Ch)" Set). If States are fixed, you can ask why this Set is not pre-defined. In this preset I use one "button group" only. But in more complete presets there can be several groups, and each can have own Monitor type.

"_LED" "Off"/"On" is used temporary to decide either turn some LED on or off. It is possible to write all related Action Lists without using this Set, but there will be more Actions. Again, just "code optimization".

"ModeSwitch" "Off"/"On" is used to detect "long press" of the ModeSwitch button (explained later).
"ModeSwitchLED" "Off"/"On"/"Blink_On"/"Blink_Off" is what ModeSwitch LED should do. It will correspond to "Level" (no light), "Mute" (continuous light) and "Blink_On" (solo). "Blink_Off" will be used later in the ModeSwitch implementation.
"BankDown" "Off"/"On" is used for yet another way to switch modes.

Continued in the next post...

"_Level" Control
This control is for monitoring only, it has no MIDI assigned and it is not used as a function. The same as with "_Strip". But it has 3(!) different Monitors.

In the LOCATION section (used by 2 of 3 monitors) I choose Strip "Strip" <current> Volume. The Set "Strip" has currently focused strip type (as defined before). So it is going to be always in sync with focused strip in Sonar.

"Parameter Name Monitor" (priority "1", since it has dependency from "Strip" changed in "0" priority monitor) is there to detect focused strip changes. "Parameter Name" is always "Volume", but as I have already explains, the Monitor will detect strip changes. Note that we can not use "Parameter Volume Monitor", since we do not want triggering on volume change. In its feedback list I "reset" "Level(_Ch)" for "_Ch" = 8 to "Off". The reason is: I keep LED on button 8 lighting for 2 seconds, even when current level is lower. Without this monitor, when you change strips and previous strip was clipping at the time of switch, "CLIP" will still light for up to 2 seconds. Not nice.
I put "BtnMode:Level" condition for this monitor since we need it during Level mode only (preventing "useless running" all the time). When the strip is changed after we left Level mode, this Monitor is still activated once we enter Level mode again. Remember CHECK explanation, if Monitor Conditions are not met, nothing is remembered, so this Monitor will still have the old Strip as "last checked" all the time till the mode is Level again. That is yet another example of "logical" behavior of AZ Controller, to reduce the number of tweaks you have to do manually. Unfortunately, Sonar is not logical in many cases, as you can see in the:

"Parameter Level Monitor" (priority "2", "Strip" dependency, but more important I want it AFTER "Parameter Name" monitor possibly reset CLIP, also it should be after "BtnMode" Set monitor). Here we monitor the "level" of LOCATED (so currently focused) strip. In the feedback list, I use "Compare" Action to decide either some LED should light from the "Value" System Set (I write a bit more about "Compare" Action result in the "fBtnSendLED(_Ch)" explanation). The "Value" is mapped to monitored parameter value, in this case to the level value. You can adjust numbers as you wish. Simpler approach, shown in the Level monitoring tutorial, is less tunable. Note that "Value" is set to 0 in case monitored parameter is invalid (f.e. if there are no strips at all in the project), which works fine in our case. In more complicated case (f.e. to display "---" for strip name when there is no strip), "Selection:Invalid" condition can be used (or even better by failed status for parameter value mapping, as I explain for the button feedback later). For "_Ch":8 Actions are a bit different. We do not set "Level( 8 )" to "Off" in case it is "On", we keep "CLIP" holding. And in case the level is still "clipping", we reset the "Timer" described later to trigger after ~2 seconds. In case during these 2 seconds we again have "clipping" condition, we again reset the "Timer" to 2 seconds. Monitors in AZ Controller do not have "time memory" (on purpose), so the "Timer" will not trigger after the "first" 2 seconds, it will trigger only 2 seconds after we reset it the last time (in case we do not reset it again).
As with strip change detection, the first idea will be set "BtnMode:Level" condition. But with Level monitor the result from that condition is strange. When set, once we leave Level mode, AZ Controller immediately stop asking Sonar about the level. Interesting that Sonar "remembers" the level we have asked the last time, and "slowly drop it", the same way as in the Sonar level monitor, once we start to ask for it again. Independent from the real current value! Let say we have clipping on Track 1, which we can see on our Surface. If we switch to Mute mode, then move Track 1 fader all the way down (so the level is now <<-48db) and then turn Level mode again, our Surface will show us CLIP! Slowly dropping to silence... I do not like that, but that is how Sonar is working. So I monitor the level all the time. That in turn creates a "side effect": not only we ask Sonar for level all the time (which as I have explained we can not avoid), but we also set "Level(_Ch)" all the time, trigger timer, etc. I do not like that. So I check the mode INSIDE feedback (first 2 feedback actions), and do nothing except in the Level mode. Do you understand the difference between setting the Monitor Action Condition and checking the same condition inside the feedback? In the first case we are not CHECKING monitored parameter, so not Asking Sonar and not saving the result. In the second case, we do all that, but do nothing as the feedback. In the workaround complete? Unfortunately now.... since with do real parameter CHECK and THEN ignoring changes, our "Level(_Ch)" is "out of sync" but "last checked value" for the monitor is in sync. And when we enter Level mode again, in case the level is not changing much, surface will show incorrect information. The solution is to "reset" level monitor once we enter Level mode. We will do this inside next control, "_BtnMode".

Finally, "Timer" (once, so executed on special request only) monitor (priority 0) clean our "Level( 8 )" to "Off".

"_BtnMode" Control
It has one monitor, for "BtnMode" Set (priority "0", it it will be executed before Level and Btn, where the result is used).
For each BtnMode, we set correct type for "BtnX" monitors steered by "BtnMonMode" Set and correct ModeSwitch LED indication with "ModeSwitchLED" set.
And as explained before, we reset Level monitor (but only when entering "Level" mode, irrelevant otherwise).

Continued in the next post...


[0] Message Index

[#] Next page

Go to full version