# Converting a pitch bend (MIDI) value to a “normal” pitch value

I am trying an offline LPC analysis and synthesis using the rt_lpc (real-time LPC) implementation as given here. There are some functions within the program that can be used for an offline LPC analysis and synthesis program. The rt_lpc code is mostly meant for composers etc., which means that it uses a MIDI or glottal pulse input. There is some code in the program that converts a pitch value (obtained from auto-correlation) to the bend value. The relation is given as follows:

    pitch = (int)( Stk::sampleRate() / midi2pitch[ananya.data[1]] ) /
pow( 1.0653f, bend/64.0f*11.0f );
power *= ananya.data[2] / 64.0f;
bend = ge.data[1] / 128.0f + ge.data[2] - 64;


Some points:
a. ananya is an object of type MidiMsg that seems to be populated on the fly.
b. ge is also an object of type MidiMsg that also seems to be populated on the fly.
c. These two objects are created when the program is run in real-time (mine is an offline version that runs selective parts of it in a main.cpp of my own.

My question(s):
1. What is pitch bend?
2. How do I convert a pitch value into a bend value? What are the mapping relations?

At the core of MIDI is a representation of music as discrete note events, each of those having a static pitch. This is perfect for representing music as played on keyboard instruments. You can convert any frequency corresponding to a note on the tempered scale into a MIDI note number, using:

$69 + 12 \times \log_2 \frac{frequency}{440}$

Under the assumption that the MIDI receiver is calibrated for A4 = 440 Hz.

This representation is alright for piano music, but the problem is how to represent pitches which are not mapped to the tempered scale (non-western music, non musical sounds), and how to represent pitch variations over the duration of a note (glissando, vibrato).

This is done in MIDI by using "pitch bend messages" which instruct the synthesizer to shift the pitch of the currently played note by a small interval. Most synthesizers are calibrated by default for +/- 2 semitones over the course of the pitch bend message range (0 .. 16383). 8192 corresponds to no pitch bending - the emitted pitch is exactly that of the note value. The mapping between the pitch bend value and the frequency shifting ratio is given by:

$\frac{f_{emitted\_note}}{f_{note\_message}} = 2 ^ {\frac{pitchbend - 8192}{4096 \times 12}}$

You can thus get the frequency of a note played by a syntheszier from the following formula:

$440 \times 2^{\frac{note - 69}{12.0} + \frac{pitchbend - 8192}{4096 \times 12}}$

Where note is the 7-bits MIDI note number of the last received Note On message ; and pitchbend is the 14-bits value of the last received Pitch bend message. A synthesizer starts with its pitch bend register set to 8192, and this value is also reset during the reception of a "Reset all controllers" message.

Let us take the following example. You want to express a flute trill with the following frequency trajectory: 500 Hz, 510 Hz, 500 Hz, as MIDI messages.

The base note number is:

$round(69 + 12 \times \log_2(500 / 440)) = 71$.

So you send a "note on" message with note# equal to 71. This is equivalent to a pitch of:

$440 \times 2 ^ {(71 - 69) / 12} = 493.88$

Which is the nearest pitch on the tempered scale. You need to send a pitch bend message to raise the pitch by a factor of:

$\frac{500}{493.88} = 1.0124$

And get your 500 Hz. The corresponding pitch bend value is:

$round(8192 + 4096 \times 12 \times log_2 1.0124) = 9065$

To get your 510 Hz, the pitch bend value would be:

$round(8192 + 4096 \times 12 \times log_2 \frac{510}{493.88}) = 10469$

So your sequence of MIDI messages for 500, 510, 500 Hz would be:

• NOTE 71
• PITCH BEND 9065
• ...
• PITCH BEND 10469
• ...
• PITCH BEND 9065

You can think of the MIDI note number as the "integral" part of the pitch ; and the pitch bend as a redundant "fractional" part of the pitch.

• Also, from my understanding of the code, ge is the pitch bend message ; ge.data[2] its MSB and ge.data[1] its LSB. ananya is the note on message, ananya.data[1] is the note number and ananya.data[2] the velocity. Besides the funky variable naming which seems to imply a hidden romance between the authors of the code, I see a potential WTF here: there's something fishy in the 1.0653f and 11.0f constants. A readable choice would be: 1.05946f and 12.0f. Or 1.06504f and 11.0f. The authors seem to assume a pitch bend range of +/- 1 octave, which is another potential WTF. – pichenettes Mar 6 '12 at 15:19
• ROTFL on the "hidden romance" part! I dont think I have understood this properly so bear with me. The pitch value is obtained from the function autocorrelate, which seems to me like it is the MIDI Note that is output. Notice the midi2pitch array in the formula? If I am right, that means that I still do not have the bend value or the actual value of the pitch to estimate the bend value from, and no way of getting them either unless I have a MIDI file. A simple case of too many variables and too few equations. How do I estimate the bend, actual pitch value and the velocity in this case? – Sriram Mar 7 '12 at 12:06
• What are you trying to do? Convert a pitch/power pair to MIDI messages? Or convert MIDI data to an actual pitch? The code given above converts a pair of incoming MIDI note + pitch bend messages (ananya msg, ge msg) to a period (pitch variable) and a power (power variable). I think this is used to replace the LPC excitation by a synthetic one controlled by a MIDI keyboard - a sort of crude vocoder or autotune effect. – pichenettes Mar 7 '12 at 12:15
• a quick look at rt_lpc.cpp confirms that incoming MIDI messages of type 0xe0 (PITCH BEND) are updating the pitch bend value ; and that incoming MIDI messages of type 0x90 (NOTE ON) are copied into the "ananya" message. From there, resynthesis using a modified pitch is done using these values. Not sure what you want to do from there. – pichenettes Mar 7 '12 at 12:19
• Yes, the MIDI input is here a totally different thing for creative signal transformation. It is not part of the normal LPC analysis / synthesis chain ; but instead allows some parameters (pitch and power) to be read from a keyboard rather than produced by the analysis module. Maybe you could post a new question with some examples of audio files, and extracted pitch trajectory in Hz, so that we could orient you to more robust pitch estimation techniques. The Aubio library has a few variants of pitch trackers. – pichenettes Mar 7 '12 at 13:30

MIDI is a protocol that allows (primarily) synthesizers to control or be controlled by other synthesizers or computers.

It's a serial protocol that allows to exchange messages such as "key C1 up" "key D4 down" "key velocity, "sound change", etc. Many controllers have a "pitch wheel" that's a joystick or am modulation wheel. These allow the player to interactively change the pitch of the current note being played to manually create vibrato or to continuously "slide" from one note to the next. As this frequently done by guitar players by bending the fretted string with their left hand, it's often called pitch bending and hence the name.

The MIDI pitch bend message is a way to communicate how much pitch shifting is supposed to happen at any given point in time. A synthesizer (software or hardware) receiving a pitch bend message is supposed to change the pitch of all current notes being played by the given amount.

The controller message has an argument that goes from -8192 to 8191 and in standard MIDI files this is supposed to cover the range from -200 cent to 200 cent, where 1 cent is 1/100 of semitone, i.e. a ratio of 2^(1/1200) = 1.000577789506555. Example: to create a pitch shift downward to get to 93% of the nominal frequency, the controller value would be

c = round(log2(.93)*12*8192/2);


or -5146 in this case. 0.93 is the ratio you want, 12 the number of semitones per octave, 2 the max pitch bend range (200 cent or 2 semitones in this case), and log2() the logarithm with basis 2.

However, in most synthesizers the range is configurable and it's probably not a good idea to assume that all synthesizers behave the same.

Here is a conversion chart that may help. http://www.elvenminstrel.com/music/tuning/reference/pitchbends.shtml