PipeWire is a multimedia server, best known for it’s video support in Wayland. It also provides an audio server which can replace PulseAudio. The appeal, for me at least, to switch over from PulseAudio to PipeWire stems from PipeWire’s better support of bluetooth audio, and especially support for modern A2DP codecs such as AptX, AptX HD and LDAC.
Starting with PipeWire 0.3.20 introduced native mSBC support. This profile support mSBC codec versus CSVD supported by the older HSP/HFP profiles. The difference is significant, as the CSVD only supported narrow band speech (NBS, 8kHz) compared with mSBC support for wide band speech (WBS, 16kHz). That is the difference between 90’s era call quality sound and modern call quality sound.
Update: PipeWire-0.3.30 made the replacement process simpler. See my updated post.
Installing PipeWire 0.3.23
As of writing this post, Debian Unstable only has PipeWire 0.3.19. We are going to install PipeWire from the experimental repo so we get the PipeWire 0.3.23 with the support for mSBC.
We start by enabling the experimental repo
$ sudo apt-add-repository "deb http://deb.debian.org/debian experimental main
$ sudo apt update
Install PipeWire from experimental:
$ sudo apt install -t experimental pipewire-audio-client-libraries libspa-0.2-bluetooth
(pipewire-audio-client-libraries
will pull pipewire
itself as a dependency)
Substituting PipeWire for PulseAudio
These instructions are based on the ones from Debian Wiki, Arch Wiki and Gentoo Wiki. Create the file
$ sudo touch /etc/pipewire/media-session.d/with-pulseaudio
It will instruct PipeWire to handle Bluetooth audio devices.
Copy the pipewire-pulse
systemd service:
$ sudo cp /usr/share/doc/pipewire/examples/systemd/user/pipewire-pulse.{service,socket} /etc/systemd/user
Disable PulseAudio services and enable the PipeWire ones
$ systemctl --user disable pulseaudio.socket pulseaudio.service
$ systemctl --user stop pulseaudio.socket pulseaudio.service
$ systemctl --user enable pipewire pipewire-pulse
$ systemctl --user start pipewire pipewire-pulse
If everything worked well pactl info
should report Server Name: PulseAudio (on PipeWire 0.3.23)
:
$ pactl info | grep "Server Name"
Server Name: PulseAudio (on PipeWire 0.3.23)
If not, you might need to restart (PulseAudio tends to be rather persistent). In case PulseAudio still doesn’t play nicely, you should mask it:
$ systemctl --user mask pulseaudio.service pulseaudio.socket
$ systemctl --user stop pulseaudio.service pulseaudio.socket
Removing PulseAudio completely is not a good move at this point in time. Some packages depend on it, although they could work with PipeWire just as well. For example, when I remvoed PipeWire libcanberra-pulse
got removed as well which caused system notification sounds to break. Alternatively you could try to replace the PulseAudio package with a dummy using equivs
but that seems like more effort than keeping the package.
Enabling mSBC and SBC XQ
Edit /etc/pipewire/media-session.d/bluez-monitor.conf
and uncomment the following lines:
bluez5.msbc-support = true
bluez5.sbc-xq-support = true
This will enable both mSBC and SBC XQ.
You can test that you’re headset is connected via mSBC using pw-cli info
:
$ guyru@gdebian3:~$ pw-cli info all | grep bluez
info: unsupported type PipeWire:Interface:Profiler
info: unsupported type PipeWire:Interface:Metadata
info: unsupported type PipeWire:Interface:Metadata
* device.api = "bluez5"
* device.name = "bluez_card.94_DB_56_AC_36_52"
* api.bluez5.path = "/org/bluez/hci0/dev_94_DB_56_AC_36_52"
* api.bluez5.address = "94:DB:56:AC:36:52"
* api.bluez5.device = ""
* api.bluez5.class = "0x240404"
* api.bluez5.transport = ""
* api.bluez5.profile = "headset-head-unit"
* api.bluez5.codec = "mSBC"
* api.bluez5.address = "94:DB:56:AC:36:52"
* node.name = "bluez_input.94_DB_56_AC_36_52.headset-head-unit"
* factory.name = "api.bluez5.sco.source"
* device.api = "bluez5"
* api.bluez5.transport = ""
* api.bluez5.profile = "headset-head-unit"
* api.bluez5.codec = "mSBC"
* api.bluez5.address = "94:DB:56:AC:36:52"
* node.name = "bluez_output.94_DB_56_AC_36_52.headset-head-unit"
* factory.name = "api.bluez5.sco.sink"
* device.api = "bluez5"
In case mSBC is not supported you’ll see api.bluez5.codec = "CSVD"
(and you’lll probably hear the difference).
Errors
Problem: Connecting to bluetooth headset fails, and the following error appears in journalctl
:
bluetoothd[41893]: src/service.c:btd_service_connect() a2dp-sink profile connect failed for 94:DB:56:AC:36:52: Protocol not available
Solution: You’re missing the libspa-0.2-bluetooth
package. Install it and restart PipeWire:
$ sudo apt install -t experimental libspa-0.2-bluetooth
$ systemctl --user restart pipewire pipewire-pulse
Problem: ALSA programs fail with the following error:
ALSA lib pcm_dmix.c:1075:(snd_pcm_dmix_open) unable to open slave
aplay: main:830: audio open error: Device or resource busy
Solution: You need to enable the ALSA backend for PipeWire:
$ sudo touch /etc/pipewire/media-session.d/with-alsa
$ systemctl --user restart pipewire pipewire-pulse
Thank You for this..All steps went fine but no devices were detected while restarting, i have to start the pipewire-media-session service(Thanks to Arch wiki) after that voila all works great with extra codecs !
systemctl –user enable –now pipewire-media-session.service
Hi, I am searching for a solution … on arch linux I installed pipewire, I have usb audio, bluetooth, jack… but When I use microsoft teams or skype for linux I cannot see a output device for audio…
I tried to do something like this:
pw-loopback -m ‘[ FL FR]’ –playback-props=’media.class=Audio/Source node.name=my-source’pactl load-module module-remap-sink sink_name=my-sink
And after restart Skype and teams now show me a output, but I cant hear anything (from any program using the new sink) so I am looking for info about how to create a sink or something I can redirect to my headphones via pipewire
do you know where I can start looking ? I am reading pipewire documentation but I don’t understand a lot 🙁
I had issues with the pulseaudio compatibility layer not working. It turns out they moved the configuration files from /etc/pipewire to /usr/share/pipewire so you need to run
sudo touch /usr/share/pipewire/media-session.d/with-pulseaudio
instead of the command in this guide.There is a new package
pipewire-pulse
that already creates thewith-pulseaudio
file and also creates the necessary systemd services.Just as audio on Linux was mostly stable, some idiot invented PipeWire to break everything again. People should boycott it. Any improvements should have better been applied to PulseAudio.
I actually find PipeWire to work better than PulseAudio, especially with regard to Bluetooth audio.