- From: James Ingram <j.ingram@netcologne.de>
- Date: Sat, 15 Sep 2012 14:12:47 +0200
- To: Chris Wilson <cwilso@google.com>
- CC: public-audio@w3.org, Jussi Kalliokoski <jussi.kalliokoski@gmail.com>, Joseph Berkovitz <joe@noteflight.com>
Hi Chris, Joe, all,
Am 14.09.2012 18:22, schrieb Chris Wilson:
> On Fri, Sep 14, 2012 at 2:07 AM, James Ingram <j.ingram@netcologne.de
> <mailto:j.ingram@netcologne.de>> wrote:
>
> The problem is that the sendMIDISequence() function is recursive.
> And it has to be that way because of the way setInterval() works.
>
> It really, really doesn't need to be recursive.
I don't think you can remove the recursion, and stay accurate at the
same time. See below.
> That's what's giving you scope trouble, I believe. This is also
> causing you to have to pervert how you use setInterval - if you're
> going to have to cancel the interval every tick, you should just use
> setTimeout.
You are right, of course, using setInterval was an artefact. I thought
it might help keep the stack size down if I could explicitly clear
something, but using setTimeout actually makes no difference (I just
tried it).
> Additionally, you are only sending one message per tick; that's not
> really the point. You should be sending any messages that are between
> this interval call and the next, to get them queued up;
> ... more like this: https://gist.github.com/3722988.
That's more or less what Joe suggested too.
But if you send all messages within the INTERVAL as fast as possible (in
the while{} loop) then you lose accuracy. As far as I can see, the delay
between messages inside the INTERVAL is being ignored, and everything
gets scheduled on a grid of INTERVAL milliseconds (plus or minus a few
nano-seconds). In your code that's every 200ms. That's also what I hear
in test 6 [1], where I have simply replaced my sendMIDISequence()
function by your code (remember, my recursive function was working with
an accuracy of 1 millisecond). [Actually, that's not quite true: I have
seen rare glitches in test 5 (maybe once in 3 minutes) in which 2-3
notes deviate by more than 1 millisecond. Obviously, setInterval
sometimes takes a rest...]
Interestingly, the scheduling in test 6 (your code) also decays over
time, and the individual note-clusters spread out a bit. Looking at the
log, there's also some drift in where setInterval is starting each
INTERVAL. That's obviously what you meant by
> and really, you need some lookahead past that, in case the timers are
> skewed a bit (aka the setInterval callback is late).
I'm not at all happy with an indeterminacy of around 200ms, and I know
that passing small delays to setInterval is something one shouldn't
expect to work. So there's no way I can get to anything like 1
millisecond accuracy by using setInterval or setTimeout non-recursively.
Hope that makes sense. If not, I'm all ears.
This being the case, I think it would be worth taking a closer look at
including Tracks and Sequences in the API. I've done that in a separate
posting. this one is long enough already.
all the very best,
James
[1] http://james-ingram.de/tests/JazzMIDIBridge/ji-known-sequence6.html
Received on Saturday, 15 September 2012 12:13:28 UTC