• Posts
  • RSS
  • ◂◂RSS
  • Contact

  • AudioWorklet Latency: Firefox vs Chrome

    May 6th, 2020
    audio, tech  [html]
    Reading the Firefox 76 Release Notes I noticed that it now supports AudioWorklet. I tested out my whistle-controlled bass synthesizer, and it felt much better than in Chrome, though still not as responsive as the native version. I decided to take some latency measurements.

    I connected the computer (2017 MacBook Pro running 10.14.6) to an external speaker and microphone, set the browser to run a simple AudioWorklet-based echo, and set my phone to record. I made a sharp tapping sound, and looked at the recording to see the delay from when the original sound is recorded to when the echo plays it back.

    I tested Chrome and Firefox. I would have liked to compare to Safari, since Apple has historically taken audio latency very seriously, but they haven't implemented the AudioWorklet spec yet. I also tested Reaper and PortAudio [1] for comparison.

    Here's what this [EDIT: initially, see update at the end where everything gets faster] looked like with Reaper, Firefox, and Chrome all set to echo:


    (mp3)

    I made twelve clicks in a row, and saw Reaper at 15ms, Firefox at 62ms, and Chrome at 124ms. I learned which echo was which by turning off each in turn.

    You would expect that latency would be completely consistent, because you can't change the length of the delay without getting ugly artifacts, but in Chrome it was not consistent. Earlier I made a much longer recording (mp3) and taking the two sections where you can clearly hear Chrome echos (mp3, mp3) I get 78ms, 78ms, 77ms, 94ms, 94ms, 93ms, 93ms, 93ms and then later 88ms, 88ms, 88ms, 88ms, 88ms, 93ms, 109ms, 109ms, 114ms, 114ms, 120ms, 147ms, 152ms, 152ms, 152ms, 152ms, 152ms, 152ms, 152ms, 152ms, 152ms, 163ms, 153ms, 153ms. Since one of the projects I'd like to do with browser audio requires completely consistent latency, I'm not sure it would work at all in Chrome.

    PortAudio compared very similarly to Firefox, about 3ms faster. I'm not sure what Reaper is doing to get much lower latency than PortAudio and Firefox? If I was going to look into this further my next step would be to log which system calls they're making and try to figure out what they're doing differently.

    Overall, I'm very impressed with Firefox's AudioWorklet implementation's performance, and I hope Firefox pushes Chrome to do better as well.

    (Disclosure: I work for Google, which makes Chrome. I don't work on the browser, though, and I'm speaking only for myself.)

    Update 2020-05-07: after I published this, Chrome folks told me that passing {latencyHint: 0} when starting the AudioContext would tell it to use a smaller buffer. I was surprised by this, because the spec says the default value for latencyHint is "interactive: Provide the lowest audio output latency possible without glitching." But it does help, across browsers.

    Then Björn on LW pointed me to the getUserMedia call and recommended setting echoCancellation: false. I looked at the other settings available there and additionally decided to turn off noiseSuppression and autoGainControl, and set latency to zero. (echo-demo-v4)

    With all of these together, latency was much better in both Chrome and Firefox. Here's a long recording (mp3) of Reaper vs Firefox vs Chrome. This time Reaper was consistently 11ms and Firefox 14, but Chrome was not consistent. I got latency as low as 19ms, but as high as 41ms. I took a longer recording with Chrome (mp3) where you can see the latency as low as 19ms (most of the recording, including, ex, 0:10) but as high as 30ms (ex: 1:37). I wonder whether Chrome might be trying to dynamically determine what level of latency it can manage without dropouts?

    I've updated my whistle-controlled bass synth to use these settings, and on my Mac it's now great in Firefox, and nearly as good in Chrome. Here it is in Firefox, though you'll either need headphones or speakers that can do a good job with bass:


    [1] I used paex_read_write_wire.c with FRAMES_PER_BUFFER set to 64 and suggestedLatency set to defaultLowInputLatency and defaultLowOutputLatency. I installed portaudio (brew install portaudio) and then ran gcc paex_read_write_wire.c -o paex_read_write_wire -lportaudio && ./paex_read_write_wire.

    Comment via: facebook, lesswrong, hacker news

    Recent posts on blogs I like:

    Collections: The Queen’s Latin or Who Were the Romans, Part V: Saving And Losing an Empire

    This is the fifth and final part (I, II, III, IV) of our series asking the question ‘Who were the Romans?’ How did they understand themselves as a people and the idea of ‘Roman’ as an identity? Was this a homogeneous, ethnically defined group, as some ver…

    via A Collection of Unmitigated Pedantry July 30, 2021

    Modernizing Rail 2021 Announcement

    We are happy to announce that on Sunday the 29th of August we will hold this year’s Modernizing Rail conference, on the heels of the success last year. Please register using this form. And please give details on what you’d like to see, and if you’re willi…

    via Pedestrian Observations July 29, 2021

    Songs about terrible relationships

    [Spoilers for several old musicals.] TV Tropes lists dozens of examples of the “I want” song (where the hero of a musical sings about their dream of escaping their small surroundings). After watching a bunch of musicals on maternity leave, I’m wondering h…

    via The whole sky July 17, 2021

    more     (via openring)


  • Posts
  • RSS
  • ◂◂RSS
  • Contact