WebAudio / web-midi-api

The Web MIDI API, developed by the W3C Audio WG
http://webaudio.github.io/web-midi-api/
Other
321 stars 55 forks source link

On performance.now and relative deltatime #73

Closed nfroidure closed 11 years ago

nfroidure commented 11 years ago

The 'performance.now()' approach annoy me on two aspects :

On a MIDI stream, each event timing is expressed as delta-times relatively to the previous event.

Why not just use relative deltatimes ? My opinion is we should use the MIDI Channel Events format since it would both allow us to send single events or events chain with the help of a Uint8Array or an ArrayBuffer or an array for old browsers. It would also allow us to send midi events of tracks in midi files as is. See the "MIDI Channel Events" section of the following link for more information : http://www.sonicspot.com/guide/midifiles.html

There is just one thing to keep in mind if you decide to take a look at this approach. DeltaTimes aren't timestamp or milliseconds values. They are ticks (per beats or per frames). More informations on the above link in the "Time Division" section.

So, we will need a midiOutput.setTimeDivision() method or something like that to fix the delta times meaning.

jussi-kalliokoski commented 11 years ago

I actually originally though of using delta times, that would be the simple way; but, since in JS timers are hardly ever stable, it would be very complicated (not impossible!) to get accurate playback results with deltas. You'd have to calculate how much the timer is off this time and based on that recalculate the deltas and hope that works. I don't see any value in adopting deltas instead of performance.now().

it depends on performance.now witch is not implemented on each browser

Neither is Web MIDI API and you can betcha browser vendors will implement performance.now() before they will the Web MIDI API.

nfroidure commented 11 years ago

I'm not a C++ hardcore developper but i think that the browser implementation will be based on a separate thread so delta times should be a good approach for native API.

In fact, i think that the polyfill could also take advantage of the "MIDI Channel Events" in an ArrayBuffer approach since ArrayBuffers are "transferable" objects (https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers#Passing_data_by_transferring_ownership_(transferable_objects)).

So the polyfill could create a WebWorker, message him the ArrayBuffer and the Worker would message it back to the main thread with the event data to be played immediately. I do not know if the Jazz plugin is available in WebWorker, but if so, it could be played int he WebWorker directly.

jussi-kalliokoski commented 11 years ago

it depends on performance.now witch is not implemented on each browser

Also, it's already in IE10, Firefox and Chrome; Which browser are you referring to?

In fact, i think that the polyfill could also take advantage of the "MIDI Channel Events" in an ArrayBuffer approach since ArrayBuffers are "transferable" objects

What would that help? It would just add the roundtrip of transferring data to a worker and back.

jussi-kalliokoski commented 11 years ago

I'm not a C++ hardcore developper but i think that the browser implementation will be based on a separate thread so delta times should be a good approach for native API.

Why would that be so?

nfroidure commented 11 years ago

Also, it's already in IE10, Firefox and Chrome; Which browser are you referring to?

Older browsers. The Jazz plug-in runs on a lot of old browser that do not provide performance.now so it would impeach to polyfill the WebMidiAPI while another spec could enable it.

What would that help? It would just add the roundtrip of transferring data to a worker and back.

I assumed that using a worker to check the elapsed time and decide to send an event would free the main thread of that treatments. But, it will still depend on the main thread message queue, so you're probably right, that would not help that much.

Why would that be so?

The above conclusion also apply, it will probably not be based on a thread.

jussi-kalliokoski commented 11 years ago

The Jazz plug-in runs on a lot of old browser

Writing a polyfill for performance.now() is much easier than for Web MIDI API anyway. ;)

The above conclusion also apply, it will probably not be based on a thread.

Actually you're correct that a native implementation is most likely off-main-thread but that doesn't really change anything.

marcoscaceres commented 11 years ago

On Saturday, 6 July 2013 at 10:40, Jussi Kalliokoski wrote:

The Jazz plug-in runs on a lot of old browser

Writing a polyfill for performance.now() is much easier than for Web MIDI API anyway. ;)

This is true. I wrote one specifically for Web MIDI.

https://github.com/marcoscaceres/adlib.js (see lib/polyfills/performance.now.js)