W3C home > Mailing lists > Public > public-audio@w3.org > July to September 2012

[Bug 18764] MIDI messages don't all have a channel, and status should be part of data.

From: <bugzilla@jessica.w3.org>
Date: Sun, 09 Sep 2012 01:18:26 +0000
Message-Id: <E1TAWAM-00070E-N8@jessica.w3.org>
To: public-audio@w3.org

Srikumar Subramanian (Kumar) <srikumarks@gmail.com> changed:

           What    |Removed                     |Added
                 CC|                            |srikumarks@gmail.com

--- Comment #19 from Srikumar Subramanian (Kumar) <srikumarks@gmail.com> 2012-09-09 01:18:26 UTC ---
(In reply to comment #15)

I find the short form sendMessage API to be no simpler than the array version
since the burden of having to refer to the MIDI protocol spec to find out how
to construct the data bytes remains. I agree with Jussi that programmers will
therefore write sendNoteOn kind of wrappers to even the shorter sendMessage API
.. due to this remaining conceptual burden.

So, if the byte protocol is going to be exposed to API users without support
for constructing the bytes, then having a single array based sendMIDIMessage
(or simply send()) is strictly simpler. It may also help set expectations that
no message verification will be performed by the API. 

If easing a developer's conceptual burden in the API is important, then it will
be conceptually simpler to have multiple functions that hide the byte protocol
- like sendNoteOn(timestamp, channel, pitch, velocity), perhaps with velocity
in [0,1] range even. Covering the most common cases of noteOn, noteOff and
controller change and allNotesOff may be enough.

If developers are to write their own wrappers, performance isn't an issue (I
think). I found that a sendNoteOn wrapper on top of a shared Uint8Array based
implementation gave me more than 10 million overhead calls per second on my
macbook air (https://gist.github.com/3652045). That's 50x the capacity needed
to send 100Hz control messages to each of 128 controllers in each of 16
channels through individual function calls.

Regarding naming, the array in MIDIMessage can hold more than one message, but
the name suggests that it holds only one. Maybe adopt the CoreMIDI name
"MIDIPacket" instead? A shorter send() function name also seems more correct
for this reason.

> (In reply to comment #14)
> > Florian: I have to disagree.  This is a MIDI API.  MIDI is a software protocol.
> >  I don't think we should be explicitly trying to make this a generic serial
> > send/receive API.  All the wealth of devices I'm interested in out there-
> > synths and keyboard controllers, drum machines, mixers, guitar amp simulators,
> > DJ controllers, lighting systems, control pads like the Launchpad, and more
> > have all designed for MIDI.  I don't think we need to go out of our way - e.g.
> > validating every message - but we do need to design for the protocol, as timing
> > can be important to real-world devices.  And most importantly - this is the
> > point I really, really care about - we should be optimizing for the most
> > important and commonly-used scenarios in sending and receiving MIDI messages. 
> > Far and away the most common scenario is a three-byte "short" message - sysex
> > is useful and needed, but you end up doing a tremendous amount with just note
> > on/off and CC messages.
> > 
> > This also is my reasoning for wanting the "send a short message" call to be as
> > trivial as possible - send( status, data0, data1) - because it is incredibly
> > common.
> > 
> > Jussi - I disagree that "MIDI devices hardly ever transfer more than 100
> > messages in a second."  Or, more to the point - I can easily see wanting to be
> > able to have a higher-speed connection than that.  Not because I am a
> > high-speed-Rachmaninoff player, but because I want to be twisting knobs with
> > instantaneous response, and because I've seen first hand that those sexy
> > Ableton and Traktor controllers have multicolor button displays, and pushing
> > data back and forth to those could easily outstrip 100 messages/second.  I
> > could hit that from computer->Launchpad in my Conway demo easily, by hitting a
> > button twice in a second.
> Nevertheless, the bottleneck is never going to be in this part. Even
> smartphones should be able to send at least hundreds of thousands of MIDI
> messages this way. And really, if the underlying API makes it slower to send
> completely custom messages, it's pretty easy to see the length of the typed
> array in the MIDIMessage and if it's <= 3, you'll know it's a short message.
> sendMessage is just sugar, not really a meaningful optimization.
> > I understand 
> > 
> > port.sendMIDIMessage( { data: Uint8Array([0x80, 0x70, 0x60] ) })
> > 
> > is only a couple of object allocations/constructions and pushing 3 parameters
> > into an array (and pulling them back out) over
> > 
> > port.sendMessage(0x80, 0x70, 0x60)
> > 
> > However, as an author, it's cargo-cult boilerplate.  I think we should need to
> > make this ultra-common case simple.
> The API users will probably make boilerplate that fits them anyway, it's likely
> that there will be libraries that have separate functions for common cases,
> such as
> noteOn(key, velocity)
> noteOff(key, velocity)
> controlChange(cc, value)
> and they can internally use even a simple function like this for sending a
> message:
> function send (data, /* optional */ timestamp) {
>   port.sendMIDIMessage({
>     timestamp: timestamp,
>     data: new Uint8Array(data)
>   })
> }
> /* send the message ASAP */
> send([0x80, 0x70, 0x60])
> /* send the message one second later */
> send([0x80, 0x70, 0x60], performance.now() + 1000.0)
> In fact I intend to make a library like that myself. ^^

Configure bugmail: https://www.w3.org/Bugs/Public/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
Received on Sunday, 9 September 2012 01:18:28 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:50:02 UTC