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

Fix MIDI note-on events being converted to note-off events #66003

Merged
merged 1 commit into from
Oct 12, 2022

Conversation

voidshine
Copy link
Contributor

This PR fixes a bug in Godot's MIDI processing logic that destroys information as it flows from device to application. The engine converts note-on events with velocity 0 to note-off for programmer convenience, which is sometimes helpful and sometimes confounding. In fact, MIDI device implementations vary and some MIDI devices intend for note-on to mean note-on regardless of velocity. So the only way to support such devices is to faithfully pass MIDI information to the application exactly as it is received from the device.

It's up to application developers to decide how to handle received MIDI data and it's a very minor inconvenience to convert if needed, but having the engine interfere and mutate event data before it reaches the application makes some use cases impossible.

I commented on this before but the issues were closed, so now I'm submitting a fix directly:

@voidshine voidshine requested a review from a team as a code owner September 17, 2022 20:06
@Calinou Calinou added this to the 4.0 milestone Sep 17, 2022
@Calinou Calinou added cherrypick:3.x Considered for cherry-picking into a future 3.x release cherrypick:3.5 Considered for cherry-picking into a future 3.5.x release labels Sep 17, 2022
@akien-mga
Copy link
Member

akien-mga commented Sep 18, 2022

The documentation should likely be improved to advise users that they have to do this check themselves if they rely on this common convention.

Not suitable for a 3.5 cherrypick as it breaks compat, so removing that label.

@akien-mga akien-mga added breaks compat and removed cherrypick:3.5 Considered for cherry-picking into a future 3.5.x release labels Sep 18, 2022
@voidshine voidshine requested a review from a team as a code owner September 18, 2022 17:29
@voidshine
Copy link
Contributor Author

Good idea, thanks -- I added a second commit that updates the documentation.

@reduz
Copy link
Member

reduz commented Oct 10, 2022

AFAIK I am not sure what the point of this is, NOTE ON with velocity 0 is always expected to be note off. Any synth will react to this.

@voidshine
Copy link
Contributor Author

Hi Juan, first of all, I want to say thanks for all your work on Godot -- awesome engine!

The point of this change is to make it possible for Godot applications to work correctly with all kinds of MIDI input devices. To do that, Godot must report MIDI input events accurately. Currently, Godot is tampering with events in a way that makes some applications impossible. The mutation is often harmless, but not always, and when NOTE ON is transformed by Godot into a NOTE OFF, the application has no way of knowing.

Some MIDI keyboard implementations are very simple; they use the full velocity range from 0 to 127 with NOTE ON for key presses, and then they use NOTE OFF for key releases. For such keyboards, a gentle press of the key will play a quiet note in other apps, but will be ignored as a NOTE OFF in Godot apps. There's no way for a Godot script to know the truth that the device reported a NOTE ON, because Godot mutated it. The mutation was well-intended, for the sake of programmer convenience, but it's inaccurate. So this PR is a bug fix, improving Godot's correctness and capability.

@reduz
Copy link
Member

reduz commented Oct 11, 2022

@voidshine makes sense, I guess if you want to use a device as a controller for a specific situation, Godot should simply pass what comes in, as there is no reason to alter it.

@akien-mga
Copy link
Member

For the record, the email you used to author this commit isn't valid, so it's not attributed to your GitHub account (see the header of https://patch-diff.githubusercontent.com/raw/godotengine/godot/pull/66003.patch). If you want to change it, you can do so by editing your local Git identity and then git commit --amend --reset-author).

@voidshine voidshine force-pushed the fix_midi_event_mutation branch from 80a5efe to 60b63bd Compare October 11, 2022 15:19
@voidshine
Copy link
Contributor Author

Thanks for accepting the change! Excited to make my first little contribution here. :)

@akien-mga
Copy link
Member

Could you squash the 2 commits? See PR workflow for instructions.

(For the record that's why I suggested amending the original commit with git commit --amend, instead of making a new commit.)

That would also give you the possibility to fix the email on that first commit, which is still the original invalid one.

And finally, the new email you used is valid, but not tied to your GitHub account. That's not a problem, but if you want the commit to appear as authored by @voidshine, you can add that email as secondary email in your GitHub settings.

@voidshine
Copy link
Contributor Author

@akien-mga I actually did use --amend, I entered the git commands as written. So there should only be my original two commits, no extras. Are you saying I should not have created the second documentation-update commit in the first place? Having two seemed sensible at the time and doesn't seem to violate the article's principle about keeping Godot in a functional state. Happy to conform to Godot's PR workflow here, I just thought what I did was sensible.

Would squashing the code and documentation commits together invalidate the approval? I'd like to avoid spending more code approver time on a history change if possible. If that's allowed without approval invalidation, I can try my hand at rewriting history...

@voidshine
Copy link
Contributor Author

Also, thanks again for the tip about email -- I am not too concerned about credit here, but will go ahead and validate the email with GitHub so it will link things up.

@akien-mga
Copy link
Member

Ah I see. Well the code change and the documentation are related, so it's better to have them in a single commit. The documentation change is only valid because of the code change so they can be kept together as a unit.

@voidshine voidshine force-pushed the fix_midi_event_mutation branch from 60b63bd to f0f72b3 Compare October 11, 2022 19:39
Update documentation with note about MIDI velocity interpretation
@voidshine
Copy link
Contributor Author

Makes sense, I just did the squash, thanks for the guidance here!

@akien-mga akien-mga merged commit 3852b50 into godotengine:master Oct 12, 2022
@akien-mga
Copy link
Member

akien-mga commented Oct 12, 2022

Thanks! And congrats for your first merged Godot contribution 🎉

@voidshine
Copy link
Contributor Author

Thanks! 🎉 Hoping to make some more in years to come. 💟 Godot!

@akien-mga
Copy link
Member

Cherry-picked for 3.6.

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

Successfully merging this pull request may close these issues.

4 participants