PipeWire
PipeWire is a Article description::low-latency and graph-based processing engine and a server for interfacing with audio and video devices that can be used to support use cases currently handled by ALSA, PulseAudio, and/or JACK. Interested users should understand that as of early 2021 PipeWire is still in active development and not everything is fully integrated, tested, or implemented.
Replacing existing audio solutions on Gentoo is possible but the experience is currently not guaranteed to be perfect or free of issues and bugs.
Some key features of PipeWire include:
- Minimal latency capture/playback of audio and video.
- Real-time multimedia processing.
- Multi-process architecture allowing multimedia content sharing between applications.
- Seamless support for PulseAudio, JACK, ALSA, and GStreamer.
- Applications sandboxing support with Flatpak.
Installation
USE-Flags
The use of PipeWire by applications is governed by the
screencast
USE flag.
USE flags for media-video/pipewire Multimedia processing graphs
X
|
Add support for X11 |
bluetooth
|
Enable Bluetooth Support |
debug
|
Enable extra debug codepaths, like asserts and extra output. If you want to get meaningful backtraces see https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces |
doc
|
Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally |
ffmpeg
|
Enable ffmpeg/libav-based audio/video codec support |
gstreamer
|
Add support for media-libs/gstreamer (Streaming media) |
jack
|
Enable SPA JACK plugin and emulation to be able to run JACK applications on top of PipeWire |
sdl
|
Add support for Simple Direct Layer (media library) |
sndfile
|
Add support for libsndfile |
systemd
|
Enable use of systemd-specific libraries and features like socket activation or session tracking |
test
|
Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently) |
vulkan
|
Enable vulkan spa plugin integration |
Emerge
To emerge PipeWire one can either issue:
root #
emerge --ask media-video/pipewire
or set the screencast
USE flag on ebuilds that have it e.g. by adding it to global USE and then rebuilding changed packages:
root #
emerge -avuUD world
which should pull in media-video/pipewire as dependency.
Configuration
PipeWire is still in heavy development - configuration paths, options and defaults can change from one minor release to another - if things on the system do not align with documentation, double check or at least make a backup before making changes.
In order to avoid a lower quality duplicate, PipeWire configuration that is not specific to Gentoo should be found at the project's official wiki instead.
Global PipeWire configuration can be changed by editing /etc/pipewire/pipewire.conf . Additionally PipeWire recognizes multiple environment variables that allow these settings to be changed per-user or individual command. Typically things work reasonably well out of the box, and PipeWire's global configuration is best left alone.
In principle existing PulseAudio or JACK tools can be used to interact with PipeWire when it is set up to behave as a JACK and/or PulseAudio server but currently only parts of the respective APIs have been implemented.
Starting PipeWire with user session
systemd
PipeWire provides socket and service files when built with the systemd
USE flag. The following systemctl command enables systemd's socket activation of PipeWire for the current user:
user $
systemctl --user enable --now pipewire.socket
The socket activation only starts the service when required, which is usually sufficient. Alternatively the user service can be always started when the user logs in by replacing pipewire.socket with pipewire.service:
user $
systemctl --user enable --now pipewire.service
In both cases, the `--now` flag is optional but probably safe to use as starting PipeWire with default configuration merely allows using new interfaces but does not change the existing ones i.e. non-PipeWire clients continue using the same libraries and services they were using previously. To also replace PulseAudio and/or JACK, one must additionally follow the appropriate instructions elsewhere in this page.
OpenRC with elogind (any of Gentoo's desktop profiles)
PipeWire relies on a working D-Bus user daemon as well as XDG compliant environment. Both requirements should be automatically met when any one of the desktop profiles is being used thanks to their elogind integration. On such systems starting PipeWire is as simple as starting the pipewire
binary. The only tricky part is that there is no truly standardized way (outside of systemd, of course) to actually do this and users need to choose the correct approach based on how their graphical shell is started, which has been summarized in the following table:
In all cases where systemd user services are not being used, PipeWire must be started before anything that might try to connect to any sound input or output, such as a volume monitoring applet. Additionally one may consider disabling PA autospawn as described in
man pulse-client.conf
.Setup | Instructions | Content to add | Notes |
---|---|---|---|
Display manager (SDDM, LightDM, GDM, etc) | Edit ~/.xprofile file. | FILE ~/.xprofile pipewire & | Note It's currently unknown whether .xprofile is sourced when starting a Wayland session - such users may need to look for an alternative approach, e.g. using XDG autostart. |
startx | Edit ~/.xinitrc file. | FILE ~/.xinitrc pipewire & | D-Bus user session and XDG integration assumed to work out of the box but untested. |
Sway | Edit ~/.config/sway/config file. | FILE ~/.config/sway/config exec --no-startup-id pipewire | Either elogind or seatd must be in use. Otherwise start sway with user $ dbus-launch --exit-with-session sway |
Login without session management
The user must ensure there is a viable D-Bus session active:
~/.xinitrc
<syntaxhighlight lang="bash">if which dbus-launch >/dev/null && test -z "$DBUS_SESSION_BUS_ADDRESS"; then eval `dbus-launch --sh-syntax --exit-with-session` fi</syntaxhighlight>
The user must ensure that XDG_RUNTIME_DIR is set. This is usually managed by either systemd-logind, it's fork elogind for OpenRC and similar init systems or seatd - an alternative free-standing implementation of logind. In addition to running one of the 3 logind variants, a PAM module must also be loaded to let the daemon interact with users logging in and out of the system.
On systems where the above is not true, the user must create the require directory and set the environmental variable manually:
#-- ensure XDG_Runtime_dir is set
unset XDG_RUNTIME_DIR
export XDG_RUNTIME_DIR=$(mktemp -d /tmp/$(id -u)-runtime-dir.XXX)
The PipeWire executable must also be called:
~/.xinitrc
/usr/bin/pipewire
Replacing PulseAudio
systemd
These instructions must be executed as and for each user that needs PipeWire!
First disable PulseAudio user service (safe to do even if user service was not in use) and then enable PipeWire and PipeWire-Pulse sockets:
user $
systemctl --user disable pulseaudio.socket pulseaudio.service
user $
systemctl --user enable pipewire.socket pipewire-pulse.socket
While PipeWire does not appear to utilize it beyond the cookie file, it may be a good idea to delete or rename the directory of existing PulseAudio user configuration that's usually found under
~/.config/pulse/
.Optionally one can also mask PulseAudio user service and socket but it should be noted that this will not help much if PulseAudio configuration permits autostart [as is default]:
user $
systemctl --user mask pulseaudio.socket pulseaudio.service
A reboot is strongly advised for the change to take effect. Of course this can be avoided but due to PulseAudio usually being configured to autostart and often surviving logouts, this feat of stubbornness is left as an exercise to particularly skilled readers.
OpenRC
To have PipeWire to act as a PulseAudio user daemon/server, un-comment the "/usr/bin/pipewire" = { args = "-c pipewire-pulse.conf" } line in the main configuration file:
/etc/pipewire/pipewire.conf
context.exec = { #<program-name> = { [ args = "<arguments>" ] } # # Execute the given program with arguments. # # Start the session manager. Run the session manager with -h for # options. # "/usr/bin/pipewire-media-session" = { args = "" } # # You can optionally start the pulseaudio-server here as well # but it better to start it as a systemd service. # It can be interesting to start another daemon here that listens # on another address with the -a option (eg. -a tcp:4713). "/usr/bin/pipewire" = { args = "-c pipewire-pulse.conf" } }
Verifying that it worked
To check whether PipeWire is now acting as the PulseAudio user daemon/server, use this pactl command in a Bash compatible shell (no the code below is not a typo - we had to avoid piping commands as Gentoo Wiki templates run on the pipe symbol):
user $
pactl info > >(grep "Server Name")
Replacing JACK
To have JACK clients routed through PipeWire, currently the only method supported by Gentoo is to run them via pw-jack which uses LD_PRELOAD to redirect clients from JACK's original libraries to PipeWire's alternatives:
user $
pw-jack qsynth
Existing JACK users are likely to have realtime capability set up but new users are advised to raise the RLIMIT_MEMLOCK from Gentoo's default of 64 kilobytes to 256 kilobytes on all PipeWire users that want to use its JACK emulation. For instructions on how to achieve that please see the subsection on that below (also listed in the table of contents for this page). Failure to do this will likely cause at least occasional buffer underuns (xruns) as a single page fault is likely to spend half to the entire length of a buffer just in kernel time to resolve.
It should be noted that either due to PipeWire incompleteness or Gentoo configuration shortcomings, not every client will work. Some may even ungracefully exit due to missing symbols. It will likely also require re-configuration of JACK clients, because they will attempt to use their old configuration files, if such exist.
Alternatively it should be possible to have PipeWire connect to a real jackd and act as a gateway for non-JACK applications but, unless there already is a working JACK setup, this is not recommended for the overall worse user experience with JACK.
Fixes and workarounds
CS:GO (and other games using the Valve's Source engine)
It appears that this issue has been resolved by a patch by Valve in early 2021. If the issue is no longer present without any fixes applied, then please delete this subsection entirely.
The default sound buffer length is 0.025. This can sometimes be too low causing cracking audio; for now the workaround is to increase the size of the application's audio buffer from within CS:GO[1][2]:
snd_mixahead is the length of the sound buffer in seconds, so 0.05 is 50ms (0.10, edited: 25ms is the default). This is essentially the audio delay, so reducing it gives better synchronization. Not all hardware can handle this low of a buffer setting though, so if you hear any crackling or pops at 0.05, increase this setting by 0.01 until the crackling/pops disappear.
Increasing RLIMIT_MEMLOCK for PulseAudio clients (systemd specific)
While the general issue of insufficient lockable memory limit is common among Gentoo and, indeed, most Desktop GNU/Linux distributions, this subsection chiefly addresses an additional resource limit on systemd units. Readers not using systemd's user services should follow instructions on JACK clients instead.
In case if messages such as this are observed:
user $
systemctl --user status pipewire-pulse.service
.. pipewire-pulse[pid]: Failed to mlock memory [address] 32816: This is not a problem but for best performance, consider increasing RLIMIT_MEMLOCK
...one can adjust the amount of memory that pipewire-pulse process can lock via:
user $
systemctl edit --user pipewire-pulse.service
and add in the blank space in the upper section of the editor window (not forgetting to save the file afterwards, of course):
...
### Anything between here and the comment below will become the new contents of the file
[Service]
LimitMEMLOCK=256K
### Lines below this comment will be discarded
...
systemd is case sensitive and does not recognize the SI abbreviation for kilo, so be sure to use the capital letter K or will print a warning about illegal value and not apply the override!
If the system is shared between multiple users, this has to be done for each user (or the created override file has to be copied over with appropriate permissions).
Finally, to have the override applied one must reload the configuration and then restart the service:
user $
systemctl --user daemon-reload
user $
systemctl --user restart pipewire-pulse.service
The current unit default is set to LimitMEMLOCK=131072
(same as 128K) by the Gentoo package which as of PipeWire 0.3.21 appears to allow for 1 PulseAudio client (subsequent clients will receive buffers backed by unlocked memory). Increasing the number to 256K as seen above should allow for 3 clients with buffers locked to memory at the same time.
While this is just a conjecture, it seems very likely that the LimitMEMLOCK which sets the per-unit hard limit (and implicitly also the LimitMEMLOCKSoft to the same value) must be within the bounds set on the user in question, which is 64 kilobytes for users without realtime capability. To actually have the default 128K or any other value above 64 kilobytes applied, one therefore must set a new limit for non-system accounts:
/etc/security/limits.d/50-custom.conf
# This raises the lockable memory upper limit of every process running under a non-system account (except for nobody) from default 64 to 256 kilobytes (in increments of ''page size''); default (soft limit) remains at 64 kilobytes 1000:65533 hard memlock 256
The new limits are only in effect on new logins, therefore the user must log out and back in. This is usually enough but if pipewire-pulse.service survived the logout, then it must be manually restarted as described previously in this subsection.
Increasing RLIMIT_MEMLOCK for JACK clients (and PulseAudio clients with OpenRC)
Unlike the case of PulseAudio clients, for which the user service does memory locking of buffers, JACK clients do it themselves. In the likely event that the clients report being unable to lock memory, in addition to the hard limit (max permitted value) described in previous sub-section on PulseAudio RLIMIT_MEMLOCK, the soft limit (the default value) must also be raised:
/etc/security/limits.d/50-custom.conf
# This both raises the max and sets the default lockable memory limit of every process running under a non-system account (except for nobody) from default 64 to 256 kilobytes (in increments of ''page size'') 1000:65533 - memlock 256
Bluetooth
PipeWire should already be enabling the bluez5 module when built with the
pulseaudio
USE flag. Please check if it's being set system-wide as PulseAudio API for clients is not going anywhere in a hurry.By default, Bluetooth support is disabled to avoid clashes with PulseAudio's Bluetooth stack since currently the main use case is as an addition to not a replacement for PA. Uncomment PipeWire's bluez5 module for Bluetooth devices to be listed:
/etc/pipewire/media-session.d/media-session.conf
... modules = { ... default = [ ... bluez5 # bluetooth support ... ] ...
then run:
user $
systemctl --user restart pipewire-pulse.service
See also
- PulseAudio — a sound server that provides a number of features on top of the low-level audio interface ALSA on Linux
- ALSA — describes the setup of a sound card with ALSA (Advanced Linux Sound Architecture).