Firefox and Audio Streaming

I use my desktop computer as an audio source for music listening. Listening to high quality (lossless) music over the browser, I’ve explored different browsers and how they deal with audio. This is on Ubuntu 18 Linux with Pulseaudio. I’ve set up the audio to avoid resampling as much as possible.

I tried about 10 different browsers on Ubuntu. Every one but Firefox resamples audio to some fixed rate, either 44.1 or 48 kbps. Firefox is the only one that passes audio through unmolested. Or, at least it used to. Primephonic is a classical music streaming service that passes audio uncompressed at whatever rate the albums were recorded (from 44.1 to 192 kHz).  I could listen to different albums and watch Pulseaudio change the sampling rate to match whatever rate each was recorded. At least until some time in Feb 2021, when Firefox’s behavior changed.

Here’s a summary of the changes:

Firefox now ignores the audio stream’s native rate and attempts to stream it at the highest rate the system will support. This means it will resample the audio rather than play it at its native rate.

If Pulseaudio’s avoid-resampling is set to true, then that rate will always be the highest rate the system supports. For example, with my Juli@ sound card it is 192 kHz. Otherwise (avoid-resampling set to false) that rate is the highest rate Pulseaudio is configured to use. That is either default-sample-rate or alternate-sample-rate, whichever is higher.

So in order to listen to music on Firefox without resampling, you must:

  • Set both of Pulseaudio’s rates to the native rate of the stream you are playing.
  • Set Pulseaudio avoid-resampling to false.

Essentially, you are forcing the system to play all audio at a single rate that exactly matches the audio you are playing.

And indeed, the irony is that in order to avoid resampling, you must set avoid-resampling to false!

Incidentally, why the irony? I can only speculate. Cubeb, the audio engine in Firefox, asks Pulseaudio what is its highest sampling rate. If Pulseaudio is avoiding resampling, then it reports its highest rate to be the highest rate the audio card supports. But if Pulseaudio is resampling, then it reports its highest rate as whatever rate it is resampling everything into. Seems logical. But it ironically leads the reverse of the intended behavior. The root of the problem is cubeb. It should pass audio to the system at its native rate, and let the system deal with it. Cubeb is being too smart by half, trying to deal with that itself.