Re: Timing limitations when programming MIDI with Javascript

Was just about to hit send on a reply to James when Jussi's mail came in.
 +1 to what he said.

The only thing I'd add is the the current spec treats DOMHighResTimeStamp
as if it has an innate zero-reference point (a la "milliseconds since UNIX
epoch"), which it does not - unless we explicitly refer to
window.performance.now().

Also, in noting that the params are readonly, I'm starting to wonder if it
would be best to stay with this API but additionally have a "send short
message immediately" that doesn't use the MIDIMessage structure - it seems
like overkill to create a UInt8Array, call createMIDIMessage, etc.  when
what I really want to do is

out.sendShortMessage( out.NOTEON, channel, notenumber, velocity );

Definition would look something like

boolean  createMIDIMessage (short status, short channel, short? data1,
short? data2);

Additionally, I'm not sure why all the parameters in MIDIMessage are
readonly?

On Mon, Jun 4, 2012 at 10:56 AM, Jussi Kalliokoski <
jussi.kalliokoski@gmail.com> wrote:

> Hello James!
>
> This could be realized by having either
>> 1) two different functions in the API:
>> creatMidiMessage(...) and createTimeStampedMIDIMessage().
>> rather than a single function with an optional argument as at present in
>> Midibridge's
>> midiAccess.createMIDIMessage(...)
>> or
>> 2) some way of declaring globally that the programmer wants to use
>> time-stamps of some sort.
>>
>
> The spec currently says that the timestamp is optional, being filled in as
> the current time. However, I don't see the value of having two types of
> MIDIMessages, with and without timestamps. The DOMHighResolutionTimeStamp
> is currently specified to be a double, and the cost of having a double in a
> struct is as much as having a pointer instead in 64bit system, which is not
> that much, even for a smartphone. The timestamp will be the least of the
> implementations' memory concerns, I'd believe. Garbage collection isn't
> necessarily a problem, since implementations will probably just use JS
> wrappers for the messages and the data will actually be stored in an
> underlying struct, and MIDI isn't exactly one of the highest traffic
> protocols anyway.
>
>
>> I've been investigating the limitations on timing in Javascript
>> applications:
>> 1. According to the W3C standard, the delay set in setTimeout() will
>> never be less than 4 milliseconds [2]. In practise, the lower limit can be
>> much larger [3].
>> 2. The time interval in setInterval() is measured in milliseconds, so
>> there are limits on the rates at which it can be used to send MIDI Clock
>> events. (MIDI defines the rate at which MIDI Clocks are sent in
>> *microseconds*. MIDI-Clocks are usually sent event every 20 milliseconds or
>> so.)
>>
>
> Yes, this is exactly why timestamps are quite essential in a MIDI API that
> will be in a JavaScript environment, they allow you to make the messages
> happen as accurately as possible, i.e. ahead of time, so that you don't
> have to rely on unreliable timing systems such as setTimeout().
>
>
>> 3. I suspect that multithreading comes in here somewhere...
>>
>
> Yes, multithreading is something we need to talk about, I just haven't
> formed my own opinion yet either. E.g. currently there's no great way to
> process MIDI messages in a worker, for example you can't create MIDI
> messages in a worker (no MIDIAccess), and I'm not sure making MIDIMessage a
> non-[[NoInterface]] (i.e. global) is a very good idea, the global scope is
> polluted enough as it is. What we could do, however, is that
> sendMIDIMessage() would accept JavaScript objects that have all the
> properties of a MIDIMessage.
>
> Cheers,
> Jussi
>
> P.S.
>
>> [1] https://github.com/abudaan/MIDIBridge/issues/1
>>
> Regarding this, I believe the reason Quicktime would react slowly to patch
> change commands is that as it's processing the soft-synth output as buffers
> (probably big ones to have minimal performance overhead), it might be just
> disregarding a patch change that occurs in the middle of the buffer and
> apply it before the next buffer.
>

Received on Monday, 4 June 2012 18:14:44 UTC