Setting per-app sound "spacial location" with surround sound

Is it possible to configure the “spacial location” of the sound output of a specific app?

Use-case Example:
In a multi-screen setup with 5.1 surround sound: define that the audio of the app used for video conferencing comes from “front left”, according to the screen where the conferencing app is on.
While having system sounds come from the center speaker only. And some background music playing from the back speakers.

I’m running default Fedora 38 on gnome.

Do you already have working 5.1 setup with PipeWire?

I’m not sure if placing sound sources in 3D space is supported yet. According to pipewire#3035, a panner module is not yet implemented.

But, it should be possible to just route apps to specific channels. Try using qpwgraph to play with the routing.

I have 5.1 setup in a sense that all the speakers show up in the Gnome Sound Settings panel and I can hear the test sound from all the individual speakers.

Thanks for the pointer to qpwgraph, it pretty much does exactly what I want… and with a nice GUI at that… I was mentally prepared to dig into some obscure configuration files :sweat_smile: .

What I’ve not figured out yet is how to make the configuration stick. Every time Chrome stops outputting audio it disappears in qpwgraph. And when it re-appears it is back to the defaults.

I’ve not tried it yet, but I found suggestions for the persistence problem here: Reddit - Dive into anything

I don’t use Chrome or 5.1, so I’m not 100% sure of the details.

The “easiest” way I can think of is to create a virtual sink that maps to the channel you want, set Chrome to the virtual sink, and wireplumber should remember the link automatically.

Before getting into the config, we can test the idea via cli first.

This command will create a virtual mono sink named remap_fl, that maps to the FL channel of your sink. Replace YOUR_SINK with the name of your sink (use pactl get-default-sink or pactl list short sinks).

pw-loopback --name='remap_fl' --capture-props='media.class=Audio/Sink audio.position=[MONO]' --playback-props='audio.position=[FL] node.target=YOUR_SINK stream.dont-remix=true node.passive=true'

While this command is running, make Chrome have an audio stream (I suggest playing any “stereo test” video on YouTube), then use pavucontrol to set the sink of Chrome to remap_fl (on the Playback tab).

Make sure both left and right channels of the stereo test or whatever audio can be heard (through the FL channel of your 5.1). Then restart Chrome and check that it sticks to this remap_fl sink.

If everything works, quit the running pw-loopback (press Ctrl-C), and rewrite the command into a config. See here for the config of the loopback module and here for config location.

Note with this setup, Chrome is effectively set to mono output. There might be some difference in volume from before.

Sorry for the long silence.
I did try this out once (running the pw-loopback command) and it worked like a charm, thanks!

I’ve not gotten around to persist the config yet. I’ll post the config and more details here once I’ve done that, in case it might be useful to anyone else trying to achieve this.

1 Like