I got a Roli Seaboard. Super fun! -BUT it makes non-MPE/single channel synths either freak out or not work at all. Essentially sending (potentially) wildly different CC values one after another. Flippy floppy filter knobs! Warbling notes! The main issue is that each finger sends it's own aftertouch, "brightness", and pitch bend. In the studio at home on Ableton I can "deal with it" through Max-for-Live by, at the least, simply stripping these values out and Live "helps" by combining everything to Channel 1.
BUT- I am transitioning to iOS for live performance use and expect that MidiFire will come quite in handy for various things: Roli, BopPad, Helix and Triple Play all included.
I would like a bit of code that will take all of these separate MPE channels and spit out a single channel of usable data so I can switch to an non-MPE/Multitimbral synth in AUM using the MidiFire input instead of the Seaboard direct. Combine all note messages to one channel (simple) Average all the aftertouch/pressure, CC74, and pitchbend controllers from any keys currently engaged (not so simple)
Yes, you're right - not so simple, especially as pitchbend is a 14 bit value...
I *think* I could come up with something, but maybe we could start with something simpler - strip out all the unwanted data except for the first held note? Maybe that would come close enough? I think it is worth a try before trying to calculate averages. :-)
Something like this:
IF LOAD # number of currently sounding notes ASS L80 = 0 END
# collapse everything to channel 1 XX = X0
# munge note on/vel0 9X XX 00 = 8X
# count held notes IF MT == 90 MAT L80 = L80 + 1 END IF MT == 80 MAT L80 = L80 - 1 END
# if just one note held, then block certain # events that come just before the second held note IF L80 >= 1 BX 4A = XX +B # CC 74 EX = XX +B # pitchbend END
# if more than one note held, block certain # events that come after the second held note # (and before and after subsequent notes) IF L80 > 1 AX = XX +B # aftertouch DX = XX +B # channel pressure END
There's a possible side issue here in that I don't know whether the Roli sends the pitchbend (and CC) before or after the note event. I suspect pitchbend and maybe the CCs are sent before and the rest after. The code above assumes this. If not, you may need to move those blocking rules around between the two IF L80 clauses.
Could you give that a whirl and see how you fare. It might just be sufficient before we delve into trying to average stuff. Note, I have not tested the above; it may not compile or could have logic errors.
Last Edit: Jan 11, 2019 13:01:30 GMT by nic: update code
Thank you Nic Just watching through event monitor it appears that when only fingering a single note then everything is stripped except pressure after touch. So I assume it's the other way round order then, maybe?
More importantly as soon as a second note is held down *only* note on/off messages are sent and everything else is blocked.
Just trying to organize the flowchart scripting an "average of whatever keys currently active" hurts my brain. The most complex bit seems to be adding/removing keys from the current average. The workaround of using only the first note's values is OK though "last key touched" might be a more practical "usable" solution, though not optimal. Possibly easier to script using last note also. Most important, "last note played" would make mono synths react better, maybe. I'm afraid that to truly do that right an array would need to be used so the script could fault back to the "previous last note" and that seems just as complicated to me as doing the full averaged array thing, Also, other than pitchbend and aftertouch it might maybe help to limit the script to the specific "Slide" CC: #74, /shrug
Well, your monitor output suggests that bend/cc74 are sent before the note and channel pressure after the note which is what I had expected. No sign of any aftertouch.
Is the event monitor dump showing a keypress before or after the StreamByter code? I think you're saying it's before?
I have made a couple of small revisions to the code above (specifically handle CC74 instead of all CC's and changed logic to cater for one or more held notes vs 2 or more held notes).
>> More importantly as soon as a second note is held down *only* note on/off messages are sent and everything else is blocked.
That is what the code supposed to do.
Just looking at the code again, I think it should be doing the right thing, but could you repeat your event monitor but monitoring the StreamByter output (or even better two separate monitors - one before and one after for comparison). I may have a bug that I'm just missing.