[Solved] Unexpected behaviour in MPE object


#1

I use the midi/ctrl/mpe object in patches for my Seaboard Rise.

I experienced some unexpected behaviour. Whenever I change the octave on the Seaboard my bendrange in the Axoloti changes. Initially I used the pitch outlet to control my osc, but I had to change the patch so it uses the note and the bend outlet.

Today I connected my Seaboard to a midimonitor and I discovered what caused this behaviour. When I change the octave on my Seaboard it sends a control message (Hex B0 6 #)

When I examine the MPE object I found the following code:

switch(data1) {
case MIDI_C_RPN_LSB: lastRPNLSB = data2; break;
case MIDI_C_RPN_MSB: lastRPNMSB = data2; break;
case MIDI_C_DATA_ENTRY: {
if (lastRPNLSB == 0 && lastRPNMSB == 0) {
_bendRange = data2;.

IF the MPE object receives MIDI_C_DATA_ENTRY it changes the bendrange to data2. On the Seaboard this is the octave setting I do not know what is the reason to respond to Data Entry MSB but in combination with the Seaboard the bendrange is changed.


#2

Id need to double check, but basically the MPE draft allowed the bend range to be altered with an NRPN message - so that’s what I implemented.
It may have changed since that (early) draft, as I did it a long time ago ...and I’m guessing Roli are using an nrpn for octave change buttons.
( don’t know though as don’t have a Roli)


#3

I had the same behavior with the Seaboard. Try using the module from TSG's Buzz or Karp MPE synth. Using note+bend (and not pitch, which seems to have a similar problem) this works perfect for me.


#4

I did some further digging and you are right the latest specification also states that the pitch bend range can be changed by using RPN 00H 00H.

But the Roli sends out
$B0 99 0
$B0 98 2
$B0 6 #
Which is a Non RPN

It seems that the axoloti responds like it receives
$B0 101 0
$B0 100 0
$B0 6 #

I checked and MIDI_C_PRN_LSB and MIDI_C_PRN_MSB are set to 0x64 and 0x65


#5

i cant see that that is the case given the generated code is:

firmware/midi.h:#define MIDI_C_RPN_LSB                  0x64 // registered parameter LSB
firmware/midi.h:#define MIDI_C_RPN_MSB                  0x65 // registered parameter MSB

} else if (data1 == MIDI_C_RPN_MSB || data1 == MIDI_C_RPN_LSB || data1 == MIDI_C_DATA_ENTRY) {
    switch(data1) {
         case MIDI_C_RPN_LSB: _lastRPN_LSB = data2; break;
         case MIDI_C_RPN_MSB: _lastRPN_MSB = data2; break;
         case MIDI_C_DATA_ENTRY: {
              if (_lastRPN_LSB == 0 && _lastRPN_MSB == 0) {
                _bendRange = data2;
              }
            }
            break;
        default: break;
    }

this all looks perfectly ok to me...

i need to look at the latest mpe spec to see if there are any alterations needed.

note+bend on TSG buzz, there is a known issue i think also logged on the Axoloti repo, i can't quite remember what it was off-hand... its probably also on the forum somewhere... again, I'll take a look when i get time.


#6

Hi Mark,
I found the problem. lastRPNLSB and lastRPNMSB initialize to zero on declaration. So if the first two case statements have not been executed the if statement in the last case statement is still executed.

Initializing them at 128 on declaration could in my opinion solve the issue without interfering with normal use.


#7

I haven't noticed this with my Seaboard block, but it reminded me of a minor tweak I do to the MPE object for slide (timbre). What happens is that _timbre isn't reset on a new note, so I get a jump from the old value to the new when I start sliding. I haven't really looked at the code at all, so not sure if there is a reason things are like they are, but I reset _timbre to 0 on my patches for the Blocks and that seems to work fine.

  if (_note == data1-64) {
    _rvelo = data2<<20;
    _gate = 0;
    _pressure = 0;
    _timbre = 0;
  }

#8

and indeed this should not happen...

the reason is, the controller should send timbre (CC74) before the note on.
(so you definitely do not want to reset it)

imagine your using your seaboard (with absolute timbre mode, or whatever its called on the Roli)

press at the top of the wave, and the timbre should start at 127 (not 0), and you want this before note-on, so the sound engine does not sound at 0, and then suddenly switch to 127.
similarly , you do not want to reset it at note-off, since the sound engine may have a 'tail' (e.g. release on an amp envelope) , so you want to it to ring out with the last timbre you had before you lost contact with the surface.

(the same is true for pitchbend btw , pressure is Ok, because note-on/off indicate touching the surface so can change pressure... though really this should not be necessary if the controller is correctly coded!)

this is one of the issues with MPE spec, which I raised really early on with the writers of the spec. they have not well specified some aspects of when messages are sent... to define a model of how sound generators can work.
this actually is very important due to the serial nature of midi messages.

unfortunately, they were not interested in listening, as they just wanted to push it thru.
(fair enough, I suppose given how its taken even in its current form)


#9

Maybe they listened better then you expected. In version 0.61 of the MMA it is mentioned that these values should be set before note on.:grinning:


#10

I believe the Seaboard block does not have octave switches and the controller values that made the issues vissible where send when using those switches.

Handling timbre is an issue that is new to MPE type controllers I think . I believe there are three approaches you can have towards this. Use the relative position you touch the "key" as starting controller value, consider this position you hit the "key" as zero or consider the position you hit the "key"as 64 (mid midi controller). I believe that on the axoloti there could be a use for each of them. The Seaboard Rise sends out the relative value ( I coudl not find the parameter to change this). I personally prefer to use the starting position as zero value and use the slide up and down to control the connected parameter. I have created a controller object (azaxo/ctrl/SeaboardSendMixer5OutSH) that latches the starting value and subtracts this starting value from the actual controller value.


#11

cool, they finally got there :wink:

im not so sure its 'approaches', as being being a down to the physical nature (and implmentation) of the expressive controller.

relative is often preferable, where the Y axis on the controller is small, i.e. you cant really start in a definite Y position (think Roli block/linnstrument), or the mechanics of the controller e.g. eigenharp (discrete keys) /seaboard rise (piano layout), make it preferable.

however, something like the haken continuum and Madrona Labs Soundplane which have a larger and full continuous Y axis, absolute feels much more relevant, so you can start the sound wherever you want it to be.. i enjoy this a lot :slight_smile:

but as such, all this should be hidden from the sound generator... the point of 'mpe' is to present the controllers in a unified way... so basically as a continuous x/y/z surface, its then up to the controller to allow different 'modes' if necessary e.g. absolute/relative.

anyway thats how i work it... i write patches as if the surface is completely continuous, so they work well with my Soundplane, but they also work well with my Eigenharps... even though they are quite different.

that all said, i find is you always end up 'refining' patches/presets for the specific controller. I'll often find particular patches which i really enjoy on one controller are pretty 'average' on others. its to do with how they play/feel - I put this down to the fact the response rates / sensitivity which really vary between controllers.

(this is a point Ive heard Haken/Eagen make, that to make a really good expressive patch, it needs to be closely tied to the characteristics of the surface, then it feels 'natural')


Timbre ("Glide") on Seaboard Rise
#12

Right, makes sense. I think CC74 wasn't sent on a note on (I remember checking that the Eigenharp sent it, but the Seaboard block didn't). Since I was using "relative bipolar mode" and no tail (pressure to VCA) resetting to zero as a fix worked fine.

In any case, I checked again now on current firmware and CC74 is indeed sent. Sometimes before note on, sometimes after, according to my midi monitor. The Seaboard block firmware I was using at the time was buggy and quickly got updated, so not sure if it was a temporary bug or I was simply plain wrong. Nice to know I don't need to worry about it any more.


#13

I think I agree with them on this. You need to "learn" your controller before you can get the most out of it. The way it controls your soundsource is another aspect of this learning process. With traditional accoustic instruments like a guitar these are connected but even then with a new guitar comes a new learning process. I understand your view that multidimensional controllers and soundsources have an identical "interface". But my apporach is much more practical I want to create nice and uniques sounds. Instruments like the Roli Seaboard in combination with an Axoloti open up the door to many new expressive possibilities.

But I am working on a synth for my seaboard. When it is finnished I wil drop it in my community folder and I am curious how it interacts with your other expressive controllers.