vishnubob / python-midi

Python MIDI library
MIT License
1.51k stars 369 forks source link

Can you pitch-shift a note (in cents or Hz value)? #160

Closed davetremblay closed 5 years ago

davetremblay commented 5 years ago

I'm trying to use python-midi for procedural microtonal music generation, and I need to know how to apply a pitch-bend value to certain notes, in cents, and what values the program would accept (integer or float). Thank you.

EDIT: I read a bit, and found the midi.PitchWheelEvent() feature, however, I'm having a hard time grasping how to calculate a pitch bend precisely.

MaurizioB commented 5 years ago

MIDI pitch bend values are always in the 0-16383 range, with 8192 used as the "center" value (no pitch bend), with values 0-8191 for negative values and 8192-16383 for positive. The actual amount depends only on the instrument configuration. Generally speaking, almost all instruments use a -1/+1 tone range, but it is usually user configurable. So, if you want to convert pitch bend values as cents, it's simple as that:

def getCents(pitchValue):
    return 100. * (pitchValue - 8192) / 8192
davetremblay commented 5 years ago

Thanks, I just found a way that the program will accept. midi.PitchWheelEvent(tick=0, pitch=X) X being the value in cents of the bend multiplied by the value of pitch bend units in one cent (which is 40.96). There you go!

MaurizioB commented 5 years ago

Good. I forgot to mention that the 0-16383 range is obviously in the 14bit format (two byte fields) with LSB first, while python-midi treats it in a "human readable" way, actually converting it to negative/positive values, which is obviously easier to work with; so -8192 (which is 0 for MIDI) becomes [0, 0], -8191 is [1, 0], -1 (which is 8191) is [127, 63], etc.