Re: [Web MIDI API] send() timestamp

On Friday, December 14, 2012 at 9:12 PM, Chris Wilson wrote:

> I don't actually know of any systems that do this (future-scheduling of MIDI input), personally, but that's not the point of timestamps in my opinion.  
>  
> The point of the timestamps on input is based on the fact that the underlying system (device driver, e.g.) will get the MIDI input likely on a much higher precision time clock than it will be able to pass the message into a JavaScript callback (on the main thread, which may get blocked by layout, etc.). The higher precision of that timestamp allows, e.g. a higher-precision recording of the timing of input messages in a sequence; for example, if you're recording the MIDI messages from a live piano controller, you will want the subtleties of that timing recorded - you may have some lag when passing through to send(), but when playing back that recorded sequence later, your timestamps will be more precise.
Hang on… I'm seeing what you are saying, but this seems like a strange way to achieve the desired outcome… if the idea is to hook device A to device B through some communication port (in this case we are using send), then it's better to do this directly. At the moment, we have basically this:

input.addEventListener("message",function(e){output.send(e.data)})

When what we really want is:

input.connect(output);

So you can bypass the JS layer and get realtime communication.  
  
> Likewise, the timestamps on send need to be on a consistent time clock, to keep a rock-solid "sequence timing" going - that's why we use performance timing rather than time.now() - and using offsets would require finding the "current time" when send() is called frequently. You could make it an offset, rather than an absolute; however, that would require coders to call window.performance.now() more frequently.

As above.   
>  
>  
> To schedule the next note of a sequence with absolute times, presuming "note" is an object that contains the next note's data and timestamp as an absolute start time:  
>  
> out.send( note.data, sequence.startTime + note.timestamp );
>  
> if you had offsets instead:
>  
> out.send( note.data, note.timestamp - ( window.performance.now() - sequence.startTime );  
>  
> There are other ways to structure this, of course - and in those cases, you may not have this kind of offset. For example, Standard MIDI Files record offsets from the last note - but that's actually not as relevant as it seems, because "the last note" is not where you're likely scheduling THIS note. The main point is, it's going to be easier to not have to convert between a time offset from the current time all the time. The symmetry with receiving is also a very good thing, of course.  
>  
> Your example is a relevant counter-example - but keep in mind, it is quite rare that you would want to actually call send() on a large number of notes at once, because then you can't cancel them or control tempo.  
>  
> I've had it on my list to do a sequence-playing example for a while; hope to get to that in the next couple of weeks.
>  


Ok, looking forward to seeing more use cases/examples.  

--  
Marcos Caceres

Received on Friday, 14 December 2012 21:33:43 UTC