|
Post by mo13 on Mar 10, 2022 12:26:19 GMT
I've been trying to get this script working for some time now, original courtesy of uncledave . unfortunatuly I'm only getting as far as clearing out the LED's without getting any feedback. here is my situation : my controller sends out 32 CC's on Ch.1 starting from B0 00 for feedback it expects the same but coming in on Ch.3 and with a CC value of 05. first thing on start up that needs to happen is to clear out a block of LED's (as my controller has 128 push CC's in total but I'm only adressing this specific block of 32 now) next thing, after the block is cleared, every LED has to act as one LED at a time, from here on i'm unforunately stuck : If load
Alias J00 oldValue Alias I00 reg0 Alias B2 sendCC #feedback ch. Ass J00 = $2
# sends zero to all CCs in the range
Alias 0 theFirst Alias $31 theLast Sub ClearBlock theFirst theLast Ass reg0 = theFirst While reg0 <= theLast Snd sendCC reg0 3 #value that clears out the LED"s Mat reg0 = reg0 + 1 End End
Alias $0 theCC Alias $5 theColor Sub SetLed theCC theColor theFirst theLast If oldValue > 5 ClearBlock theFirst theLast Else Snd sendCC oldValue 0 End Ass oldValue = theCC Snd sendCC theCC theColor End End
I'm still in the process of understanding StreamByter 2 rules compared to v1, so I'm sure there are enough mistakes here. appriciate any kind of input!
|
|
|
Post by uncledave on Mar 10, 2022 19:27:45 GMT
Here's my suggested update to your code. What you had wrong was the subroutine parameters. The parameters are the additional names, like "theFirst" that appear on the Sub line after the subroutine name. They are used inside the Sub like variables. They are passed to the Sub where it is called. They let the same Sub do different stuff at different times; quite a powerful concept. You used Aliases which turned them into constants, which is not desired.
Also, I guess you know that the code in If Load is just run when the script is loaded, and the Subs are not even run, they are just prepared. You need events from outside to trigger pieces of code outside If Load to do any work. In my update of your code, I use Note events to test the script. You probably already have CCs or other events to do this.
I suggest that you load this script, just like it is. Send in some notes and watch a MIDI monitor. The first note will clear all the LEDs and set one. Every following note will clear the previous LED and set another.
#LEDFeedback
If load Alias 0 firstCC Alias $31 lastCC Alias J00 oldValue # this is the CC# previously lit Alias I00 reg0 Alias B2 sendCC #feedback ch.
Mat oldValue = lastCC + 1 # impossible value indicates first time
# sends zero to all CCs in the range. Used by SetLed. # theFirst and theLast are parameters, not constants. They come # from the subroutine call. Sub ClearBlock theFirst theLast Ass reg0 = theFirst While reg0 <= theLast Snd sendCC reg0 3 #value that clears out the LED"s Mat reg0 = reg0 + 1 End End
# you need to call this with the LED # you want to light, and the color, # maybe # SetLed 7 5 # to light LED 7 with color 5. # You would do this from an event in the lower part of the script (outside # If load), or from a Sub lower down in If load. Sub SetLed theCC theColor If oldValue > lastCC # first time clears all ClearBlock firstCC lastCC Else # should this send 0 or 3 to turn light off? Snd sendCC oldValue 3 # normal turns off previous End Ass oldValue = theCC # remember the CC Snd sendCC theCC theColor # and turn it on End
End # Initialization ———————————————————————————
# sample test code. Lights one light based on incoming note. If MT == 90 # reduce note # to 0..31 Mat I10 = M1 % $32 SetLed I10 5 End # block the test note messages If MT < A0 Block End
|
|
|
Post by mo13 on Mar 10, 2022 20:49:40 GMT
thanks Dave, good to learn some more on that. The test mode with sending in notes works like you've described, but while it runs and after it stops, I can just fill up the grid again with the base LED color - so no feedback anymore.  the intention here is that the clearblock only happens once (maybe there is a trick to it that it ignores scene loads on MidiFire so it remembers the last lit LED) and after that it's only one LED at a time, like here I had set it up in my primitive way by 'if load +snd CC values to clear the block on every scene switch, and after that every pressed CC sends out zero msges to all the unpressed ones in the the block :  but as you already showed me how that's unnecessary overwork for MF. so we do have scene switches for the Initialization if needed.
|
|
|
Post by uncledave on Mar 10, 2022 21:14:44 GMT
There is no feedback in my script or yours. You need to add that code after my note event handler. Code that responds to whatever comes in, CCs, whatever, and calls SetLed with the proper CC# and color. There is no magic here. The subroutines do the work, but but you need event handlers to trigger them. What event is supposed to trigger this feedback? Is it the same CC# on MIDI channel 1? That would just be: If M0 == B0 # CC on ch. 1 If M1 <= lastCC # one of first 32 CCs SetLed M1 5 End End
That will set the led corresponding to the CC#, if it's less than 32. It does not block the CC, but you could add that.
Note that these event handlers are outside the If Load section. They are run (once) for every MIDI message entering the block. The If logic identifies what kind of message it is and takes appropriate action. And, unless you Block them, the incoming messages all flow out of SB to whatever it is connected to.
|
|
|
Post by mo13 on Mar 10, 2022 22:03:51 GMT
yeah it's perect now! I'll study the script for tonight now for the other 4 independent blocks, but to be sure, it is possible to have independent blocks in one script? so for instance the next block will start with $32 where Alias firstCC sits now? thanks!
|
|
|
Post by uncledave on Mar 11, 2022 0:41:21 GMT
yeah it's perect now! I'll study the script for tonight now for the other 4 independent blocks, but to be sure, it is possible to have independent blocks in one script? so for instance the next block will start with $32 where Alias firstCC sits now? thanks! Yes. It might be easiest for you to make a new SetLed for each bank, using different start/end constants, and a different variable for the oldValue. Create new aliases for the limits, and for the oldValue. You can just use J01 etc. for the new saved values. And you'll need to change the event logic so it selects the correct Sub based on the input CC#.
|
|
|
Post by mo13 on Mar 11, 2022 8:22:56 GMT
Should be on the right track with this i think, only now I'm getting one big bank of 64 one-led-at-a-time CC's instead of 2 seperate banks so the event logic for it is off for selecting the right sub yes? If load
Alias 0 firstCC-A # A = bank A Alias $31 lastCC-A Alias $32 firstCC-B Alias $63 lastCC-B Alias J00 oldValue-A # this is the CC# previously lit Alias J01 oldValue-B Alias I00 reg0 Alias B2 sendCC #feedback ch.
Mat oldValue-A = lastCC-A + 1 # impossible value indicates first time Mat oldValue-B = lastCC-B + 1
# sends zero to all CCs in the range. Used by SetLed. # theFirst and theLast are parameters, not constants. They come # from the subroutine call.
Sub ClearBlock theFirst theLast Ass reg0 = theFirst While reg0 <= theLast Snd sendCC reg0 3 #value that clears out the LED"s
Mat reg0 = reg0 + 1 End End
# you need to call this with the LED # you want to light, and the color, # maybe # SetLed 7 5 # to light LED 7 with color 5. # You would do this from an event in the lower part of the script (outside # If load), or from a Sub lower down in If load.
Sub SetLed-A theCC theColor If oldValue-A > lastCC-A # first time clears all ClearBlock firstCC-A lastCC-A Else
# should this send 0 or 3 to turn light off? 3 is for off in this particular bank, there will be 1 lit LED bank. Snd sendCC oldValue-A 3 # normal turns off previous End Ass oldValue-A = theCC # remember the CC Snd sendCC theCC theColor # and turn it on End
Sub SetLed-B theCC theColor If oldValue-B > lastCC-B # first time clears all ClearBlock firstCC-B lastCC-B Else Snd sendCC oldValue-B 3 End Ass oldValue-B = theCC # remember the CC Snd sendCC theCC theColor # and turn it on End End
If M0 == B2 # CC on ch. 3 # channel has been changed to 3 If M1 <= lastCC-A # one of first 32 CCs SetLed-A M1 5 End
If M0 == B2 # CC on ch. 3 If M1 <= lastCC-B # one of first 32 CCs SetLed-B M1 6 # notice the LED color has changed here to the previous bank End End End
this is just a practicing example for bank B so if I know what's going on, I can take it from there for the other banks, althout the last 2 banks will be toggles instead of one-led-a-time but that shouldn't be too hard to add. here is what's on the monotior, and yes we need to block all the other stuff besides the script events @ where the X is, as you can see we have double feedback now as well because of the rules not being correct yet. 
|
|
|
Post by uncledave on Mar 11, 2022 11:25:28 GMT
You're still confusing Sub parameters with defined variable names (Aliases). You should leave the Subs with parameters theCC and theColor, as I wrote it. Those parameter names should appear only on the Sub line and inside the Sub. They are replaced with the variables from the place where the Sub is called. The call is where the Sub name appears without Sub in front of it. Study my version to see the Sub definition, with its parameters, used inside the Sub (before its End), and the call, where variables are passed to the Sub. Notice that the CC# (M1) and the color (5 or 6) in the call of SetLed are passed to theCC and theColor in the Sub. This lets the Sub do different stuff each time.
You need better logic to separate the second bank CCs. Like If M1 >= firstCC-B If M1 <= lastCC-B SetLed-B M1 6 End End
Your version does both actions for buttons in the first bank, since M1 is <= both limits.
Also, I would not have used a dash ("-") in these names, because it is also a minus sign. It appears to work, but the normal convention would be to simply attach the extra letter, or use underscore ("_") between them.
|
|
|
Post by mo13 on Mar 11, 2022 12:56:10 GMT
I didn't have luck with removing things out of the Subs as it gave me errors, so I hope I can learn from how it should be written out. I do understand the difference now though. banks C and D added, only now bank B and D will need a different value of ClearBlock, acting as visual seperator (Ps. Bank F cyan also has to come on lit @ClearBlock ) those Bank color values are now in the script @subs but I didn't touch the initial ClearBlock out of cautiousness. If load
Alias 0 firstCC_A # A = bank A Alias $31 lastCC_A Alias $32 firstCC_B Alias $63 lastCC_B Alias $64 firstCC_C Alias $95 lastCC_C Alias $96 firstCC_D Alias $111 lastCC_D
# @not implemented yet, as i don’t know the right way and order of how to write the actual rules/Aliases out for this script # CC 112-119 acting as Solo toggles, 1st press is Lit aka CC value 5, 2nd press unlit aka val.3 # CC 120-127 acting as Mute toggles, starting out Lit = val.2 (by clearblock) 1st press unlit aka value 3 then 2nd press back to val.2
Alias J00 oldValue_A # this is the CC# previously lit Alias J01 oldValue_B Alias J02 oldValue_C Alias J03 oldValue_D Alias I00 reg0 Alias B2 sendCC #feedback ch.
Mat oldValue_A = lastCC_A + 1 # impossible value indicates first time Mat oldValue_B = lastCC_B + 1 Mat oldValue_C = lastCC_C + 1 Mat oldValue_D = lastCC_D + 1
# sends zero to all CCs in the range. Used by SetLed. # theFirst and theLast are parameters, not constants. They come # from the subroutine call.
Sub ClearBlock theFirst theLast Ass reg0 = theFirst While reg0 <= theLast Snd sendCC reg0 3 #value that clears out the LED"s Mat reg0 = reg0 + 1 End End
# you need to call this with the LED # you want to light, and the color, # maybe # SetLed 7 5 # to light LED 7 with color 5. # You would do this from an event in the lower part of the script (outside # If load), or from a Sub lower down in If load.
Sub SetLed_A theCC theColor If oldValue_A > lastCC_A # first time clears all ClearBlock firstCC_A lastCC_A Else Snd sendCC oldValue_A 3 # set to the basic LED Color. As a visual separator. End Ass oldValue_A = theCC # remember the CC Snd sendCC theCC theColor # and turn it on End
Sub SetLed_B theCC theColor If oldValue_B > lastCC_B # first time clears all ClearBlock firstCC_B lastCC_B Else Snd sendCC oldValue_B 0 # set to the basic LED Color. As a visual separator. End Ass oldValue_B = theCC # remember the CC Snd sendCC theCC theColor # and turn it on End
Sub SetLed_C theCC theColor If oldValue_C > lastCC_C # first time clears all ClearBlock firstCC_C lastCC_C Else Snd sendCC oldValue_C 3 # normal turns off previous End Ass oldValue_C = theCC # remember the CC Snd sendCC theCC theColor # and turn it on End
Sub SetLed_D theCC theColor If oldValue_D > lastCC_D # first time clears all ClearBlock firstCC_D lastCC_D Else Snd sendCC oldValue_D 0 # normal turns off previous End Ass oldValue_D = theCC # remember the CC Snd sendCC theCC theColor # and turn it on End End
If M0 == B2 # CC on ch. 3 # channel has been changed to 3 If M1 <= lastCC_A # one of first 32 CCs SetLed_A M1 5 End End
If M1 >= firstCC_B If M1 <= lastCC_B SetLed_B M1 6 End End
If M1 >= firstCC_C If M1 <= lastCC_C SetLed_C M1 4 End End
If M1 >= firstCC_D If M1 <= lastCC_D SetLed_D M1 6 End End
It honestly already took me forever to set it up in the SB V1 rules fasion. So great that it's almost a single script!
|
|
|
Post by uncledave on Mar 11, 2022 16:55:08 GMT
OK. This is good, I think. Now we can think about the next steps. I've written the programmer version of this, with some (I hope) helpful info. A StreamByter script is actually a computer program, and in order to understand it, you have to think like a programmer. This is basically second nature to me because I've done it for so long. But, you need to be able to look at a line of code and know exactly what it does, and why it is where it is. To help you with this, I've written the script that handles all 4 banks of 32 LEDs. I've tested this, and it manages each bank as a separate set of 32 LEDs, setting only one at a time. The script is written as a tutorial. I've purposely left out any comments, and most of the Aliases that make the code more readable. I've replaced them with a lot of questions, which you should try to answer. Look up the items in the SB manual, so you have a clearer idea of what they do, and why they are useful. You may need to skip some of the questions at first, because they depend on items farther down the code. It may be helpful to download the PDF version of the SB manual for easier reading. I use mine almost every day, to check on various peculiarities. If you post the answers to the questions, and ask for explanation of parts that are unclear, I'll review them and try to give explanations. You could PM the answers, if you don't want to post them. #SetLedAny # This script handles 4 separate banks of 32 LEDs. # Please try it out, and try to answer all the questions. # You need to read the manual to answer some of them. # And you need to finish reading the program before you # can answer some of them.
If load # 1a. When does this part run? How often? # 1b. Where does this part end?
Alias $32 bankSize Alias 4 numBanks Alias B2 setCommand Alias $112 totalBanks # 2a. Why do we use Alias for these values? # 2b. What happens when we use the Alias name in the script? # 2c. How many LEDs are in a bank?
Ass J00 = 80 80 80 80 # 3a. Which variables does this initialize? List them. # 3b. What is Jii used for? Hint: look in SetLedAny. # 3c. Why do we use 80 here? Hint: what CC#s are possible?
Ass K00 = 5 6 4 6 3 0 3 0 # 4a. Which variables does this initialize? List them. # 4b. What is Kii used for? Hint: look in SetLedAny. # 4c. How can we change the color used in a given bank? # 4d. How can we change the background color for a bank?
Sub ClearBank pBank # 5a. What is ClearBank? # 5b. When does it run? # 5c. What is pBank? # 5d. pBank is never assigned, so how does it get a value? Mat I20 = pBank * bankSize # 6a. What is I20? # 6b. What value is I20 when pBank is 0, 1, 2, or 3? Mat I21 = I20 + bankSize # 7a. What value is I21? If I21 > totalBanks Ass I21 = totalBanks End # 29a. What value is I21 now? # 29b. What happens to LEDs 112-127? Mat I22 = pBank + numBanks Ass I22 = KI22 # 30a. What value is I22 now?
# 8a. What does the While do? # 8b. What values does I20 go through before the loop stops? While I20 < I21 Send setCommand I20 I22 # 9a. What MIDI message does this send for each value of I20? # 9b. What color does it use? Mat I20 = I20 + 1 # 10a. How does I20 change here? # 10b. How does this affect the While? End End
# 11a. What does ClearBank do when it is called? # 11b. (Extra Credit) Why use a separate Sub for ClearBank? # Couldn't we just put it inside SetLedAny?
Sub SetLedAny pNumb # 12a. What is SetLedAny? # 12b. When does it run? # 12c. What is pNumb? # 12d. pNumb is never assigned, so how does it get a value? Mat I10 = pNumb / bankSize # 13a. What value does I10 get? Consider different CC#s from 0 to 127. # Remember that integer divide truncates. No decimal part.
# 14a. What is JI10? What value does it have? # 14b. What does it mean when JI10 is 80? If JI10 == 80 ClearBank I10 # 15a. What does ClearBank I10 do? Else # 17a. When do we execute this and not ClearBank? Mat I11 = I10 + numBanks Send setCommand JI10 KI11 # 16a. What MIDI message does this send? # 16b. Which LED does it clear? # 16c. What color does it clear the LED to? End
Send setCommand pNumb KI10 # 18a. What MIDI message does this send? # 18b. Which LED does it set? # 18c. What color does it use? Ass JI10 = pNumb # 19a. What value does JI10 get here? # 19b. How will that affect the next call for this bank? End
# 20a. What does SetLedAny do when it is called? # 20b. What happens the first time SetLedAny is called for a bank? # 20c. What happens on every other call for a bank?
# 25a. (Extra Credit) Why did I use I10 in one Sub, I20 in the other? Why not just use I10 everywhere?
Set Name SetLed # 21a. What is the Name? # 21b. Why is it useful?
End # Initialization ———————————————————————————
# 22a. What is this part of the script? Hint: it handles events. # 22b. When does it run? How often? # 22c. What values are in M0, M1, and M2 when it runs? # 22d. What happens for a CC message on MIDI channel 3? # 22e. What happens for any other message?
If M0 == B2 # 27a. When does this part run? If M1 < totalBanks # 28a. What happens on press of button 112? SetLedAny M1 # 23a. What does SetLedAny M1 do? # 23b. What value is passed as pNumb in SetLedAny? # 26a. (Extra Credit) Why do I only call a Sub in the CC event handler? # Why not just put all the code right here? Else # can handle last 2 rows of 8 here End End
# 24a. Do any MIDI messages leave this script? Which ones? Block
I know this looks really long, but it's actually quite short, when the questions are removed. I've used the colors from your example, and I've blocked off CCs 112-127, so they can be handled differently. Edit: Changed the background colors. Limited the last block to CC 111.
|
|
|
Post by mo13 on Mar 11, 2022 18:20:47 GMT
thanks alot for these extra efforts Dave! quite honestly my head is already spinning just from looking at the first few questions, but which is only a good thing  I can already see that 80% of the refreferentials are completely new to me. This will keep me busy with the manual, great! @script, everythinig is instantly working, ClearBlock now clears all the banks to the value 3, banks B and D will eventually have a ClearBlock value of 0 on them for the visual separation of the Banks as I mentioned, I'll try to see if I can figure it out myself in your programmers version, maybe set up a version with the questions removed as well, to put myself in your shoes for a sec, but ofcourse next to the questions version to take notes. It'll take me some time to digest, I still can't get my head around how to set a range of CC's to toggle from a single set of rules (and block the rest), I've been dreadfully converting your older # entire CC range to note on/off's back to toggles for that purpose, and sometimes Nic's older version for a single toggle : If load Ass K0 = B2 $112 # toggle flag (ON to start) Ass L0 = 7F End
# trap toggle CC if M0 == K0 K1 if M2 == 7F
# send toggle version of CC if ON send K0 K1 L0 calc L0 = L0 ^ 7F end block end
would be goot to know a simple way to remember how to set up a range of toggles for CC112 to 127 and meanwhile I'm going to be scratching my head alot with the assignment, thanks again!
|
|
|
Post by uncledave on Mar 11, 2022 19:16:46 GMT
My version already has the different background colors. Just tell me how it works and I'll show you how to handle the toggles. (Hint: we use an array, same as I'm doing for the LED memories and bank colors.)
|
|
|
Post by mo13 on Mar 11, 2022 20:17:55 GMT
PM !
|
|
|
Post by mo13 on Mar 18, 2022 8:47:05 GMT
hey uncledave this is on a separate SB instance but it still somehow clashes, as in renders your script for the first 4 banks inactive: #toggles for last 2 banks
If load
Set Name SetToggles # sets the initial state of Bank E and F LEDs Snd B2 70 03 Snd B2 71 03 Snd B2 72 03 Snd B2 73 03 Snd B2 74 03 Snd B2 75 03 Snd B2 76 03 Snd B2 77 03 Snd B2 78 02 Snd B2 79 02 Snd B2 7A 02 Snd B2 7B 02 Snd B2 7C 02 Snd B2 7D 02 Snd B2 7E 02 Snd B2 7F 03 End
If M0 == B2 If M1 <= 7F If M2 == 7F Mat LM1 = LM1 ^ 7F Ass M2 = LM1 If M2 == 7F Ass M0 = 90 Else Ass M0 = 80 End Else Block End End End
90 70-76 = B2 XX 05 +C # Bank E toggle 80 70-76 = B2 XX 03 +C 90 77-77 = B2 77 06 +C # Last CC Bank E 80 77-77 = B2 77 03 +C 90 78-7E = B2 XX 03 +C # Bank F toggle 80 78-7E = B2 XX 02 +C 90 7F-7F = B2 7F 05 +C # Last CC Bank F 80 7F-7F = B2 7F 03 +C
# [extra edit] ≈ Solos turn off the Mute LEDs correspondingly to AUM’s channels handled from another script.
90 70 = B2 78 03 +C 80 70 = B2 78 02 +C 90 71 = B2 79 03 +C 80 71 = B2 79 02 +C 90 72 = B2 7A 03 +C 80 72 = B2 7A 02 +C 90 73 = B2 7B 03 +C 80 73 = B2 7B 02 +C 90 74 = B2 7C 03 +C 80 74 = B2 7C 02 +C 90 75 = B2 7D 03 +C 80 75 = B2 7D 02 +C 90 76 = B2 7E 03 +C 80 76 = B2 7E 02 +C
XX = XX +B [edit] I traced where the clash came from, there was an inactive script that somehow was still interfering with the rest. Would you be so kind to point me in the right direction @how this can be incorporated with the 4 banks in the other script?
|
|
|
Post by uncledave on Mar 29, 2022 17:26:20 GMT
Here's the implementation for the toggles (only). Please try it out. I can easily merge it with the other script for the bands later.
I ran into one little problem with AllSolosOff. The script receives CCs for the buttons, and sends the same CC#s (with different values) to control the lights. No problem with that. But you said that AllSolosOff should send the same CC#s to turn off solo in AUM. This conflicts with the light messages, because they're all on the same MIDI channel (3, command B2). I "fixed" it by adding 1 to the channel in these messages directed to AUM. It think we have to use some different channel for the AUM messages.
I've tested this with my Xtouch Mini controller and it works as intended. I implemented AllSolosOff by just sending internal messages to "push" the lighted Solo buttons. This ensures that the logic (restoring saved mute) works correctly.
The following description is pretty long, but the actual logic is really simple.
#Toggles
# Top row of buttons # Bank E. CC 112-118 ClearBlock Val.3, # 1st press is Lit aka CC val 5, 2nd press unlit aka val.3 # (if this is a possibility) to set these up so they cancel out Bank F # indicating there is a Solo active, thus holding in memory which CC's # of Bank F were last active.
# CC 119 a stand-alone CC, ClearBlock Val. 3. 1st press Lit Cyan # blinking aka CC val.6. 2nd press unlit val.3. This logic is # overridden by new AllSolosOff.
# Bottom row of buttons # Bank F. CC 120-126, starting out Lit = val.2 (CleaBlock) 1st press # unlit aka val.3 then 2nd press back to val.2
# CC 127 a stand-alone CC, ClearBlock Val. 3. 1st press Lit Green # blinking aka CC val.5. 2nd press unlit val.3
# A finite-state machine is useful when logic becomes a bit too # complicated. The state variable is a number encoding all the # info about the state. Each input event will cause a transition to a new # state. This is encoded in the state transition matrix which gives the # new state value when each input arrives for each prior state.
# Here, the state is the status of the Solo and Mute lights, and the prior # status of Mute, so it can be represented by a 3-bit number, i.e. 0..7. # The inputs are presses of the Solo and Mute buttons. They cause # state transitions as described below.
# Finite-state Machine # 8 possible states, corresponding to Solo, Mute, and Prior Mute # being ON or OFF. The state value bit-codes the 3 status values. # Use 4 for Solo, 2 for Mute, 1 for Prior Mute. # Add the digits to make the state number, e.g. 401 –> 5. # 2 inputs corresponding to button press in top row and bottom row. # Each input changes the state to a new state. For example, top row press # turns Solo OFF into Solo ON. # Transitions for each pair of state and input: # 000 Solo –> 400 # Mute –> 020 # 001 Solo –> 401 (unlikely) # Mute –> 020 (unlikely) # 020 Solo –> 401 (Solo turns Mute off, sets memory) # Mute –> 000 # 021 Solo –> 401 (unlikely) # Mute –> 000 # 400 Solo –> 000 # Mute –> 400 (no mute because Solo is ON) # 401 Solo –> 020 (Solo off restores prior Mute) # Mute –> 401 (no mute because Solo is ON) # 420 Solo –> 020 (unlikely) # Mute –> 400 (unlikely) # 421 Solo –> 020 (unlikely) # Mute –> 401 (unlikely) # Some transitions are unlikely because prior state cannot occur, but # we cover all possibilities. # Transition table. Left number for Solo input, right for Mute. # 42 52 50 50 04 25 24 25
# Alternative table for last button pair. LEDs are independent. # 1 bit not used. Button events just set or clear corresponding LED. # 000 Top –> 400 # Bot –> 020 # 001 Top –> 400 # Bot –> 020 # 020 Top –> 420 # Bot –> 000 # 021 Top –> 420 # Bot –> 000 # 400 Top –> 000 # Bot –> 420 # 401 Top –> 000 # Bot –> 420 # 420 Top –> 020 # Bot –> 400 # 421 Top –> 020 # Bot –> 400 # Alt table: 42 42 60 60 06 06 24 24
If Load Set Name Toggle Alias $112 totalBanks Alias B2 setCommand
Alias 8 togSize # two rows of 8 toggles Alias 10 buttonBase # offset to button data in J and K Alias 20 transBase # offset to transition data in K Alias J18 needResend Alias 4 soloBit Alias 2 muteBit # J10, etc. contains 8 state memories. Each state memory contains 3 bits, # 4 for Solo, 2 for Mute, 1 for old mute. This initialization sets the mutes. Ass J10 = 2 2 2 2 2 2 2 0 # J18... contains working variables Ass J18 = 0 0 0 0 0 0 0 0 # K10, etc. contains 16 ON colors Ass K10 = 5 5 5 5 5 5 5 6 2 2 2 2 2 2 2 5 # K20 is transition table for first 7 columns, K28 for last column # Each entry is new states for a given state. High nybble for top button, # low nybble for bottom button. Ass K20 = 42 52 50 50 04 25 24 25 Ass K28 = 42 42 60 60 06 06 24 24 # Note that the values in the K array are packed together, with no gaps. # There are 16 colors, then 2 transition tables of 8.
# our own internal SysEx message Define resendMessage F0 7D 02
# Sets one LED. pState is 0 for OFF, non-zero for ON. # pCol is the column number, pOffset is 0 for top row, 8 for bottom. Sub SetOneLed pValue pCol pOffset # determine the color If pValue > 0 Mat I28 = pCol + buttonBase # index column color Mat I28 = I28 + pOffset Ass I28 = KI28 # index ON color from table Else Ass I28 = 3 End # determine CC# Mat I29 = pCol + totalBanks Mat I29 = I29 + pOffset Send setCommand I29 I28 # set the LED End
# sets both LEDs in the column, given the state value Sub SetLedPair pCol pState Mat I20 = pState & soloBit # top button state SetOneLed I20 pCol 0 Mat I20 = pState & muteBit # bottom button state SetOneLed I20 pCol togSize End
# Updates data for one column. pNumb is button number, 0..15 Sub UpdateToggle pNumb Mat I10 = pNumb % togSize # column index 0..7 Mat I11 = pNumb / togSize # row number 0, 1 Mat I12 = I10 + buttonBase # index state, JI12 is state value Set LB0 JI12 # display entering state Mat I13 = JI12 + transBase # index transition entry for state # use second transition table for last column If I10 == 7 Mat I13 = I13 + togSize End # update new state from table, using high or low nybble of transition # in KI13. Top row uses high nybble, bottom uses low If I11 == 0 Mat JI12 = KI13 / 10 # divide moves high nybble to low Mat JI12 = JI12 & F # ensure nothing crazy Else Mat JI12 = KI13 & F # mask selects low nybble End Set LB1 JI12 # display new state # update leds in this column SetLedPair I10 JI12 End
# sends an internal toggle message for each current solo # These messages are sent in one burst. Then SB will run to handle # each one of them. Enabling resend causes these messages to be # sent out also. Sub AllSolosOff # messages sent with +I flag go to the SB input queue, not outside. Send resendMessage 1 F7 +I # send internal msg to enable resend Ass I10 = 0 Ass I11 = togSize Mat I11 = I11 - 1 # I10 will run 0-6 While I10 < I11 Mat I12 = I10 + buttonBase # index button states Mat I12 = JI12 & soloBit # test the Solo bit If I12 != 0 Mat I13 = I10 + totalBanks # create the CC# Send setCommand I13 $127 +I # send internal cmd to push solo End Mat I10 = I10 + 1 End Send resendMessage 0 F7 +I # cancel previous resend enable End
# sets the toggle LEDs to their initial values Sub PresetToggles Ass I10 = 0 # loop over columns While I10 < togSize Mat I12 = I10 + buttonBase SetLedPair I10 JI12 Mat I10 = I10 + 1 End Set LB0 STogs_Init End
PresetToggles # initialize the lights
End # Initialization ———————————————————————————
If M0 == B2 If M1 >= totalBanks # handle toggles If M1 == $119 # special case for AllSolosOff AllSolosOff Else # other toggles here Mat I00 = M1 - totalBanks # value 0..15 UpdateToggle I00 If needResend == 1 Mat M0 = M0 + 1 # send msg on next higher channel Send M0 M1 M2 # send this msg out (clone) End End End End
# handle internal resend message If M0 == resendMessage # M3 is 1 to enable resend, 0 to disable Ass needResend = M3 End Block # all input messages are blocked
|
|