Tuesday 30 March 2021

MIDI Pitch Bend - A Tiny Inconsistency

Sometimes 'The Bears' really are lurking, ready to get you if you step on the cracks between the paving stones... 

One of the things that has been beaten into me, over many years of working with hardware, firmware and software, is a rule that has many forms, but which boils down to something like:

"Question everything. Measure everything at least twice. Always ask: 'Why?"

It is an expanded version of the 'Never Assume Anything' rule. It has served me well. But you must never let your guard down...

Ever...

Photo by Synthesizerwriter

The MIDI Pitch Bend Inconsistency

As with all unexpected things, it crept up on me silently, unannounced, from a direction I wasn't expecting. When you have spent a long time with something, then you think you know about it. Since I got my first copy of the original MIDI Specification back in the mid 1990s, then I have read it carefully and repeatedly. I spotted some of the things that were put in there by knowledgable hardware people who really knew their stuff, like what a MIDI Clock message actually looks like 'on the wire' of a 5-pin DIN cable, and why it was defined like that. And since you are now intrigued, I'm going to leave that until another post...

So the original MIDI Specification 1.0 (1996) has a section for Channel Voice MIDI Messages, starting with Note On (0x8n in modern formatting, but shown in mid 90's style as 8nH, where 'H' means Hexadecimal and 'n' is the MIDI channel (0x00-00xF or 00H-0FH for 1-16)), then Note Off (0x9n, 9nH), through to Pitch Bend (0xEn, EnH). After that you have the System Common MIDI Messages, which all start with '0xF'. So all of the 'highest bit set' values are specified, from 0x9 to 0xF.

The Pitch Bend message is the last of the Channel Voice messages to be specified, and the specification  contains just two paragraphs - the second of which is just two sentences and is just clarification about sensitivity. Here's that first paragraph:  

This function is a special purpose pitch change controller, and messages are always sent with 14 bit resolution (2 bytes). In contrast to other MIDI functions, which may send either the LSB or MSB, the Pitch Bender message is always transmitted with both data bytes. This takes into account human hearing which is particularly sensitive to pitch changes. The Pitch Bend Change message consists of 3 bytes when the leading status byte is also transmitted. The maximum negative swing is achieved with data byte values of 00, 00. The center (no effect) position is achieved with data byte values of 00, 64 (00H, 40H). The maximum positive swing is achieved with data byte values of 127, 127 (7FH, 7FH).

There are quite a few important take-aways in this paragraph. Firstly: Pitch Bend messages are ALWAYS 14 bit resolution. Now I've done quite a lot of Max and MaxForLive devices, and Max is a very useful general purpose tool for exploring MIDI... In Max, there are two basic objects that are used specifically for receiving Pitch Bend messages (there are other, more generic MIDI 'parsing' objects...): 'bendin' and 'xbendin'. 'bendin' is the 'basic' object, and it returns 7-bit values for pitch bend of 0-127 (a single MIDI data byte), whilst 'xbendin' is the 'extra precision' object, and it returns 14-bit values from 0-16,383 (two MIDI data bytes)). 

7-bit and 14-bit Pitch Bend objects in Max

The next important thing here is that the 'bendin' object is throwing away the second byte, the Least Significant Byte (LSB), so the values that you get are just the raw 7-bit values (0-127) that are in the Most Significant Byte (MSB). As I'm sure you know already, individual MIDI 'bytes' only have 7 bits available for data, which is why the value doesn't have the range of 0-255. You need multiple MIDI 'bytes' in a message to get extra resolution. In the 14-bit-oriented way that MIDI represents higher resolution numbers, then for a value represented with two 'bytes', the MSB is the top 7 bits, and the LSB is the bottom 7 bits. So the range covered by the LSB is from 0x0000 to 0x007F (0 to 127) in steps of 1, whilst the MSB is from 0x0000 to 0x3FFF, in steps of 128. Now 0x3FFF is 16,383, so that's where the full MIDI Pitch Bend resolution of 0-16,383 comes from.

Note. I need to point out that Pitch Bend messages, by design, should include 14-bit 'extra precision' values - as noted by the MIDI Specification - because pitch bend is a 'special purpose' controller. Max and MaxForLive provide access to the 7-bit lower resolution value only because that value can then be used for other things, anywhere in MIDI or Ableton Live, or even externally if you convert it to a Control Voltage. For the control of pitch, then 14-bits are a much better idea, because this will give you nice smooth changes of pitch.

Ok. All sorted.

Not quite. There's a problem. 

Pitch Bend is bipolar: it can be positive or negative. In MIDI, the 'no bend', middle, detented position is defined as being a value of 8,192 (0x4000 or 4000H), which would be output as a value of 64 from Max's 'bendin' object and as a value of 8,192 from Max's 'xbendin' object. Max does provide another special object, called 'xbendin2', and this outputs the two 7-bit Bytes separately, so you can see the actual MSB and LSB if you want to. 

So negative Pitch Bend is the 64 values from 0 to 64 when we are talking 7-bit resolution, and the 8,192 values from 0 to 8,192 for 14-bit values. All perfectly fine and reasonable. But the positive Pitch Bend is slightly different. it can only go from 64 to 127, which is 63 values, because the highest 7-bit value MIDI allows is 127. yes there are 128 possible values in 7 bits, but if you start at 0, then you end up at 127. There are 128 values between 0 and 127. Max's 'bendin' object only provides 7-bit values for controlling other 7-bit parameters, and you would not use it for actually bending the pitch of a note - you would hear the steps! But the smaller numbers do make it very clear what is happening...

In 14-bits, then it goes from 8,192 to 16,383, and there are only 8,191 values, because 16,384 is ever so slightly larger than you can represent in a 14-bit number. 

The MIDI Specification 1.0 doesn't hide this. That final sentence of the first paragraph says:  

The maximum positive swing is achieved with data byte values of 127, 127 (7FH, 7FH).

The previous two sentences in the paragraph define the centre position and the maximum negative swing - but most people don't notice that 0->64->127 and 0->8,192->16,383 aren't symmetric. There is one less positive number than negative, and it is not hidden, it is in plain sight, printed in the specification. Unfortunately, the big numbers (16,383, and 8,191) tend to obscure what is actually happening...

In other words:

If no pitch bend at all has a value of zero, then the most negative pitch bend value is -8192. But the most positive pitch bend is 8191. (14-bit values are used here because these are what pitch bend applies to!)

Yep, The Bears just got us. 

The MIDI Pitch Bend Message doesn't allow us to bend up by the full amount. We can bend down and produce 64 7-bit messages or 8,192 14-bit messages (assuming our MIDI Controller outputs every value as a message, but that's another story). But when we bend up, then there are only 63 7-bit or 8,191 14-bit messages that can be output. That final value (8,192) is just outside of what MIDI allows. 

This means that if you set your PitchBend sensitivity to be 1 octave, then you can bend down by exactly one octave, but you will only be able to bend up by slightly less than one octave. The Owner's Manuals for MIDI Controllers, synthesizers and any other devices that output MIDI Pitch Bend messages generally say it exactly like it is - they say what the maximum positive output is. What they tend not to mention is that this is slightly less than what you need to do a pitch bend up that has the same range as a pitch bend down. And with 14-bits of pitch resolution, then the difference is very tiny. Miniscule.

In fact, I would guess that you've never noticed it...

So if you want exact pitch bend that utilises the end-stop of the Pitch Bend wheel or lever, then you should only bend downwards. This applies to any device that uses MIDI 1.0, regardless of age, firmware, operating system or manufacturer. Oh, and MIDI 2.0 is... different, because it has even higher resolution available.

Actually, there's another solution, and that is to not use the limits of the Pitch Bend wheel or lever (or push pad, or however it is implemented on your device), and that is to set the range to one note more than you require, and then to only move the wheel, lever, etc. by the amount required to get the bend you actually require. So for an octave, you might set the range to 13 notes up and down, and then only ever bend up or down by 12 notes. This gives perfect pitch bending, albeit with slightly less than the resolution of 16,384 values that were intended by the MIDI specifiers (but only very slightly less!). It does mean that you can't use the end stops of the wheel, lever, etc, but that's a minor inconvenience, and Pitch Bend by ear is so much better than relying on mechanics...

Oh, yes, and if you are thinking that this is a tiny difference in the pitch bend, and that it doesn't matter, then re-read that section in the MIDI Specification 1.0. It says that the MIDI Pitch Bend messages always use 14-bits resolution BECAUSE '...human hearing... is particularly sensitive to pitch changes.' I will gloss over the fact that it then goes on to define positive MIDI Pitch Bend so that it isn't perfect in precisely the place where human hearing is particularly sensitive. 

Not an Error

Actually, there is no error at all here. Nothing to see. This isn't a mistake by the people who wrote the MIDI Specification 1.0. It is nothing more than a consequence of the way that number work in these particular circumstances. Image the simplest pitch bend controller: three positions, No Pitch Bend (in the middle), Full negative (at one end of the travel of the wheel, lever...), and Full positive (at the other end of the travel). So these could be represented by -1, 0 , and +1. But this gives a jerky pitch change, of course!

If we increase the resolution by 5 times, something interesting happens. The range is now -5 to 0 to +5, and there are 11 values instead of the 3 values that we had for -1, 0, and +1. So if we start with the most negative value (-5) and assign it to 0 on the pitch wheel, then the middle (zero) value will be at 6 on the pitch wheel, and the most positive value will be at 11. Aha!: We have a Marshall Amplifier 'goes up to 11' situation. Unfortunately, no matter how the range and the resolutions are set, there will always be an odd number of values, consisting of the negative numbers, plus the negative numbers, plus that zero in the middle. So we need a controller with an odd number of values (which would also be very useful for that Marshall amp!)...

The binary world of computer is even. The basic counting system (binary) is based on two values: 0 and 1. So if you have just one bit to represent a number then there are two possible values: 0 and 1. Two bits gives four values: 00, 01, 10, and 11, which are 0, 1, 2, 3, and 4 in decimal number form. Any number of bits used will always give an even number of possible values. MIDI's 7-bit numbers have 128 different values, which are normally shown from zero: 0 to 127.  MIDI's 14-bit numbers have 16,384 different values, and if we show them from zero they go from 0 to 16,383. 

(Decimal numbers are even as well! So are pairs, dozens...) 

When we take these even numbers of possible values and try to map them on to a Pitch Bend wheel, lever, etc. then there's a problem, because we now know that the total number of pitch bend values are always odd since there has to be a zero in the middle. The positive and negative values are symmetric and have the same range, but the need to have a zero position in the middle adds an extra number and we get an odd number of values. No matter how hard you try, if you have an even number of drawers and an odd number of things to put in those drawers, there will always be at least one empty drawer or thing left over (each drawer will hold only one thing, of course, in this scenario - which matches the way that numbers work very nicely!). 5 drawers and 4 things? One drawer will be empty. 4 drawers and 5 things? One thing will be left over, because all the drawers will be full. 

One possible solution is to have two zeroes! If you assign two of the values in the middle to zero, then you can have perfect matching! 

In the case of MIDI Pitch Bend, the design puts a single 'no pitch change' zero value at 8,192, full negative at 0, and full positive at 16,383. So the negative range has 8192 different values (0 to 8,192), and the positive range has 8,191 different values (8,192 to 16,383, which is 8,191). There is no value of 16,384 because that would require a 15-bit number, and we only have 14-bits. 


So the biggest negative pitch bend message value is -8,192, and the biggest positive pitch bend message is +8,191. The biggest possible positive pitch bend is always going to to be 1/8192th smaller than the biggest negative pitch bend message value. And it is a teeny, tiny value! Nothing to worry about. It is a minute pitch difference.

But it is an inconsistency!  

  







---


If you find my writing helpful, informative or entertaining, then please consider visiting this link:

Synthesizerwriter's Store (New 'Modular thinking' designs now available!)

Buy me a coffeeBuy me a coffee (Encourage me to write more posts like this one!)




 



2 comments:

  1. I had always assumed that the pitch-bend range up, or down, would be the precise number of semitones as programmed. It's just that the data coding going up would be at a very slightly lower resolution than that going down.

    ReplyDelete