|
Post by ajp on Mar 20, 2019 19:34:35 GMT
Can Stream Byter be used to create a scale quantizer that allows user scales with realtime input?
There are 2 parts to this: 1- allows user created scales I.e. the user can enable the notes they want and not rely on preset scales I'm assuming this is straightforward for Stream Byter, but also assuming this needs to be written into the code and would not be something that could be modified on the fly - or can you make adjustments and "Install Rules" while things are playing and not have stuck notes, etc.?
2- allow realtime control over those notes selected? I.e. instead of just selecting the notes in the code, a second MIDI input allows chords played to be the "quantize mask" to which notes on the primary channel are transposed or filtered.
So: Input MIDI channel 1 = stream of notes \__ Output = stream of notes on Ch1 transposed and/or masked by the chord notes Input MIDI channel 2 = chords played /
Possible?
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Mar 21, 2019 11:56:32 GMT
Hi ajp,
Yeah, this is complex but not impossible. You are right in that we need to take care of stuck notes, but it is quite possible to change a Stream Byter script's behaviour on the fly with MIDI events, so we probably would not need to try and trigger an 'Install Rules' in the middle of operating.
I'm thinking it could be done with some sort of 'shift' CC that when active, 'programs' the scale either by supplying notes to set the scale (as you suggest, which is relatively simple) or by trying to program the scale with some other sort of incantation like some CCs or sysex messages which I do not recommend. The flow of logic would be something like:
- SHIFT on, clears the current scale and each note pressed is recorded into the scale (and blocked) until SHIFT off
- Each incoming note is mapped to the closest of the current scale (scale is duplicated across all octaves)
Alternatively instead of the 'shift' mechanism you could treat notes coming in on channel A as sounding notes and channel B as scale programming notes, but then you need something to clear the current scale. Seems to me that the shift would work best if setting the scale with a controller.
Regards, Nic.
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Mar 25, 2019 14:51:26 GMT
Hi ajp,
OK, so I had a stab at doing this and ended up with something that seems to work. I altered the programming method a little. It works like this:
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.
Enjoy!
Regards, Nic.
# 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
|
|
|
Post by carnbot on May 7, 2019 14:41:36 GMT
This is great Is there a way to save the captured scale with the session? Or is that not possible in these types of live input scripts? I tried reloading the session after a synth crashed and found I needed to capture the scale again after saving. Makes sense as it's a live script, but wondered if there was a way Streambyter could remember this type of info in a session if saved?
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on May 7, 2019 14:51:37 GMT
Hi carnbot , You can mark the scale variables as preserved: ASS L0 = 0 0 0 0 0 0 0 0 0 0 0 0 0 +PHowever, that won't save you from a crash I'm afraid, but the current scale will be saved into a preset/host session/preset and restored. Regards, Nic.
|
|
|
Post by carnbot on May 7, 2019 14:54:54 GMT
oh great, thanks Nic, I'll try that
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on May 7, 2019 15:07:01 GMT
Actually, if the host saves its session regularly, maybe it would preserve over a crash...
|
|
|
Post by imagine on Dec 5, 2019 14:51:01 GMT
This is absolutely brilliant! Since I moved "outside" the box regarding the instruments I was looking for some non-AU/VST MIDI quantizer and this perfectly suits my needs. Now I use my Beatstep Pro to switch or select the notes of the scales on the fly. Not to mention that Midifire greatly expanded the possibilities of my studio! :-)
Thanks! :-)
|
|
|
Post by synthi on Sept 5, 2021 17:46:38 GMT
Thanks alt for this script!
Would be possible to modify it so it quantize to the held notes? I mean not waiting for release so I can jam in real-time and the quantizer follow my chords?
|
|