kaeru


"Stuff I'm working on ..."

Virtual Surround Sound Headphone setup on Linux with Pipewire

by kaeru published 2021/11/21 18:13:00 GMT+8, last modified 2021-11-30T12:18:10+08:00
Headphones and Audio Interface
Sony MDR-7506 Headphones and MoTU M4 Audio Interface

Proprietary virtual surround sound features for standard headphones are often not available for Linux as they're implemented in software and the manufacturers only make drivers and utilities for Windows only.

With Pipewire the new audio server and open source convolution reverb utilities, we can simulate this feature in Linux and the setup is now less convoluted.

Pipewire replaces pulseaudio, jack and alsa (the client side) servers and provides seamless unified integration between audio clients. I've been using it for several months now for a rather complicated setup and it just works with existing software and hardware, including Bluetooth audio devices.

Setting it up to replace pulseaudio and/or jack audio is straightforward, for Ubuntu/Debian users you can find the PPA and instructions here: https://pipewire-debian.github.io/pipewire-debian/. Once done, all your audio applications will work as they did before. Except now, if you've only been on pulseaudio, you now have access to large variety of "pro" audio software that uses jack audio backend. And the unified audio server means that all your audio applications now work seamlessly and with each other.

Carla Plugin Host
Carla Plugin Host Patchbay with seamless connectivity with Pipewire, between Pulseaudio apps such as Rhythmbox and Bitwig DAW with jack

Setting up Virtual Surround Headphone Sink with jconvolver

The full instructions are available on the Pipewire Wiki. For Ubuntu users you can just apt get jconvolver

First setup a virtual surround sound sink device. This way your applications will connect the right outputs automatically without you having to map it manually to the convolution engine device manually.

pw-cli create-node adapter '{ factory.name=support.null-audio-sink node.name=hrir-headphones media.class=Audio/Sink object.linger=1 audio.position=[FL,BL,SL,FC,FR,BR,SR,LFE] }'
Virtual Surround Sink
Carla Patchbay showing Virtual Surround Headphone sink

Jconvolver Config and HeSuVi HRTF audio for Dolby Atmos

Pipewire wiki link earlier already provided an example config you can use with different audio sources, here is mine for Dolby Atmos headphones. You will need to also download the appropriate hesuvi hrtf audio file. A large database with download links is available here including the atmos.wav file I used, but many more HRTF reference files that could be useful for other applications or research in future.

$ pw-jack jconvolver -s pipewire-0 /home/kaeru//virtual-surround/atmos.config 

Mentioned in the upstream wiki, but if you get Jack buffer size change, exiting error, then you need to set it. jconvolver is the only jack app I've seen this error with, the following command setting it to buffer size of 1024 will fix this.

pw-metadata -n settings 0 clock.min-quantum 1024

You can then use Carla or QJactl to link jconvolver output to appropriate audio out device

Screenshot from 2021-11-21 23-21-23.png
jconvolver to surround headphones sink in Carla Patchbay

At first your, application might map to your default stereo out device first instead of the virtual headphone sink, you can switch to it using pulseaudio settings app.

Pulseaudio Volume

Close and re-open your video player and it should now have 7 outputs mapped to jconvolver.

vlc to jconvolver in Carla

The Pipewire wiki link earlier shows how this can be set up as a service, so you always have a virtual surround headphone sink automatically. But in future, with unified audio now possible once pipewire is made default for Linux distributions, it will just be a matter of time before this feature is available as an easy to use standalone graphical application.

Native Pipewire Filter Alternative

I followed jconvolver example, because I'm more familiar with JACK applications, but there is a built-in 5.1 and 7.1 hesuvi filter with pipewire you can also try. Will get around to trying and writing up illustrated notes for that setup in future when I get around to it.