Bug 18992 - Running status should be prohibited
Running status should be prohibited
Status: CLOSED FIXED
Product: AudioWG
Classification: Unclassified
Component: MIDI API
unspecified
PC All
: P2 normal
: TBD
Assigned To: Chris Wilson
public-audio
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-09-24 18:34 UTC by Chris Wilson
Modified: 2012-12-11 16:56 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Wilson 2012-09-24 18:34:45 UTC
Input from Yamaha:

● Prohibit to receive/send ‘Running Status’ (‘Running Status’: http://goo.gl/Cyjtz)
○ Running Status is not able to stream in the spec of USB-MIDI. So the Web MIDI API must care the
Running Status.
■ About sending MIDI Message from web browser: The iOS for example, the spec says that
to set Running Status to MIDIPacket is prohibited, so Web MIDI API also follow the spec and prohibit to set Running Status. And also, we do NOT know the device which accepts Running Status, so we think this spec is appropriate to the Web MIDI API.
■ About receiving MIDI Message from external MIDI input devices: The iOS for example, status byte is added when the Running Status from MIDI mesages found. We think this spec is also appropriate to the Web MIDI API.
Comment 1 Jussi Kalliokoski 2012-09-25 07:56:51 UTC
(In reply to comment #0)
> Input from Yamaha:
> 
> ● Prohibit to receive/send ‘Running Status’ (‘Running Status’:
> http://goo.gl/Cyjtz)
> ○ Running Status is not able to stream in the spec of USB-MIDI. So the Web MIDI
> API must care the
> Running Status.
> ■ About sending MIDI Message from web browser: The iOS for example, the spec
> says that
> to set Running Status to MIDIPacket is prohibited, so Web MIDI API also follow
> the spec and prohibit to set Running Status. And also, we do NOT know the
> device which accepts Running Status, so we think this spec is appropriate to
> the Web MIDI API.
> ■ About receiving MIDI Message from external MIDI input devices: The iOS for
> example, status byte is added when the Running Status from MIDI mesages found.
> We think this spec is also appropriate to the Web MIDI API.

Interesting, somehow I didn't even know of Running Status messages. I also find it odd that USB-MIDI doesn't support it, couldn't it just treat it as an arbitrary message? Weird.

Anyhow, I think the course of action should be to just fix running status messages, e.g. if the developer sends a running status message, the underlying implementation will add the status byte and same for receiving. I'm not sure it makes sense to explicitly prohibit Running Status messages, as if we can detect them we can also just add the missing byte. Does that encourage people to use running status? I doubt it, they'd have to keep track of the previous status to keep the stream functional to no apparent performance gain even. But "supporting" Running Status may well help someone porting old software to the web, this could be a hard to debug issue.

As a side note, I'm rather unhappy to learn something like that even exists. Sounds like a silly convenience addition that just makes things break. :(
Comment 2 Jussi Kalliokoski 2012-09-25 17:28:52 UTC
I should probably add a section detailing how sent/received messages should be handled.
Comment 3 Chris Wilson 2012-09-25 18:00:50 UTC
> Interesting, somehow I didn't even know of Running Status messages. I also find
> it odd that USB-MIDI doesn't support it, couldn't it just treat it as an
> arbitrary message? Weird.

From reading the USB-MIDI spec (http://www.usb.org/developers/devclass_docs/midi10.pdf) - it parses MIDI messages, rather than just treating it as a stream of uninterpreted data (see section "USB-MIDI Event Packets").  Running status would interfere with that - you would have to explicitly support running status in order to parse into messages.

> Anyhow, I think the course of action should be to just fix running status
> messages, e.g. if the developer sends a running status message, the underlying
> implementation will add the status byte and same for receiving. 

I think we should mention running status and simply say use of running status is not recommended, as many MIDI devices will not support them - but we don't explicitly try to error out on them or anything.  This isn't fundamentally any different than OS APIs today.

> I'm not sure it
> makes sense to explicitly prohibit Running Status messages, as if we can detect
> them we can also just add the missing byte. Does that encourage people to use
> running status? I doubt it, they'd have to keep track of the previous status to
> keep the stream functional to no apparent performance gain even. But
> "supporting" Running Status may well help someone porting old software to the
> web, this could be a hard to debug issue.

I don't think so.  My understanding of support of running status is that it's mostly used in file storage (i.e. Standard MIDI files).

> As a side note, I'm rather unhappy to learn something like that even exists.
> Sounds like a silly convenience addition that just makes things break. :(

Heh.  Just wait until you realize that Running Status is *THE* reason why a MIDI Note On message with a velocity of zero is explicitly the same as a MIDI Note Off.  That way, you can compress a dense passage of note on/note off messages by 33%.
Comment 4 Florian Bomers 2012-10-01 08:34:35 UTC
Running Status is not just a convention, it's part of the core MIDI specification. Every MIDI receiver should understand running status or it will risk misinterpreting the incoming data. This is particularly true for 5-pin DIN MIDI connections (which are not obsolete).

For example, my old drum computer sends 5 bytes for every pad: e.g. this string of MIDI hex bytes: "90 40 7F 40 00", turning a note on and immediately off -- consecutive notes on the same channel, it will also omit the first status byte. For fast and "dense" rhythm patterns, the byte savings will improve timing considerably.

All software API's that I know of will undo running status for the user. That's probably appropriate for the Web MIDI API, too. But "prohibit" sending running status seems quite arbitrary to me. If supported by the underlying OS support, running status can be passed on to the MIDI interface with its positive implications. Otherwise, the Web MIDI API implementation needs to undo running status to fulfill the underlying OS' requirements. That's not hard to do.

In a nutshell: only because some transports and some OS API's do not want to/need to handle running status, it does not mean that the Web MIDI API should prohibit it entirely. Discouraging its use is OK.
Comment 5 Jussi Kalliokoski 2012-10-03 08:21:21 UTC
(In reply to comment #4)
> Running Status is not just a convention, it's part of the core MIDI
> specification. Every MIDI receiver should understand running status or it will
> risk misinterpreting the incoming data. This is particularly true for 5-pin DIN
> MIDI connections (which are not obsolete).
> 
> For example, my old drum computer sends 5 bytes for every pad: e.g. this string
> of MIDI hex bytes: "90 40 7F 40 00", turning a note on and immediately off --
> consecutive notes on the same channel, it will also omit the first status byte.
> For fast and "dense" rhythm patterns, the byte savings will improve timing
> considerably.

I'm too young and spoiled with bandwidth to understand. ^^ Kidding aside, I can see the benefit of Running Status.

> All software API's that I know of will undo running status for the user. That's
> probably appropriate for the Web MIDI API, too. But "prohibit" sending running
> status seems quite arbitrary to me. If supported by the underlying OS support,
> running status can be passed on to the MIDI interface with its positive
> implications. Otherwise, the Web MIDI API implementation needs to undo running
> status to fulfill the underlying OS' requirements. That's not hard to do.
> 
> In a nutshell: only because some transports and some OS API's do not want
> to/need to handle running status, it does not mean that the Web MIDI API should
> prohibit it entirely. Discouraging its use is OK.

Agreed.

Something I'm wondering (maybe a bit off-topic) is that I have a few MIDI->USB-MIDI adapters, how do these deal with running status? I assume the adapter just adds the missing bytes?
Comment 6 Florian Bomers 2012-10-03 10:24:59 UTC
(In reply to comment #5)
> (...)
> Something I'm wondering (maybe a bit off-topic) is that I have a few
> MIDI->USB-MIDI adapters, how do these deal with running status? I assume the
> adapter just adds the missing bytes?

yes they do: undoing running status yields an equivalent MIDI message, so no information is removed or added.
Comment 7 Chris Wilson 2012-10-03 17:09:34 UTC
(In reply to comment #6)
> (In reply to comment #5)
> > (...)
> > Something I'm wondering (maybe a bit off-topic) is that I have a few
> > MIDI->USB-MIDI adapters, how do these deal with running status? I assume the
> > adapter just adds the missing bytes?
> 
> yes they do: undoing running status yields an equivalent MIDI message, so no
> information is removed or added.

If the underlying implementation is handling running status, then why does it matter?

Yamaha's request was that short MIDIMessages be complete messages - i.e., that they not require additional state to be maintained from message to message (aside from long messages that could be broken in multiple parts; they weren't happy about that, but were okay with it.)  That seems like a logical request; and with your current system, what does the Windows/Mac API give you for your drum computer?
Comment 8 Florian Bomers 2012-10-03 23:24:30 UTC
(In reply to comment #7)
> Yamaha's request was that short MIDIMessages be complete messages - i.e., that
> they not require additional state to be maintained from message to message
> (aside from long messages that could be broken in multiple parts; they weren't
> happy about that, but were okay with it.)  That seems like a logical request;
> and with your current system, what does the Windows/Mac API give you for your
> drum computer?

On reception (drum computer to host), the Windows and Mac API's undo running status, so I receive a series of complete MIDI messages. I only know that the drum computer is using running status from the old DOS days.

However, I have been able to send multiple messages at once WITH running status (on Windows, with midiOutLongMsg() ), and it works fine. I just assume that the bytes are sent "as is" on the MIDI transport. But it's hard to verify these days...
Comment 9 Chris Wilson 2012-11-16 00:10:24 UTC
I note that CoreMIDI explicitly disallows running status:  it says "data: A variable-length stream of MIDI messages. Running status is not allowed."  (from http://developer.apple.com/library/ios/documentation/CoreMidi/Reference/MIDIServices_Reference/Reference/reference.html#//apple_ref/doc/c_ref/MIDIPacket)

I believe we should follow this precedent.
Comment 10 Florian Bomers 2012-11-16 11:07:48 UTC
The fact that CoreMIDI disallows running status was already part of Yamahas original request to ban running status. 

I don't think that a limitation on ONE system is a good enough reason to limit a cross platform API. I think it's more important to create an API that is generally useful and makes sense, than to find the common denominator of functionality available in today's OS's.

We do the right thing with timestamped messages: although on some OS's, the webmidi implementation will need to create an own scheduler, there is still a way for sending timestamped MIDI messages.

So I think it's still the right thing to discourage running status but not to prohibit it. As previously said, Yamaha's concern that a receiver might not be able to understand running status is not reasonable. The disclaimer might even say that sending a message with running status might not work the same on all OS's. Then the CoreMIDI implementation does not need to take care of undoing running status, though it's really not that hard.
Comment 11 Chris Wilson 2012-11-16 19:02:32 UTC
(In reply to comment #10)
> The fact that CoreMIDI disallows running status was already part of Yamahas
> original request to ban running status. 

Yamaha had mentioned that iOS disallowed it (but I'd point out all iOS MIDI devices are going to be USB-MIDI devices, and USB-MIDI disallows running status anyway).  I'd run across this mention in desktop CoreMIDI documentation.

> I don't think that a limitation on ONE system is a good enough reason to
> limit a cross platform API. I think it's more important to create an API
> that is generally useful and makes sense, than to find the common
> denominator of functionality available in today's OS's.

I don't see this as a limitation.  I think the point I'm trying to make is that running status had a point - to compress data on an actual 31.25kB serial connection - and that should be handled well below this API, and I don't see a significant reason to impose having to watch out for running status and unroll it on reception (Florian, from previous comments I *think* you agree with this - that you should never get running status in the data bytes in a MIDI message in the Web MIDI API).

Likewise, I don't really see a strong enough reason to support it in sending either.  (It is not just CoreMIDI, BTW - any other system, like ChromeOS, where the only hardware connected would be USB-MIDI, would have to unroll this also.)  This is a tradeoff, though - Windows lets you send running status, but direct USB-MIDI doesn't, and CoreMIDI doesn't.  On those systems, the implementations of Web MIDI would have to parse the send() data into messages to look out for running status before sending the data deeper down.  If necessary, we can impose this on implementors, but:

1) If we're going to do that, we need to be explicit about requirement in the spec ("data in the send() call may make use of MIDI running status, and therefore implementations MUST support running status to the end device; either by sending the running status out onto a MIDI hardware protocol wire, or unrolling the running status (i.e. inserting additional status bytes as needed) in the case of devices that do not support them, such as USB-MIDI devices.")

2) I still want to understand a use case/scenario that needs this.  This doesn't mean we won't be compatible with old MIDI devices; the MIDI hardware interface will unroll this for you, on all current systems (it's required to).  The best I can come up with is you can read in a block in a standard MIDI file and drop it straight into the API - but I can only come up with one scenario (Media player) where I wouldn't need to be interpreting the message data myself at the same time (and therefore unrolling it at the app layer anyway).

> So I think it's still the right thing to discourage running status but not
> to prohibit it. As previously said, Yamaha's concern that a receiver might
> not be able to understand running status is not reasonable. The disclaimer
> might even say that sending a message with running status might not work the
> same on all OS's. Then the CoreMIDI implementation does not need to take
> care of undoing running status, though it's really not that hard.

We need to clearly state 

1) whether running status will ever show up in the data an app may receive from the Web MIDI API (I think we are agreed it's okay to say it does not?), and

2) whether an application can utilize running status in the send() data.  This MUST be clearly stated - as either a MUST or a MUST NOT be supported - as it does require parsing of the data in order to support on a sizable number of systems (OSX/iOS and any direct-to-USB-MIDI implementation).

"Discourage" doesn't really mean anything.  :) We either say implementations need to support it, or we say it's prohibited.  (Remember, this spec is for implementers as well as developers using the API.)
Comment 12 Florian Bomers 2012-11-17 13:51:54 UTC
Hi Chris,

I agree:
1) webmidi apps will never receive running status
2) it's a good idea to state whether running status is allowed in the send() method.

"Discouraging" implies that running status is allowed (and the webmidi implementation might need to parse the data for iOS, OSX and so on).

My main motivation for my reasoning is that I am not comfortable with API's that try to "hold the hand" of developers, by restricting the API with parameters or functionality that the *API* designers find useful. For me, ideally, a MIDI API allows you to send and receive arbitrary bytes. It will be the responsibility of the developer to send data that is meaningful to the receiver.

But obviously, the makers of most (or all) MIDI API's chose a different way, by disallowing certain messages or ways to use MIDI. I hoped the webmidi API could be a place to make things better. But since it will usually depend on an underlying OS API, sending running status would complicate matters with very little benefit. 

So I won't oppose disallowing sending running status anymore, but it's sad ;)

And I hate to bring this up, but have you thought about those undefined MIDI messages with status bytes F4, F5, F9, FD? Some OS's do not handle them, because it is not defined how many data bytes those messages have.
Comment 13 Chris Wilson 2012-11-19 18:01:12 UTC
Fixed by https://dvcs.w3.org/hg/audio/rev/e0f3c5871603.

I would expect the undefined MIDI status headers would be dropped, likely by the underlying system.
Comment 14 Olivier Thereaux 2012-12-11 09:44:45 UTC
Changeset looks good, seeing no objection. Closing. 


On a side note, I see in the changeset: "The data must contain a stream of valid, complete MIDI messages". Should it be a RFC2119 "MUST"?
Comment 15 Chris Wilson 2012-12-11 16:56:20 UTC
(In reply to comment #14)
> On a side note, I see in the changeset: "The data must contain a stream of
> valid, complete MIDI messages". Should it be a RFC2119 "MUST"?

Fixed.