- 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