Post by ki on Jan 30, 2019 22:16:04 GMT
During my jams i often control AU parameters or parameters of SteamByter scripts using CC generators like RozetaLFO (automated) or RozetaXY (interactive)
It always bugged me that it was an „either or“ decision, and so i came up with this script:
Two or more CC generators can be feed into the script using two different midi channels. One of the CCs (defaults to modwheel which is present in RozetaXY) can now crossfade between the CC values from these input channels.
Besides the crossfader CC one can specify the mainChannel (which is used when the crossfader is at zero) and also a list of pass-through CCs that are not affected by the crossfading.
Using this script in a jam setup allows to smoothly fade from automated CCs to interactive CCs and back to automated CCs just using RozetaXYs modwheel slider.
Here an image showing the midi flow in an AUM setup:
You can download this AUM session (using RozetaXY/LFO, StreamByter and Zeeon). First select ‚download‘ and then use Safari‘s share button and AUM as destination.
Expect nothing fancy, it is just showing the use-case and contains the script. You then can save it using StreamByters preset system.
For your convenience all user values are input as decimal.
# CC-Crossfade: Crossfades between CC values send on different channels
# Version: 3 / 17.02.2019
# Author: -ki https://forum.audiob.us/profile/_ki
#
# This script allows to smoothly crossfade CC values for all CCs on two
# specific midi channels.
#
# One crossfadeCC (default modwheel CC1) determines the mix ratio:
#
# min : All CCs from the main channel are output unmodified
# max : All CCs from the other channel are output unmodified
# inbetween : Each CC is a smooth blend between both channel values
#
# There is a list of passthrough CC ids that are not affected by mixing.
# All output CCs are send on the main channel and only if their value
# changed.
#
# Other midi information (like notes, pitchbend or CCs on different etc)
# or events on differentchannels are passed through unmodified.
IF LOAD # User specified decimal values :
ASS I10 = 1 # Main midi channel (1..16)
ASS I11 = 2 # Other midi channel (1..16)
ASS I12 = 1 # Crossfader CC (1..127)
ASS I13 = 1 # Transmit crossfader CC (0=no, 1=yes)
ASS I14 = 13 15 -1 # List of pass-through CCs, ends with -1
END
# ============= Do not modify below this line ========================
IF MT == B0 # if (inputType == ControlerChange) {
ASS I11 = 0 # found = 0
IF MC == ICC # if (inputChannel == mainChannel) {
ASS I11 = 1 # found = 1
END # }
IF MC == ICD # if (inputChannel == otherChannel) {
ASS I11 = 1 # found = 1
END # }
IF I11 == 1 # if (found) {
IF M1 == IC0 # if (inputController == crossfadeCC) {
ASS ICA = M2 # mixVal = inputValue
IF IC1 != 0 # if (transmitCC1) {
SND M0 M1 M2 # send(inputCmd, inputController, inputValue)
END # }
MAT I0 = M2 * 64 # tmp = inputVal * 100
MAT I0 = I0 / 7F # tmp /= 127
SET LB0 SMIX # show(left, ‚MIX‘)
SET LB1 I0 +D # show(right, tmp) // Percentage
END # }
IF M1 != IC0 # if (inputController != crossfadeCC) {
ASS ID = M2 # newValue = inputValue
IF JM1 != C0DE # if (a[inputContreoller] != C0DE) {
IF MC == ICC # if (inputChannel == mainChannel) {
ASS JM1 = M2 # a[ inputController ] = inputValue
END # }
IF MC == ICD # if (inputChannel == otherChannel) {
ASS KM1 = M2 # b[ inputController ] = inputValue
END # }
ASS IA = JM1 # aVal = a[inputController]
ASS IB = KM1 # bVal = b[inputController]
ASS IC = LM1 # oldVal = o[inputController]
MAT I3 = 7F - ICA # oneMinusMixVal = 127 - mixVal
MAT I4 = I3 * IA # partA = oneMinusMixVal * aVal
MAT I5 = ICA * IB # partB = mixVal * bVal
MAT I6 = I4 + I5 # sumAB = partA + partB
MAT ID = I6 / 7F # newVal = sumAB / 127
END # }
IF IC != ID # if (oldVal != newVal) {
ASS LM1 = ID # o[inputController] = newVal
MAT I7 = B0 + IC1 # midiCmd = CCcmd + mainChannel
SND B0 M1 ID # send(midiCmd, inputController, newVal)
END # }
END # }
XX = XX +B # // block current CC command
END # }
END # }
IF LOAD # // Initialization of data arrays
ASS I0 = 0 # i = 0
IF I0 <= 7F +L # if (i <= 127) {
ASS JI0 = 0 # a[i] = 0
ASS KI0 = 0 # b[i] = 0
ASS LI0 = 100 # o[i] = NOT_RECEIVED
MAT I0 = I0 + 1 # i += i
END # }
ASS ICC = 0 # mixVal = 0
ASS I0 = 10 # i = 0
IF II0 < 8000 +L # if (param[i] < 8000 ) {
ASS ID0 = II0 # bcdValue = param[i]
# | SUBROUTINE Unrolled BCD to hex code V2
# | ======================================
# | // Input in var ID0
# | // Output in var ID1, error in ID2
# | // Uses vars ID3+ID4
# |
ASS ID2 = 0 # | error = False
ASS ID3 = 0 # | neg = False
IF ID0 >= 8000 # | if (bcdValue >= $8000) {
ASS ID3 = 1 # | neg = True
MAT ID0 = 0 - ID0 # | bcdValue = -bcdValue
END # | }
# |
MAT ID4 = ID0 & F000 # | digit = bcdValue & byte4mask
MAT ID4 = ID4 / 1000 # | digit = digit >> byte4shift
IF ID4 > 9 # | IF (digit > 9) {
ASS ID2 = 1 # | error = True
END # | }
ASS ID1 = ID4 # | outValue = digit // first
# |
MAT ID4 = ID0 & 0F00 # | digit = bcdValue & byte3mask
MAT ID4 = ID4 / 0100 # | digit = digit >> byte3shift
IF ID4 > 9 # | IF (digit > 9) {
ASS ID2 = 1 # | error = True
END # | }
MAT ID1 = ID1 * A # | outValue *= 10
MAT ID1 = ID1 + ID4 # | outValue += digit
# |
MAT ID4 = ID0 & 00F0 # | digit = bcdValue & byte2mask
MAT ID4 = ID4 / 0010 # | digit = digit >> byte2shift
IF ID4 > 9 # | IF (digit > 9) {
ASS ID2 = 1 # | error = True
END # | }
MAT ID1 = ID1 * A # | outValue *= 10
MAT ID1 = ID1 + ID4 # | outValue += digit
# |
MAT ID4 = ID0 & 000F # | digit = bcdValue & byte1mask
MAT ID4 = ID4 / 0001 # | digit = digit >> byte1shift
IF ID4 > 9 # | IF (digit > 9) {
ASS ID2 = 1 # | error = True
END # | }
MAT ID1 = ID1 * A # | outValue *= 10
MAT ID1 = ID1 + ID4 # | outValue += digit
# |
IF ID3 == 1 # | if (neg) {
MAT ID1 = 0 - ID1 # | outValue = -outValue
END # | }
IF ID2 != 0 # if (error) {
ASS ID1 = 100 # outValue = 256 // big value
END # }
ASS II0 = ID1 # param[i] = outValue
MAT I0 = I0 + 1 # i += 1
END # }
MAT ICC = I10 - 1 # mainChannel = paramChannel - 1 // SB range 0-F
IF ICC > F # if (mainChannel > 15) {
SET LB0 SCH# # show(left, ‚CH#‘)
SET LB1 SERR # show(right,‘ERR‘)
ASS ICC = 0 # mainChannel = 0 // channel 1
END # }
MAT ICD = I11 - 1 # otherChannel = paramChannel2 - 1 // SB range 0-F
IF ICD > F # if (otherChannel > 15) {
SET LB0 SCH# # show(left, ‚OT#‘)
SET LB1 SERR # show(right,‘ERR‘)
ASS ICC = 0 # otherChannel = 1 // channel 2
END # }
ASS IC0 = I12 # crossfadeCC = paramCC
IF IC0 > 7F # if (crossfadeCC > 127) {
SET LB0 SCC# # show(left, ‚CC#‘)
SET LB1 SERR # show(right,‘ERR‘)
ASS IC0 = 1 # mainChannel = 1 // modwheel
END # }
ASS IC1 = I13 # crossfadeTransmit = paramTransmit
IF IC1 > 1 # if (crossfadeTransmit > 1) {
SET LB0 SCTR # show(left, ‚CTR‘)
SET LB1 SERR # show(right,‘ERR‘)
ASS IC1 = 0 # crossfadeTransmit = 0 // off
END # }
ASS I0 = 14 # i = $14 // Mark pass-through CCs
IF I0 < 94 +L # if (param[i] < $94 ) { // max 128 CCs
ASS I1 = II0 # id = param[i]
IF I1 < 80 # if (id < 128 ) {
ASS JI1 = C0DE # a[ id ] = C0DE // mark
END # }
IF I1 >= 8000 # if (id < 0 ) {
ASS I0 = 100 # i = 256 // break loop
ASS I1 = 0 # id = 0
END # }
IF I1 >= 80 # if (id >= 128) {
SET LB0 SPT # show(left, ‚PT‘)
SET LB1 I0 # show(right, i)
ASS I0 = 100 # i0 = 256 // break loop
END # }
MAT I0 = I0 + 1 # i += 1
END # }
END