MPE / [mpeparse] / [mc.noteallocator~] and Pitch Bend/Glide

Nick's icon

Hey all.

I'm on Max 8.0.2. Given that, under Help > Examles > mc there's an example patcher named "mc_mpe_synth." This thing is awesome. Inside, you'll notice that from the [mc.noteallocator~] object, the 5th outlet for Pitch Bend is not used. I set out to implement that within the example just to get my head around MC/MPE, and I'm way confused.

My question is simply: how do I take the value that comes out of that 5th outlet and map it onto a sensible [-1.0, 1.0] range where a value of -1.0 means "minus one semitone" and +1.0 means "plus one semitone"?

There's a helpful post here on the forums that explains this a bit, and a link shared therein for more information:
https://cycling74.com/forums/pitch-bend-ranges
https://sites.uci.edu/camp2014/2014/04/30/managing-midi-pitchbend-messages/

If I understand correctly, the value from that 5th outlet is this 14-bit MIDI pitch bend message where the first 7 bits are "fine" and the second 7 bits are "coarse." So far this seems good: if I isolate the coarse bits with [& 127] then [<< 7] I get 8192 when I'm applying no pitch bend. If I take this through [scale 0 16383 -1.0 1.0] as per the second link there, I get a value that makes sense (0.0 = + 0 semitones).

Where I'm confused though is that this seems super coarse. I'm playing with a Seaboard BLOCK and I really have to crank the pitch bend to get even up to 8320 for the coarse bits, and I have a hard time getting past that. So, I figure I have some work to do with the fine bits: for these I tried taking the same 5th outlet of [mc.noteallocator~] through [& 0x7F00] to isolate the 7 bits of "fine" information then [>> 7] to align the bits. Finally I OR the coarse and the fine values together and now I have decent behavior centered around 8192 but still it seems way too coarse. I have to slide two notes away on my Seaboard even to get past 8320.

Obviously this doesn't map to any notion of +/-1.0 representing +/- one semitone. What am I doing wrong here? Have I misunderstood the range here or is my math wrong?

Thanks!

Nick's icon

Nevermind! The issue was that my Seaboard BLOCK was configured to a pitch bend range of +/- 48 semitones, so it was using very little of the [0, 16383] range relative to what I was expecting. Dumb error... but the good news is that the approach above seems to be ok.

bd's icon

Hey Nick, I have another problem, that relates to your though by topic.
While using exactly the example synth patch, how / where did you actually add the pitch bend value to the note on original pitch?
I am trying different possibilities, but somehow adding it whether with the existing mc.target object for pitch or with a new one additionally causes problems. Pitch of other notes or new notes get messed up.
It is some timing issue I guess, like old value stored for new notes or so. Probably because of the Max message order etc. I am trying to debug this but no success so far.
So I though I ask you, before I screw my head even more :D

Diemo Schwarz's icon

Thanks, Nick for pointing out the mc_mpe_synth example. To add pitchbend, one needs the weird (to avoid an f-word) logic of abusing mc for event and control data. The key is to pass into mc immediately and do all operations in multi-channel signal domain (pretty wasteful).

Here is the wrong non-mc version that mixes up controls and the correct version.

mc_mpe_synth pitchbend WRONG.maxpat
Max Patch
mc_mpe_synth pitchbend.maxpat
Max Patch