Re: Concerning the gap-less output of real-time generated audio in JavaScript

Philip: I completely agree. If there is too much jitter in between the
callback times, or if it's too spread out, then we get issues.  I personally
like moz audio's push model better because you don't have to even create a
callback for it, though in the end it doesn't matter. I've seen some
instances where the APIs can wait to buffer up to a few hundred thousand
samples before refilling, and it can basically destroy buffer position
listening as a result. For instance, if you want no more latency than that
of 20,000 samples, but the API only buffers to that of 100,000 at a time,
you can get issues if you're using the buffer position in your calculations
for audio (Audio underrun protection if your audio generating code is
running slow (example: setInterval is running too slow).). I run into the
last problem described here within some of my stuff on Linux with moz audio
and web audio (Basically if the API only wants to output like 100k samples
at a time, it's gonna be trash to use.).

> On Tue, Jul 12, 2011 at 1:25 AM, Philip Jägenstedt <philipj@opera.com <philipj@opera.com?Subject=Re%3A%20Concerning%20the%20gap-less%20output%20of%20real-time%20generated%20audio%20in%20JavaScript&In-Reply-To=%253CCAHzqrxoHYYozA50njiHP4D4SVxmXTDckvvOGHKm4Uw151rwbiw%40mail.gmail.com%253E&References=%253CCAHzqrxoHYYozA50njiHP4D4SVxmXTDckvvOGHKm4Uw151rwbiw%40mail.gmail.com%253E>>wrote:
>
> >
> > The callback method is basically a pull model. AFAICT, the only way to
> > achieve low latency is by having the callback fire very late, increasing the
> > risk of missing the deadline.
> >
> > Mozilla's (old) API is a push model. AFAICT, the only way to achieve low
> > latency is by filling up very little data at a time, again increasing the
> > risk of gaps.
> >
> > Perhaps an overwriteable ring buffer model is more complicated, but it is
> > very flexible in allowing the application to pick the (necessary) trade-off
> > between latency and risk of gaps.
> >
> >
> And an overwritable ring buffer is the worst of both worlds; the only way to
> achieve low latency is to correctly guess when the callback is going to
> fire. :-)
>
> I'm kidding, of course. It doesn't really matter. All of the methods under
> discussion are more or less isomorphic. You can make a push system look like
> a pull system if you only ever push one or two buffers; you can make a pull
> system look like a push system by managing your own list or ring buffer and
> handing off little pieces of it in the callback.
>
> Let's be frank: the only way to achieve low audio latency is to service the
> audio at a high, predictable rate.  Whether you service that via pull or
> push is not particularly germane to a discussion of latency. In the past
> I've tended to favor the push model (whether via linked list or ring
> buffer), but in the end it doesn't matter. However you design the system,
> latency is pretty much just a function of service rate and jitter. A system
> that can fire its service routine every 10ms plus or minus 1ms is going to
> have at least 11ms of latency. If jitter goes up to 10ms, then you have at
> least 20ms of latency. You have to size your buffer to account for the
> maximum jitter because jitter by its nature unpredictable; you don't know
> whether or by how much you're going to miss the deadline until you've
> already missed it.
>
> Going to an overwritable ring buffer doesn't reduce the latency; it just
> gives the app more rope to hang itself. The important question shouldn't be
> "how do we increase the application's flexibility." It should be "how do we
> make it possible for implementations to run reliably at high speed with low
> jitter?"
> Ian
>
>
>
>
>
> > --
> > Philip Jägenstedt
> > Core Developer
> > Opera Software
> >
> >
>
>
> --
> Ian Ni-Lewis
> Game Developer Advocate
> Android Developer Relations
>
>

Received on Friday, 15 July 2011 03:05:29 UTC