W3C home > Mailing lists > Public > public-audio@w3.org > October to December 2012

Re: [MIDI]: collapsing MIDIMessage into MIDIEvent

From: Chris Wilson <cwilso@google.com>
Date: Thu, 29 Nov 2012 10:43:15 -0800
Message-ID: <CAJK2wqV+fY4VKcjrAwWnCC=vdFQ9H6OyWpw5UW2a_q1DaznjSA@mail.gmail.com>
To: James Ingram <j.ingram@netcologne.de>
Cc: "public-audio@w3.org" <public-audio@w3.org>, Jussi Kalliokoski <jussi.kalliokoski@gmail.com>
James,

I think you missed it, but we explicitly moved away from having two
different send methods, and using MIDIMessage in send, specifically so that
we wouldn't need to have a constructor for MIDIMessage, and so that we
wouldn't have two different forms of what is essentially the same function.
 Using one form, with a sequence parameter and a timestamp, enables us to
have timestamping on short and long messages, variable-length messages, and
only one send method.

Note that you DON'T really have to think about UInt8Arrays, on purpose -
when you call send, it takes a sequence, so it can be anything that
functions like an array, which means you can call:

send( [ 0x90, 0x45, 0x27 ] );

(the [] creates an Array in JS.)

On the other end, when you receive a MIDI message (regardless of the
MIDIMessage change), although the parameter is a UInt8Array, you can again
just treat it like an array of numbers, you don't have to think about it
being UInt8Arrays

EXAMPLE USING PROPOSED REMOVAL OF MIDIMESSAGE:
onmessage( event ) {
  if (event.data.length < 4) {  // "short" MIDI message
    switch ( event.data[0] & 0xf0 ) {
      case 0x90: // Note on!
        notenumber = event.data[1];
        velocity = event.data[2];
      ... // etc, etc
    }
  } else {
    // sysex!
  }
}

SAME EXAMPLE, USING CURRENT MIDIMESSAGE:
onmessage( event ) {
  for (var i=0; i<event.messages.length; i++ ) {
    if (event.messages[i].data.length < 4) {  // "short" MIDI message
      switch ( event.messages[i].data[0] & 0xf0 ) {
        case 0x90: // Note on!
          notenumber = event.messages[i].data[1];
          velocity = event.messages[i].data[2];
        ... // etc, etc
      }
    } else {
      // sysex!
    }
  }
}

The main reason for using UInt8Array is it will be more efficient when
using sysex, particularly when doing file storage.  But the average user
shouldn't have to think about it.

I know the API is relatively small already.  But the fewer objects there
are, the fewer object lifetimes there are to manage, as well as the less
developers have to understand in order to be productive.  If there's
significant value, then I'm okay with additional API; I don't see much
significant value right now, and (see above) the code needed for a simple
note handler becomes more complex.


On Thu, Nov 29, 2012 at 3:24 AM, James Ingram <j.ingram@netcologne.de>wrote:

> Sitting on the user side, I'd like to keep MIDIMessage objects in the API
> (separate from MIDIEvent).
>
> 1. The API is actually very small. Increasing its size by including a
> separate MIDIMessage does not make the API significantly more difficult to
> understand.
>
> 2. I want to have a MIDIMessage constructor for creating messages, and I'd
> prefer that to be handled by the API. I don't want to have to think about
> UInt8Arrays. If MIDIMessages exist (for that reason), it makes sense to
> expect to find them in MIDIEvents too.
>
> Question: Does a MIDIMessage constructor need to be put in the spec?
>
> Possible suggestion (ignore at your pleasure): It would be convenient if
> MIDIOutput could also send a MidiEvent. I seem to remember that the 'send'
> function used to be called 'sendMIDIMessage'. Maybe that change should be
> reverted, and MIDIOutput could also be given a 'sendMidiEvent' function.
>
> best,
> James
>
>
>
Received on Thursday, 29 November 2012 18:43:46 UTC

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