MPE channel splitter based on note ranges (seeking help)

A Life In Binary's icon

Hi all,

I have a MPE keyboard, the Osmose, to be specific and I would like to create a patch that takes the incoming MPE data and re-assigns the channels depend on note ranges that are defined.

For example:
Any notes played between C1 and G2 would be assigned to a MIDI channel within 2-5 range (inclusive).
Any notes played between G#2 and C4 would be assigned to a MIDI channel with 6-10 range (inclusive)
And any note above C#4 would be assign to a MIDI channel with 11-14 range (inclusive)

I'm cut my teeth in Max prior to the invention of MPE and haven't had much opportunity to play around with the MPE objects since they were introduced in version 8, so I'm looking for a bit a guidance from the Max community with how to go about doing this.

The most significant challenge that I've faced so far is having collection of channels and notes that the Osmose sends and their corresponding re-assignments in order to prevent stuck notes.

  1. The logic that I've come up with so far is as follows:
    Upon Note On event store note and channel in a coll object

  2. Depending on which range the note falls within, assign it a new channel and remember it until the note off message is received at which point the data should be reset/deleted for that channel/note

  3. Send that message out of a virtual Max MIDI port to a hardware synth or software instrument.


Imagine you have 14 mono synths at your disposal, each one listening on a dedicated MIDI channel for notes, pitch bend, channel pressure, aftertouch, etc. but the mono synths on channels 2-5 have bass patches, the synths on channels 6-10 have pads, and the synths on 11-14 have lead patches.

MPE controllers like the Osmose assign channels in a round robin fashion, which would send notes at random to these devices. Essentially what I want to achieve is to give order to the incoming MPE data and control it so I can orchestra a number of synths from a single MPE keyboard. Would be super cool, don't you agree?

Looking forward to realising the potential of this. Thanks for reading :)

Peter Ostry's icon

The mapping problem gets worse when it comes to polyphonic pitch bend.

I cannot help with the patch but recommed testing this many synths with flowing notes and the mapping you have in mind. I tried similar ideas with MIDI guitar (6 channels) and a Roli keyboard (MPE and Multichannel). It didn't sound super cool, but rather super dorky. It may have been my fault, but you'd better simulate the concept using conventional methods before you dive into your Max project weeks ...

tyler mazaika's icon

"Any notes played between C1 and G2 would be assigned to a MIDI channel within 2-5 range (inclusive)."

Trying to understand.. do you mean to output this 19 note range to a single MPE-capable synth? Or further subdivide the 19 note range among 4 instruments?

Also, if you're just doing this in Max, why are you thinking of putting all these MIDI outs on a single port (which would mean you need to implement new channelizing logic to keep your instrument groups subdivided). You could just use separate MIDI Ports out.

Anyway, the basic model that works okay is to use the right outlet of [mpeparse] to connect to a poly~ object where the voice patches have a polymidiin (the outputs probably to another mpeparse in the voice). Using [mpeparse] is important because it's the only object which also transmits Release Velocity ( midiselect/midiparse do not). Then you have a midiformat leading out of the voice and just re-assign the channel based on your logic at note on.

You'll need to test carefully about the note-on message received order, because you may get MPE data for the controllers (pressure/bend) BEFORE the note-on, in which case you probably need a method for making sure those initial control changes (a) don't get sent through on the un-remapped channel first and (b) get sent correctly on the remapped channel.