Links
- Homepage
- https://www.pipewire.org/
- Documentation
- https://docs.pipewire.org/
There’s also some pretty good documentation on ArchWiki’s WirePlumber page.
Programs
-
qpwgraph
andqjackctl
both let you see a patch graph of nodes. You should prefer the former, the latter I think can bunch up several different clients in one. Like,qpwgraph
splits up the connections topavucontrol
, whereasqjackctl
does not. -
wpctl
is part of WirePlumber. -
pw-cli
is part of PipeWire proper.
Command Line
Creating Nodes
Here’s how to create a pipewire node:
pw-cli create-node adapter '{ factory.name=support.null-audio-sink node.name=Mixed-Input node.description="Mixed Input" media.class=Audio/Source/Virtual object.linger=true audio.position=FL,FR }'
The object.linger=true
is pretty important here.
If you don’t include it, it won’t show up on qpwgraph
.
I’m guessing it’s because objects that aren’t set to linger are automatically cleaned up when not connected to anything.
Note that you probably want to actually configure this with something like WirePlumber, but I haven’t gotten around to that as of March 2024.
My NixOS Settings
Here’s my pipewire settings for NixOS. It’s pretty outdated.
{ config, pkgs, lib, ... }:
{
# sound.enable = false;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
environment.sessionVariables.LD_LIBRARY_PATH = lib.mkForce "${config.services.pipewire.package.jack}/lib";
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# Jack support works, but it weirdly breaks GTK Webkit
# https://github.com/NixOS/nixpkgs/issues/110468
jack.enable = true;
# See the workaround up ahead
# use the example session manager (no others are packaged yet so this is enabled by default,
# no need to redefine it in your config for now)
#media-session.enable = true;
# config.pipewire doesn't work now. TODO: I'll need to make these another way. 2023-12-07
# config.pipewire = {
# "context.objects" = [
# {
# # A default dummy driver. This handles nodes marked with the "node.always-driver"
# # property when no other driver is currently active. JACK clients need this.
# factory = "spa-node-factory";
# args = {
# "factory.name" = "support.node.driver";
# "node.name" = "Dummy-Driver";
# "priority.driver" = 8000;
# };
# }
# {
# factory = "adapter";
# args = {
# "factory.name" = "support.null-audio-sink";
# "node.name" = "Mixed-Input";
# "node.description" = "Mixed Input";
# "media.class" = "Audio/Source/Virtual";
# "audio.position" = "FL,FR";
# };
# }
# {
# factory = "adapter";
# args = {
# "factory.name" = "support.null-audio-sink";
# "node.name" = "Microphone-Two";
# "node.description" = "Microphone Two";
# "media.class" = "Audio/Source/Virtual";
# "audio.position" = "MONO";
# };
# }
# {
# factory = "adapter";
# args = {
# "factory.name" = "support.null-audio-sink";
# "node.name" = "Copy-Output";
# "node.description" = "Copy Output";
# "media.class" = "Audio/Sink";
# "audio.position" = "FL,FR";
# };
# }
# ];
# };
};
environment.systemPackages = with pkgs; [
alsaUtils # Sometimes needed for changing the volume on things
pavucontrol
qjackctl
calf
# pulseeffects-pw # Not found in 2023-12-07
carla
zynaddsubfx
sorcer
speech-denoiser
# talentedhack
artyFX
# ardour
# rnnoise
];
# TODO: Add the following environment variables in a better, more stateless way
# (Maybe use an absolute path instead?)
environment.shellInit = ''
export VST_PATH=/run/current-system/sw/lib/vst:~/.vst
export LXVST_PATH=/run/current-system/sw/lib/lxvst:~/.lxvst
export LADSPA_PATH=/run/current-system/sw/lib/ladspa:~/.ladspa
export LV2_PATH=/run/current-system/sw/lib/lv2:~/.lv2
export DSSI_PATH=/run/current-system/sw/lib/dssi:~/.dssi
'';
}