- From: Björn Melinder <bjorn.melinder@gmail.com>
- Date: Wed, 3 Sep 2014 13:29:18 +0200
- To: Stephen Band <stephband@cruncher.ch>
- Cc: Norbert Schnell <Norbert.Schnell@ircam.fr>, Chris Wilson <cwilso@google.com>, Alex Russell <slightlyoff@google.com>, public-audio@w3.org
- Message-ID: <CAGpT7-kWY32HHEhYnWxddSr-PD=fVuoAF11+CGFaLt3SkQEBcQ@mail.gmail.com>
I made an empirical test to measure the latency impact of a ScriptProcessorNode with 16384 frames: http://jsfiddle.net/5md6natw/5/ The test starts with a direct path from getUserMedia to audioContext.destination. Pressing the flip button changes the rendering path to use a ScriptProcessor in-between. Same context, so the web audio to hardware i/o latency stays the same. To run the test, I placed headphones next to my MacBook mic, tapped the mic and recorded the echo-like noise using my phone. Measured the recorded echo delay in Audacity, the echo delay was exactly 16384 * 2 samples shorter in the direct path compared to the script processor path, which corresponds to the double buffering. So I believe Stephens assumption is correct, and the nice latency meter shows correct values. Furthermore, a Chrome developer helped me to disable echo cancellation which reduced the Mac latency to 20ms :) So maybe the meter could utilize that to show better numbers? E.g. var constraints = { audio: { optional: [{ echoCancellation: false }] } }; Cheers, Björn On Tue, Sep 2, 2014 at 11:43 PM, Stephen Band <stephband@cruncher.ch> wrote: > Ah yes, you're right. I was assuming that the output buffer starts to play > at the same time as the input buffer gets filled with new data onaudioprocess. > But you're right, perhaps that's a totally erroneous assumption. > > I suppose another way to do it would be to record a bunch of echos after a > single impulse and measure the time between them. You could do that with a > single script processor. > > > > On 2 September 2014 23:29, Norbert Schnell <Norbert.Schnell@ircam.fr> > wrote: > >> Hi Stephen, >> >> These two lines seem to assume that the latency through >> the ScriptProcessorNode is twice its buffer size: >> - 89: outputTimes.push(bufferLength * frame + bufferLength); >> - 104: inputTimes.push(bufferLength * frame + n - bufferLength); >> >> Is that really always the case? >> >> The only idea I had so far to reliably measure the latency through the >> ScriptProcessorNode was to send a sort of time code (e.g. a ramp counting >> the samples of a second generated via an AudioBufferSourceNode) through a >> ScriptProcessorNode (that just copies the input into the output) and to >> compare (e.g. subtract) the signal coming out of the node with the signal >> going into the node. >> I guess, one would need an additional ScriptProcessorNode to look at the >> result… >> >> (BTW: The time code can also be used to see if frames get lost on the way >> into the audio process code.) >> >> Norbert >> >> On 02 Sep 2014, at 22:59, Stephen Band <stephband@cruncher.ch> wrote: >> >> Hey Stephen, >>> >> >> >> do you have an un-minimized version of your code? >> >> >> >> Did you see this? The meat and potatoes of the code is in this gist: >> >> https <https://gist.github.com/stephband/f032a69c54f3a5d0ebf9>:// >> <https://gist.github.com/stephband/f032a69c54f3a5d0ebf9>gist.github.com >> <https://gist.github.com/stephband/f032a69c54f3a5d0ebf9> >> /stephband/f032a69c54f3a5d0ebf9 >> <https://gist.github.com/stephband/f032a69c54f3a5d0ebf9> >> >> Bjorn Melinder also had a look at it. I didn't get chance to look at what >> he said in his latest two posts, yet. >> >> >> If you're hopping process boundaries, and you usually are, you'll need to >>> double-buffer. That's 6ms. The input has the same buffering - so you're >>> up to 12ms. And that's an idealized path...) This is why even pro audio >>> hardware frequently has a "direct pass-through"... :) >> >> For sound.io I'm working on a looper that compensates for latency, so >> that you can use the direct channel of a pro audio interface and process >> loops through sound.io, yet still expect the loops to stay in time with >> you. >> >> I just tested my Metric Halo and I'm getting 38ms at 48000. That's not as >> good as I thought it was, there may well be some mistakes in the >> assumptions I've made in the code. >> >> Stephen. >> >> >> On 2 Sep 2014 22:29, "Chris Wilson" <cwilso@google.com> wrote: >> >>> Hey Stephen, >>> do you have an un-minimized version of your code? I can't understand >>> how you're accounting for the inherent ScriptProcessor latency. I also >>> didn't see a clear 2x drop when I doubled my sample rate, which I wanted to >>> investigate. >>> >>> The design of the Web Audio API was intended to provide low-latency in >>> audio; realistically, <10ms is hard to do without an optimized audio path >>> *and* a high sample rate. (A single 128-sample block at 44.1kHz is just >>> under 3ms. If you're hopping process boundaries, and you usually are, >>> you'll need to double-buffer. That's 6ms. The input has the same >>> buffering - so you're up to 12ms. And that's an idealized path...) This >>> is why even pro audio hardware frequently has a "direct pass-through"... :) >>> >>> >>> >>> >>> On Sat, Aug 30, 2014 at 2:21 PM, Alex Russell <slightlyoff@google.com> >>> wrote: >>> >>>> On Sat, Aug 30, 2014 at 12:46 PM, Stephen Band <stephband@cruncher.ch> >>>> wrote: >>>> >>>>> It's nothing to do with the UI really. >>>>> >>>> >>>> I understand that this wasn't in any way a test of UI, but in terms of >>>> the goal of reducing latency, I'd have assumed that being able to match UI >>>> closely (in response to input, e.g.) would be a goal and impls are some >>>> distance of that (although we also have bad delay in touch inputs for >>>> various reasons that are boring). >>>> >>>>> You're doing well if you get less than 40ms out of a standard sound >>>>> card, but if you use a good external audio interface you could see as low >>>>> as 5ms. >>>>> >>>>> Above 15-20ms is when the ear starts to hear two distinct sounds, >>>>> although it can be uncomfortable to sing and monitor with a latency of >>>>> >10ms. >>>>> >>>> Thanks for the context. >>>> >>>>> So I would say a good latency would be <10ms. But good luck getting >>>>> there :) >>>>> >>>> Looks like we're gonna need it = ) >>>> >>>> >>>>> On 30 Aug 2014 21:21, "Alex Russell" <slightlyoff@google.com> wrote: >>>>> >>>>>> What's a "good" number for this? I'm assuming less than a UI frame >>>>>> (16ms) is preferred? I'm seeing ~50ms on Chrome Dev/OS X/MBP and FF doesn't >>>>>> seem to detect all of the signals in my view. >>>>>> >>>>>> >>>>>> On Sat, Aug 30, 2014 at 11:24 AM, Stephen Band <stephband@cruncher.ch >>>>>> > wrote: >>>>>> >>>>>>> In case someone should find it useful, here's a round-trip latency >>>>>>> tester: >>>>>>> >>>>>>> https://sound.io/latency/ >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>> >>> >> > > > -- > > Cheers, > Stephen > > > <http://cruncher.ch> > *web*: cruncher.ch > *twitter*: @cruncher <http://twitter.com/cruncher> > *phone*: +41 76 547 30 32 > *email*: stephband@cruncher.ch >
Received on Wednesday, 3 September 2014 11:29:45 UTC