Re: Round Trip Latency test

Oh brilliant! Thanks for exploring this.

And for info about constraints - I did not know about that. I just deployed
that to the latency tester (and to the sound.io app), and sure enough my
MacBook latency is down from 44ms to 18ms. That's much more workable for
live use.

Cheers!
Stephen



On 3 September 2014 13:29, Björn Melinder <bjorn.melinder@gmail.com> wrote:

> 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 13:02:19 UTC