Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pitch-bend range #229

Open
page200 opened this issue Jul 10, 2023 · 5 comments
Open

Pitch-bend range #229

page200 opened this issue Jul 10, 2023 · 5 comments

Comments

@page200
Copy link

page200 commented Jul 10, 2023

In MIDI, the pitch-bend range is 2 by default, but can be modified via specific RPN messages, usually followed by specific "Data Entry" messages.

It would be nice to have functionality that understands those messages and can report the correct pitch or pitch-bend range.

As far as I understand, the pitch-bend range is set by three to four consecutive MIDI control messages. In hexadecimal, they look like this (with variables shown in bold):

B06500
B06400
B00602
B02604

The "0" after the "B" is the MIDI channel for which the pitch-bend range is being set.
The "02" in the end of the third message is the number of semitones by which the pitch can bend.
The "04" in the end of the fourth message is the number of cents to be added to the semitones.
The last message is optional, i.e. if there is no message of the form /B.26../ (like "B02604" in the example) then the number of cents is zero.

@craffel
Copy link
Owner

craffel commented Jul 10, 2023

The pitch_bend_to_semitones utility function already supports a different range than +/-2 semitones:
https://github.com/craffel/pretty-midi/blob/main/pretty_midi/utilities.py#L544
but we don't ever make use of that functionality in places where it would matter (e.g. when creating a piano roll or using fluidsynth). I agree it would be cool to keep track of these events and modify the piano roll/synthesis accordingly (assuming fluidsynth actually pays attention to these events?).

@page200
Copy link
Author

page200 commented Jul 10, 2023

pyfluidsynth assumes semitone_range=2 (see here) instead of paying attention to pitch-bend range messages. However, for existing MIDI files, midi2audio.FluidSynth (which pays attention to pitch-bend range messages, as far as I remember) can be used instead. So no problem with FluidSynth.

The problem is to access correct pitch info in Python (as opposed to letting the compiled FluidSynth executable parse a MIDI file, which is probably what midi2audio.FluidSynth does). Let's stick with your example - the piano roll:

pretty_midi does consider pitch bend in the piano roll, but it does that incorrectly in general because at https://github.com/craffel/pretty-midi/blob/main/pretty_midi/instrument.py#L150 it doesn't provide a second input argument to pitch_bend_to_semitones(). So it defaults to semitone_range=2 instead of the correct semitone_range from the pitch-bend range messages. Showing wrong pitch bend is kind of worse than not showing pitch bend.

Same during the other usage of pitch_bend_to_semitones(), namely in synthesize() at https://github.com/craffel/pretty-midi/blob/main/pretty_midi/instrument.py#L380

So yeah, it would be cool to keep track of pitch-bend range messages.

@craffel
Copy link
Owner

craffel commented Jul 10, 2023

Yes, PRs are welcome.

@page200
Copy link
Author

page200 commented Jul 10, 2023

So I looked into this, and it seems that mido should be fixed in this regard first, right?

And then event_compare() and so on. Regarding the comment "Events with the same tick time ares sorted by event type." there, is that sorting based on some official MIDI specification that should be followed or something?

@craffel
Copy link
Owner

craffel commented Jul 10, 2023

And then event_compare() and so on. Regarding the comment "Events with the same tick time ares sorted by event type." there, is that sorting based on some official MIDI specification that should be followed or something?

It's just to make writing more predictable and testable, it doesn't follow and MIDI spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants