MIDI On messages with velocity 0 being changed to Note Off

yeahtuna

Well-known member
I realize that MIDI On messages with velocity set to 0 are typically treated as Note Off messages, but they are technically different and I don't think all the teensy MIDI related libraries (MIDI. usbMIDI, usbHost) should be explicitly converting incoming Note On messages with velocity of 0 to Note Off behind the scenes.

It took me a long time to figure out why my teensy based MIDI interface was breaking the Mackie Control protocol. I wouldn't be surprised if breaks MPE as well.
 
It's actually part of the Midi Spec that Note On Vel 0 will always be considered as a Note Off event, and all Midi devices 'should' be able to cope with it, and treat it as such. It is to help with 'Running Status' (which isn't really relevant though for USB Midi).

For the Midi library you can use Custom Settings so that Note On Vel 0 is flagged as a Note On, and not a Note Off (which is default).


But yes, it is hard coded into the usbMidi & usbHost libraries that Note On Vel 0 will be flagged as a Note Off event, which (with lack of a custom setting) in my view is probably overall the better choice, but an option to turn this off wouldn't be bad idea (would be super easy to do).
 
The MIDI Spec infact does not say that "MIDI NoteOn messages with Vel 0 should be converted to a Note Off messages", but rather that "A Note On message with a velocity of 0 is considered to be a Note Off message." I think there's a fundemental difference here. I understand that for the average user, it's not going to make a difference. At lease it's now documented.

As an aside, Gemini seems to agree that MPU technically breaks the MIDI Spec in this regard.
 
Last edited:
A note off message is equivalent to a note-on with zero velocity - you should always treat them identically (in an ideal world). What I'm not clear about is if the velocity value in a note-off message has any meaning...
 
This is key release velocity, some keyboards report that and some synths (like Virus TI) can interpret that value to adjust for example release time or any other parameter via modulation matrix.
 
Which begs the question what key release velocity is a note-on zero-velocity packet equivalent to?
 
I agree that Key-on velocity 0 should be treated as if key-off with velocity 64 was received.

BTW, the Oberheim Xpander also uses key-off velocity (back in 1984).
 
Good point with the release velocity being 64!

So a Midi receiver like a synth (which is capable of recognising Note Off velocity) receives a Note On Vel 0 it is supposed to treat that as a Note Off Vel 64 (as per Midi Spec)

So I guess if the Midi libraries mentioned above are converting Note On Vel 0 to Note Off events, then should they also be setting the Note Off Velocity to 64 to make it compatible with devices which are sensitive to Note Off Velocity?

Currently they all set the Note Off velocity to 0 when converting from Note On to Off.
 
I'm watching this conversation and struggling to form an opinion of how serious this matter really is. Please remember I'm not a musician. I'm depending on your feedback.

I am much more interested in practical effects and compatibility with widely used devices and software than rigorous adherence to specs or academic arguments about correctness.
 
I realize that MIDI On messages with velocity set to 0 are typically treated as Note Off messages, but they are technically different and I don't think all the teensy MIDI related libraries (MIDI. usbMIDI, usbHost) should be explicitly converting incoming Note On messages with velocity of 0 to Note Off behind the scenes.
I agree. If I'm using a library, I typically do not want it to "lie" to me, especially where it's an external communication and real information is lost. The only exception would be something like a serial protocol which uses escape characters to frame packets.

It's actually part of the Midi Spec that Note On Vel 0 will always be considered as a Note Off event, and all Midi devices 'should' be able to cope with it, and treat it as such.
True, but this should (IMHO) be done at the application level, not inside the library. In this case the device doesn't have the opportunity to cope - it never even sees it.

it is hard coded into the usbMidi & usbHost libraries that Note On Vel 0 will be flagged as a Note Off event,
This is sort of true, but it's not "flagged as", it's "converted to", which loses the information that what was received was a zero-velocity note on.

which (with lack of a custom setting) in my view is probably overall the better choice, but an option to turn this off wouldn't be bad idea
I disagree, I'd call it the worse choice, unless the majority of Arduino libraries prior to usbMIDI and usbHost have done the same, and it's been implemented that way for consistency. In which case, it's still a bad choice, but justifiable, and ideally should be well-documented and have a method to turn it off.

I am much more interested in practical effects and compatibility with widely used devices and software than rigorous adherence to specs or academic arguments about correctness.
Well in this instance the practical effect is that @yeahtuna has "taken a long time to figure out" that the library is "was breaking the Mackie Control protocol". Mackie is definitely a reputable manufacturer (which of course doesn't necessarily mean they don't do weird stuff with MIDI, like insisting on a different interpretation for NoteOn@velocity0 and NoteOff@velocityN).

In your repos, we have:
Your MIDI repo is a fork of this library (albeit 33 commits out of date), and that's the one that comes out top of the list when I do a web search for "Arduino MIDI", so that's probably canonical behaviour for the Arduino-like ecosystems. It's even documented here.

The least worst thing to do would appear to be to add use of the midi::DefaultSettings structure to usbMIDI and usbHost, so that any existing customisation can ported to Teensy with the minimum of changes.
 
Isn't this required by the constructor? How would it work with usbMIDI where we create a static instance by default?
Yes. So it wouldn’t work, or at least would require some level of editing cores, which is not a useful approach.

So the second-least-worst-thing would be to add a method which can switch off the automatic conversion, and document it.
 
For now, I've just simply added this function to usb_midi.h
C:
    /* Handle Note On Velocity 0 events as Note off (default behaviour).
    convert - Sets whether Note On Velocity 0 is converted to a Note Off (default = true).
    off_velocity - Optionally sets the Release Velocity (0-127) of the converted Note Off (default = 0).
    */   
    void handleNullVelocityNoteOnAsNoteOff(bool convert, uint8_t off_velocity = 0){
        usb_midi_handle_null_vel_as_noteoff = convert;
        if (convert) usb_midi_converted_note_off_vel = off_velocity & 0x7F;
    }
Only needed a few minor changes to usb_midi.c
 
But the default value of off_velocity parameters is incorrect. Should be 64 as per MIDI spec.
 
Yeah I left it at zero for now, so it's compatible with existing code, and keeps it the same as the MIDI library.

I also tested my Midi keyboards from Novation, and Arturia which don't transmit release velocity, and they all send out Note Off's with a velocity value of Zero, so I guess using Note Off's with a velocity of zero instead of 64 is acceptable?? Unless Novation and Arturia have it wrong too.
 
I messed about a bit, and if the static instance of usbMIDI is weakly defined, then the user code can define its own (strong) instance which invokes a different constructor. So something more consistent with the MIDI class would be possible.
 
What I'm not clear about is if the velocity value in a note-off message has any meaning...
It does (it is how fast or slowly you release an already pressed key), and MPE uses release velocity as one of the five dimensions of control - strike (note on velocity), lift (note off velocity), slide (per-note pitch bend), glide (forward-back movement on each key) and press (per-note aftertouch, like polyphonic aftertouch but implemented differently). MPE is supported now in many hardware and software synths and most DAW (Digital Audio Workstation) software has some degree of MPE support.

Sadly the final version of MPE went with 7-bit values for strike and lift (earlier versions used 14-bit) but still, it can be and is used for expressive control and having 127/127 to 1/127 treated very differently to 0/127 could be inconvenient.

So for maximum compatibility, especially with older synths, aliasing Note On 0 to Note Off is a good default, but for MPE compatibility there should be the option in the library to treat them as distinct events. And it is increasingly important to report the Note-Off velocity, if the keyboard is physically capable of measuring it.

The small addition by @submo would be nice to have in the stock library.
 
Back
Top