Post by nic on Mar 29, 2019 17:46:46 GMT
This script is now included as a factory preset (and slider aware) in StreamByter v1.3
1. The incoming sequence is expected on channel 1 (change at top of script)
2. The programming channel is expected on channel 2 (also configurable) - these notes are blocked so are not heard
To program a scale, hold down the scale notes on the controller set to channel 2. After you release the last note, the scale takes effect, so I find it is easiest to hold down the first note in the scale and then tap the others and then release that first note. Once a scale is programmed, the number of notes in the scale are shown in the left Stream Byter label.
To remove a scale, tap just one note on the channel 2 controller, or to program a new scale hold the scale notes as described above.
If no scale is active, the block label will say 'NO' and all sequence notes are unaffected. A new scale is not made active until you release the final programming note.
By default, the notes get transposed according to the programmed scale. The incoming note is transposed to the closest scale note if the incoming is not in the programmed scale. If the incoming note is equidistant to two scale notes, then it is transposed to the higher note (tie-break).
You can change the script to block the out of scale notes rather than transpose by setting K2 to 0 at the top.
# programmable scaler by audeonic
IF LOAD
# sequence chan, program chan
# (hex 0-F)
ASS K0 = 0 1
# scale mode, 0=block, 1=transpose
ASS K2 = 1
# internal - scale (+ count in LC)
ASS L0 = 0 0 0 0 0 0 0 0 0 0 0 0 0
SET LB0 SNO
# interim scale
ASS L10 = 0 0 0 0 0 0 0 0 0 0 0 0 0
ASS L80 = 0 # num prog notes held
ASS J0 = 0 # sounding notes map
END
# force note offs
9X XX 00 = 8X
# note ons
IF MT == 90
# sequence
IF MC == K0
# save current note into I81
ASS I81 = M1
# is scale active?
IF LC > 1
# get note mod into I80
MAT I80 = M1 % C
# block mode
IF K2 == 0
IF LI80 == 0
# mark & block note
ASS I81 = 80
XX = XX +B
END
END
# if transpose mode
IF K2 == 1
IF LI80 == 0 # note out of scale
MAT I10 = 0 - 1
ASS I11 = F
# nearest higher note interval into I11
MAT I0 = I80 + 1
IF I0 <= B +L
IF LI0 != 0
MAT I11 = I0 - I80
ASS I0 = B
END
MAT I0 = I0 + 1
END
# nearest nower note interval into I10
MAT I0 = I80 - 1
IF I0 >= 0 +L
IF LI0 != 0
MAT I10 = I80 - I0
ASS I0 = 0
END
MAT I0 = I0 - 1
END
# for debug, send I10/11 to sysex
# SND F0 7D I10 I11 F7
# use closest note, higher note wins
# if tie break
MAT I0 = I81 + I11
IF I10 < I11
MAT I0 = I81 - I10
END
ASS I81 = I0
END
END
# remember what we mapped this input
# note to
ASS JM1 = I81
# remap the note unless blocked
IF I81 != 80
ASS M1 = I81
END
END
END
# program
IF MC == K1
# clear interim scale on first note
IF L80 == 0
ASS L10 = 0 0 0 0 0 0 0 0 0 0 0 0 0
END
# update interim scale
MAT I0 = M1 % C
MAT I0 = I0 + 10
ASS LI0 = 1
MAT L80 = L80 + 1
MAT L1C = L1C + 1
XX = XX +B
END
END
# note offs
IF MT == 80
# sequence
IF MC == K0
IF LC > 1
IF JM1 != 80
ASS M1 = JM1
END
END
END
# program
IF MC == K1
MAT L80 = L80 - 1
# detect scale clear
IF L1C == 1
ASS L10 = 0 0 0 0 0 0 0 0 0 0 0 0 0
END
IF L80 == 0
# copy interim scale to active
ASS L0 = L10 L11 L12 L13 L14 L15 L16
ASS L7 = L17 L18 L19 L1A L1B L1C
SET LB0 LC +D
IF LC == 0
SET LB0 SNO
END
# for debug, wrap scale in sysex
# SND F0 7E L0 L1 L2 L3 L4 L5 F7
# SND F0 7E L6 L7 L8 L9 LA LB LC F7
END
XX = XX +B
END
END