|
Post by John Tennison on Oct 23, 2017 22:15:36 GMT
Nic,
I wanted to be able to transpose note-ons in realtime so that I could send them to destinations which don't respond to RPNs, Sysex, or for destinations which transpose functions are not easily accessible.
Here is what the Stream Byter Module needs to do:
The module will transpose all incoming Note-on events as a function of a current "transpose variable."
The" transpose variable" will be a 7-bit variable populated by the default (decimal) value of 64, which will correspond to no transposition up or down (a delta of zero).
If the module receives a CC6 command, the module will replace the "transpose variable" with the most recently received CC6 value.
All incoming Note-On events will be transposed by the current value of the "transpose variable."
For example, if the last received CC6 value was 66 (66-64 = delta of +2), and incoming C3 (middle) note-on would be transposed up by 2 semitones to D3 before being sent out the module.
To prevent stuck notes that would occur if a new and different CC6 was received before a previously sounded note was released, a variable table of an additional 128 variables would be maintained to remember the "transpose variable" values that were in effect at the time a particular note-on event was transposed.
For example, in the example above, a value of 66 (or a delta value of +2) would be stored in the location corresponding to C3 in the table of 128 possible note-off events. When the C3 key on the controller was released, the module would look up the stored delta for C3 (in this case a +2) and send out a note-off event for D3, rather than erroneously sending out a note-off event for C3.
I don't know if syntax errors would result, but the module might need to know not to generate Note-on or Note-off events outside of the standard 00-7F hexadecimal range. For example, if I played a C3 key on my controller after having sent the module a CC6 value of 128, I would want the transposition to max out (be limited) at the 7F value; and also be limited at the 00 value if negative if negative transposition was occurring.
Thanks for any help you can lend in realizing this functionality.
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Oct 24, 2017 10:32:51 GMT
Hi John,
Yes, I think this could be done and your analysis I think is pretty sound on how it should work.
Rather than doing the usual ad-hoc typing in of rules, this is complex enough that I'd need to write and test this in the app. Sounds like a candidate for the scenes club.
Let me have a go at this during the week and see if I can make it happen. The logic to handle out of bound transposition requests will need some experimentation too.
The alternative would be to add a CC control of the transpose amount in the channel strip module which already takes care of both out of bound transpositions and sending the correct note offs.
Regards, Nic.
|
|
|
Post by John Tennison on Oct 24, 2017 11:52:04 GMT
Thanks, Nic. I look forward to trying out whatever you come up with.
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Oct 24, 2017 12:28:11 GMT
OK, so not quite so tricky. Scene attached. This operates on notes only on channel 1 and uses CC 19 (channel 1) to change the transposition. Both of these are set via the ASS K0 line near the top if you want to change them. The left label on the block shows current transpose and the right label shows the last note after transpose. Let me know how this goes, and I'll add to Scenes Club also once ironed out. Regards, Nic.
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Oct 24, 2017 12:38:14 GMT
And here's the actual code for anyone interested:
IF LOAD # K0: note chan, ctl CC/chan, ctl CC val ASS K0 = 00 B0 13 # L0: current delta, note on, note off ASS L0 = 00 MAT L1 = 90 + K0 MAT L2 = 80 + K0 SET LB0 L0 +D END
# handle CC IF M0 == K1 K2 MAT L0 = M2 - 40 SET LB0 L0 +D END
# blanket convert all note on+vel0 to off 9X XX 00 = 8X
# trap chan note on IF M0 == L1 # determine transposed note into l3 MAT L3 = M1 + L0
# check in bounds IF L3 >= 0 IF L3 <= 7F # store current delta in I ASS IM1 = L0 # transpose the note ASS M1 = L3 # show last transposed note SET LB1 L3 +N END END END
# apply current delta to note off and reset IF M0 == L2 MAT L3 = M1 + IM1 ASS IM1 = 0 ASS M1 = L3 END
Regards, Nic.
|
|
|
Post by John Tennison on Oct 24, 2017 12:58:35 GMT
Thanks, Nic! I'll try it soon and let you know how it goes.
|
|
|
Post by John Tennison on Oct 24, 2017 14:59:39 GMT
Nic,
THANK YOU! It is working flawlessly!
I am wondering: How would the code need to be altered so that it does not pass through the specific CC commands that are being used to transpose Note-ons?
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Oct 24, 2017 15:26:22 GMT
The neat/correct way is to block the CC inside the clause that handles it, but there is currently a nasty bug in the Stream Byter (now fixed for next update) that will rear its ugly head if I do that.
For now, just add this right at the very bottom of the rules:
IF M0 == K1 K2 XX = XX +B END
Regards, Nic.
|
|
|
Post by John Tennison on Oct 24, 2017 16:51:49 GMT
Thanks, Nic!
You have probably already considered this, but in addition to realtime control of transposition, having realtime control by a CC of velocity offset of incoming Note-Ons would also be very useful. For example, a CC value of 68 would add +4 to the velocity of all Note-Ons passing through the module; or a CC value of 60 would subtract 4 from the velocity of all note-Ons passing through the module, etc. etc.
It would even be useful at times to have realtime control by CC of channelization, where the lowest 8 values of a 7-bit CC command channelize to channel 1; the next 8 CC values channelize to channel 2, and so forth.
I would certainly welcome a channel strip that incorporated realtime control by three different CCs of Transposition, Velocity offset, and MIDI Channel respectively of all Note-On events passing through the module.
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Oct 26, 2017 11:24:15 GMT
In a future version, I would like to be able to assign any control on the canvas (where possible) to a learnt/specified MIDI event, so you'd be able to remotely control any module parameter or bypass button and maybe others via MIDI. Won't be in the next version, since it requires a bit of thought and effort, but it's definitely on my radar.
BTW, have added the Dynamic Transpose scene to the scenes club - thanks for the idea - hopefully will be useful to others.
Regards, Nic.
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Oct 26, 2017 17:51:22 GMT
Actually, I had a brainwave and prototyped a way of doing generalised MIDI remote control (toggled the panic button with a program change, hungrytenor) and it isn't as hard as I first envisaged. There is a good chance that this will be available sooner rather than later. Regards, Nic.
|
|
|
Post by John Tennison on Oct 29, 2017 9:43:08 GMT
Thanks, Nic. I enthusiastically look forward to all updates.
|
|