Mapping MIDI values

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Raw MIDI controller changes come in as integers from 0 to 127.

If I am mapping these to a parameter in the floating point range -1 to 1, a problem arises, there is no integer value that corresponds to zero using the straightforward formula f = 2 * (i / 127) - 1 where i is the midi integer and f is the mapped floating point value.

Would it be so bad if I were to map MIDI values 63 and 64 to zero and then stretch the remaining range into -1...1 accordingly? Or alternatively, interpret 64 as zero? Either way, one end of the range has one fewer step.

How do people handle this? I have to represent zero exactly, since there could be some additional behavior at the center point.

Post

The idea of mapping both 63 and 64 to 0.0 isn't so bad, provided you never need to reverse the mapping. Would 0.0 indicate 63 or 64?

This is a problem with all mappings between limited sets. Designing a function that is 100% reversible requires knowledge of the specific ranges and values that both sides can take. This is even more of a problem when you're mapping MIDI to parameter values which are then mapped to control ranges, such as knob positions in your GUI. You can spend an awful lot of time tweaking every mapping for every parameter. Or you can live with the fact that you never get exactly what you want, and sometimes don't get back exactly what you started with.

Personally, though, if I really just needed a middle value (and not a range of specific values, like 1 through 10 on a knob), then I think I'd treat 0 as 1, and map the range 1..127, which has a middle at exactly 64. But that's just my preference.

Post

I strongly recommend you map MIDI 64 to bipolar-normalized 0.0, MIDI 0 to bipolar-normalized -1, and MIDI 127 to bipolar-normalized +0.984375 (i.e. 63/64).

This mapping is consistent and unambiguous. The binary round numbers hit in the expected places. It doesn't change step size at the zero crossing. It behaves well when extended to 14-bit continuous controllers (where +8191/8192 = +0.99878).

Its only failing is that it can't reach exactly +1. If, for some reason, you care about that, my second best choice would be to stretch the top half of the range:

Code: Select all

midi_to_bipolar(midi):
    biased = midi-64
    if biased < 0 return biased/64.0
    else return biased/63.0
Doubling up the zero is very bad, as a slowly stepped controller will then have a jog in its response even if you do internal smoothing on the value.
Image
Don't do it my way.

Post

LOL... it figures that my guess would turn out to be the worst choice.

Thanks for the pointers, that really helped!

Post

i faced this same issue a few years ago when i wrote my own wave file reader/writer class

so i made my choice
the closest example is 8bit signed int
it goes from -128 to +127.. i map 0.0 to 0
+1.0 to +127
-1.0 to -127
thus, i don't ever use the value -128, that's a small compromise, but i have perfect zero..

this is also perfectly reversible
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post Reply

Return to “DSP and Plugin Development”