PipeWire status tracking issue

TL;DR: Things are generally in pretty good shape but wireplumber can't be configured via the nixos module yet. On the other hand most people won't need to change anything from the defaults.
If you are reporting something, please mention the pipewire version you are using, as it is updated very frequently. Bonus points for checking if upstream already has a fix mentioned in the commit log or release notes.
Currently on master:

[x] nixos service exists and works (socket-activated systemd user service)
[x] alsa and JACK compatibility shims can be enabled with options
[x] pulse-bridge, a fake pulse server enabled with the pulse option (socket-activated systemd user service)
[x] bluetooth (loaded by the pulseaudio module)
[x] wireplumber (Packaged and usable but can't be configured via nixos modules yet. Custom config files can be placed in ~/.config/wireplumber)

Configuration
Most basic additions to configuration.nix, this should be enough for most people:
  # Remove sound.enable or turn it off if you had it set previously, it seems to cause conflicts with pipewire
  #sound.enable = false;

  # rtkit is optional but recommended
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    # If you want to use JACK applications, uncomment this
    #jack.enable = true;
  };

Some useful knobs if you want to finetune or debug your setup. Note that pipewire config keys may contain a period '.' so they need to be quoted in Nix. (combine these with the basic config above):
  services.pipewire = {
    config.pipewire = {
      "properties" = {
        #"link.max-buffers" = 64;
	"link.max-buffers" = 16; # version < 3 clients can't handle more than this
	"log.level" = 2;
        #"default.clock.rate" = 48000;
        #"default.clock.quantum" = 1024;
        #"default.clock.min-quantum" = 32;
        #"default.clock.max-quantum" = 8192;
    };
  };

Virtual Sinks/Sources
If you want to do some fancy routing with null sinks, you can define them directly in the pipewire config like this. Especially convenient if you have a multi-channel (8+, or something "weird" like 2x2, 3x2) soundcard that keeps confusing applications with too many channels or a bad channel layout. (Note: you can set those cards to the "Pro Audio" profile with pavucontrol so pipewire doesn't try to guess a wrong channel layout for them.) Note that arrays are replaced rather than merged with defaults, so you need to list any default items that you want to keep here (the dummy and freewheeling driver for JACK applications, if you have JACK support enabled):
  services.pipewire = {
    config.pipewire = {
      "context.objects" = [
        {
          # A default dummy driver. This handles nodes marked with the "node.always-driver"
          # properyty 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";
            "node.group"       = "pipewire.dummy";
            "priority.driver"  = 20000;
          };
        }
        {
          # Freewheeling driver. This is used e.g. by Ardour for exporting projects faster than realtime.
          factory = "spa-node-factory";
          args = {
            "factory.name"     = "support.node.driver";
            "node.name"        = "Freewheel-Driver";
            "node.group"       = "pipewire.freewheel";
            "node.freewheel"   = true;
            "priority.driver"  = 19000;
          };
        }
        {
          factory = "adapter";
          args = {
            "factory.name"     = "support.null-audio-sink";
            "node.name"        = "Microphone-Proxy";
            "node.description" = "Microphone";
            "media.class"      = "Audio/Source/Virtual";
            "audio.position"   = "MONO";
          };
        }
        {
          factory = "adapter";
          args = {
            "factory.name"     = "support.null-audio-sink";
            "node.name"        = "Main-Output-Proxy";
            "node.description" = "Main Output";
            "media.class"      = "Audio/Sink";
            "audio.position"   = "FL,FR";
          };
        }
      ];
    };
  };

You can't currently link nodes to each other in the config, but you can adapt this script to do it for you. Replace the soundcard names and ports with whatever matches your setup:
#!/usr/bin/env bash

# ports obtained from `pw-link -io`

pw-link "Main-Output-Proxy:monitor_FL" "alsa_output.usb-Native_Instruments_Komplete_Audio_6_69BC86B9-00.pro-output-0:playback_1"
pw-link "Main-Output-Proxy:monitor_FR" "alsa_output.usb-Native_Instruments_Komplete_Audio_6_69BC86B9-00.pro-output-0:playback_2"

pw-link "alsa_input.usb-M-Audio_Fast_Track-00.pro-input-0:capture_1" "Microphone-Proxy:input_MONO"

Standalone mode (no session manager)
If you want to run a minimal pipewire instance with no session manager for automatic switching etc, you can do that as of 0.3.46 (technically pipewire supported it a bit longer than that but that's when the nixos module was adapted to account for it). This is mainly intended for systems that used to run purely JACK:
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    jack.enable = true;
    wireplumber.enable = false;
    media-session.enable = false;
  };

If this doesn't work it is likely because it defaults to using an alsa device called hw:0 which might not be the sound card you want to be using. You can easily fix this by overriding the device name in the "context.objects" array of the main pipewire configuration. The names and descriptions of available devices can be seen with aplay -l from the alsa-utils package. Note that you'll have to write out the full contents of the array because the default items will be replaced completely with this:
  services.pipewire.config.pipewire = {
      "context.objects" = [
        {
          factory = "metadata";
          args = {
            "metadata.name" = "default";
          };
        }
        {
          # A default dummy driver. This handles nodes marked with the "node.always-driver"
          # properyty 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";
            "node.group"       = "pipewire.dummy";
            "priority.driver"  = 20000;
          };
        }
        {
          # Freewheeling driver. This is used e.g. by Ardour for exporting projects faster than realtime.
          factory = "spa-node-factory";
          args = {
            "factory.name"     = "support.node.driver";
            "node.name"        = "Freewheel-Driver";
            "node.group"       = "pipewire.freewheel";
            "node.freewheel"   = true;
            "priority.driver"  = 19000;
          };
        }
        {
          args = {
          "adapter.auto-port-config" = {
            mode = "dsp";
            monitor = false;
            position = "unknown";
          };
          "api.alsa.path" = "hw:0"; # replace with the right path for your system
          "channelmix.disable" = true;
          "factory.name" = "api.alsa.pcm.source";
          "media.class" = "Audio/Source";
          "node.description" = "system";
          "node.name" = "system";
          "node.suspend-on-idle" = true;
          "resample.disable" = true;
          };
          factory = "adapter";
        }
        {
          args = {
          "adapter.auto-port-config" = {
            mode = "dsp";
            monitor = false;
            position = "unknown";
          };
          "api.alsa.path" = "hw:0"; # replace with the right path for your system
          "channelmix.disable" = true;
          "factory.name" = "api.alsa.pcm.sink";
          "media.class" = "Audio/Sink";
          "node.description" = "system";
          "node.name" = "system";
          "node.suspend-on-idle" = true;
          "resample.disable" = true;
          };
          factory = "adapter";
        }
      ];
    };
  };

Miscellaneous
For the time being you can switch between two session managers, although there is usually no reason to. Note #159546 which intends to change the default from media-session to wireplumber since media-session is considered deprecated by upstream.
  services.pipewire = {
    # wireplumber.enable = true;
    # media-session.enable = false;
  }

For other available options, consult the upstream config templates. All config files listed there should be accessible via the nixos module as services.pipewire.config.$basename and services.pipewire.media-session.config.$basename for the daemon and the default session manager respectively.
Please help test new PRs!
Please do try out update pull requests before they are merged (if you can), it is fairly easy:

Make a local clone of nixpkgs
Fetch the PR branch to your clone of nixpkgs
(It might be a good idea to cherry-pick or rebase the PR on top of your release channel branch instead of master)
Build your system configuration using the cloned nixpkgs instead of the configured channel: sudo nixos-rebuild test -I nixpkgs=path/to/nixpkgs/clone

Useful nixos-rebuild verbs besides the usual "switch" and "boot" are: "build" and "test" (build and enable but don't change boot)

Known Problems
The issues people have previously described here should all be fixed now.
Please add a comment if something is broken (and ideally open an issue upstream if it is not a packaging problem).

From my experience

With default configuration

Bluetooth

Works fine for a small amount of time, before crapping out and going out of sync

On high load

Well let's just say it isn't pretty but not unusable

With tweaked configuration (don't ask how to tweak, I don't know, or at least it needs tweaking outside of the pipewire configuration as well)

Bluetooth

I haven't had any out of sync yet, though I do have some intermittent audio loss but at least it still stays in sync

On high load

Better but still pretty distinctive

There are other things that are pretty annoying, audio control is completely bonkers for me, alsactl/alsamixer is half broken, I have to rely on using pactl and the pulseaudio library shims to even change my audio with keybinds. Anyway just a couple of things off the top of my head.
Note that you may not experience some of my issues, because it's configuration dependent on more than just the pipewire configuration.

Did some digging and the Discord issue is fairly simple: the wrapper prepends the dependencies' paths to LD_LIBRARY_PATH, and those dependencies include libpulseaudio. So I tried making a copy of the wrapper script that prepends the pipewire pulseaudio shim's path instead of the native pulseaudio one and voilà, it works perfectly!
I'm guessing the Right solution to this is to wait for the pulse-bridge aka "fake" pulseaudio server in pipewire so Discord (and presumably steam) can just use the native library and everything looks like business as usual to them.

Pulse-bridge does seem to work surprisingly well: I tried stopping the pipewire service and launching it manually with pulse-bridge enabled (I have pulseaudio disabled in my nixos config so there won't be conflicts): pipewire-media-session -e pulse-bridge
If steam, discord etc is launched after starting the media session, audio is working without further tweaking as expected. If they were running before this, they will likely crash or lock up when pipewire is stopped.
So for transparent support we'll need a nixos option to enable the pulse-bridge module as described upstream. Some discussion about that happened in #102514 . I expect the pulseaudio shim to be deprecated eventually in favour of the bridge.
The same approach could be used for the bluez5 module which is also disabled by default for now.

Upstream has deprecated the libpulseaudio.so shim and provides a systemd service to load pulse-bridge now. This makes packaging a lot easier since we don't have to patch files and there should no longer be socket conflicts with pulseaudio either.

ALSA compatibility option doesn't provide ctl.!default for some reason: https://github.com/NixOS/nixpkgs/blob/c18b90b5b90bd20c421ffe795420ad501e6613c7/nixos/modules/services/desktops/pipewire.nix#L85-L98
This leads to the impossibility to control pipewire via alsamixer :(

0.3.16 has been merged, this adds pulse-bridge which fixes most pulseaudio applications including steam and its games. (channels haven't updated yet at the time of writing though)

0.3.16 has been merged

0.3.17 just released ;)

With 0.3.17, bluetooth works out of the box for me (both HFP and A2DP).  #105362

Isn't the bluez5 module disabled by default?

Isn't the bluez5 module disabled by default?

#105362 enables it by the with-pulse file

Bluetooth worked for me even without the with-pulse file.  HFP required enabling hsphfpdSupport (compile-time option) though.

According to the source code, it should be enabled with the pulse file: https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/0.3.17/src/examples/media-session/media-session.c#L2109-2111
And looks like it should be with-pulseaudio rather than with-pulse: https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/0.3.17/src/examples/media-session/media-session.c#L2128

Thanks, fixed the with-pulseaudio file name.
Eventually, the nixos module should also generate a pipewire.conf file (so that we can modify it).  Right now, it's e.g. impossible to pass extra arguments to pipewire-media-session.

I have an issue while trying to use qjackctl with pipewire:
$ qjackctl
/nix/store/xv3g9szrk83yqizmzzaxvl45qz5sv4hh-qjackctl-0.6.3/bin/qjackctl: symbol lookup error: /nix/store/xv3g9szrk83yqizmzzaxvl45qz5sv4hh-qjackctl-0.6.3/bin/qjackctl: undefined symbol: jack_session_commands_free

Thanks, fixed the with-pulseaudio file name.

btw, imho, it is worth to replace
    sound.extraConfig = mkIf cfg.alsa.enable ''
      pcm_type.pipewire {
        libs.native = ${cfg.package.lib}/lib/alsa-lib/libasound_module_pcm_pipewire.so ;
        ${optionalString enable32BitAlsaPlugins
          "libs.32Bit = ${pkgs.pkgsi686Linux.pipewire.lib}/lib/alsa-lib/libasound_module_pcm_pipewire.so ;"}
      }
      pcm.!default {
        @func getenv
        vars [ PCM ]
        default "plug:pipewire"
        playback_mode "-1"
        capture_mode "-1"
      }
    '';
    environment.etc."alsa/conf.d/50-pipewire.conf" = mkIf cfg.alsa.enable {
      source = "${cfg.package}/share/alsa/alsa.conf.d/50-pipewire.conf";
    };

with
    sound.extraConfig = mkIf cfg.alsa.enable ''
      pcm_type.pipewire {
        libs.native = ${cfg.package.lib}/lib/alsa-lib/libasound_module_pcm_pipewire.so ;
        ${optionalString enable32BitAlsaPlugins
          "libs.32Bit = ${pkgs.pkgsi686Linux.pipewire.lib}/lib/alsa-lib/libasound_module_pcm_pipewire.so ;"}
      }
      ctl_type.pipewire {
        libs.native = ${cfg.package.lib}/lib/alsa-lib/libasound_module_ctl_pipewire.so ;
        ${optionalString enable32BitAlsaPlugins
          "libs.32Bit = ${pkgs.pkgsi686Linux.pipewire.lib}/lib/alsa-lib/libasound_module_ctl_pipewire.so ;"}
      }
    '';
    environment.etc."alsa/conf.d/50-pipewire.conf" = mkIf cfg.alsa.enable {
      source = "${cfg.package}/share/alsa/alsa.conf.d/50-pipewire.conf";
    };
    environment.etc."alsa/conf.d/99-pipewire-default.conf" = mkIf cfg.alsa.enable {
      source = "${cfg.package}/share/alsa/alsa.conf.d/99-pipewire-default.conf";
    };

Is there a reason to keep the sound.extraConfig or could we put that into alsa/conf.d as well?

Yeah, it should work with conf.d as well. You could test with alsamixer: if everything is ok, it will give pipewire volume control instead of hardware volume control by default.

It finds out, qjackctl can be fixed with --disable-jack-session option to configure. It should be provided by default, since jack session api is deprecated: https://jackaudio.org/api/group__JackSessionManagerAPI.html

I don't know if the following issues are nixos specific:

After each restart I have to replug my audio interface(PCM2902) for it to work properly
Each time the configuration is changed (volume or new audio stream) i can hear a short crackling noise.

With pipewire, my keyboard media keys (vol up & vol down) don't seem to work under gnome (x11).
Anyone has an idea?

Anyone has an idea?

It's a bug with restoring default device on restart
https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/429

pipewire has a race condition with logind, thus adding the user to the audio group might help with some issues that happen on restart (i always add my user to the audio group to have working rtkit-daemon, so I don't know which issues it might fix exactly)
https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/423

Just updated my NixOS unstable

0.3.18 is out, fixes some more issues: https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/NEWS
Hopefully my sound card won't stutter anymore with the latest bugfixes.

0.3.18 is out, fixes some more issues: https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/NEWS
Hopefully my sound card won't stutter anymore with the latest bugfixes.

Just waiting for the nixos channels to update... #106990

Oh, I missed that, thanks :)

Just updated to the latest nixos unstable (before i had almost perfectly working pipewire aside from a couple of annoyances) now i have completely broken audio, alsamixer throws this
[W][000000128.554552][ctl_pipewire.c:1105 on_core_error()] alsa-plugin 0x2177300: error id:5 seq:21 res:-2 (No such file or directory): enum params id:13 (Spa:Enum:ParamId:Route) failed

And audio (if it comes out) is completely distorted and from the left channel only

Updated to the latest nixos unstable as well and I don't have any problems :man_shrugging:

Current nixos-unstable works fine for me, but I don't really use alsa nor am I familiar with how it is supposed to work (didn't have much success when I gave it a quick try in the previous version though). @ilya-fedin can you edit the alsa bits in the OP since you seem to be familiar with it? If not, please update me on fixed/new known issues you encounter.
@bbigras plasma/gnome volume widgets aren't working at all here it seems, I think the keyboard volume buttons go through those... IIRC they are supposed to work with the fake pulse server though, not sure what the problem there is

@ilya-fedin can you edit the alsa bits in the OP since you seem to be familiar with it?

Looks like I have not enough rights :(
I know at least two problems with alsamixer (seems to be bugs in the pipewire's shim):

Volume changes don't reflect with volume on PA/PW/Jack APIs, unlike with pulseaudio's alsa shim
If set volume to 0% with alsamixer, it is impossible to revert the volume to normal with it, but amixer works:

Find id of the volume control with amixer controls (it is numid=3,iface=MIXER,name='Master Playback Volume' for me)
Reset the volume: amixer cset numid=3 (where numid=3 is your numid)

With regards to GNOME, you can convince it to work.
To get the notification icon working, you can just do a gnome reset (enter r in the alt+f2 menu)
To get the media keys working systemctl --user restart org.gnome.SettingsDaemon.MediaKeys.target
Seems like there is some sort of race condition at session-startup perhaps?

Using this config seems to make pipewire with Gnome/x11 work just fine.
Forcing the services to start instead of using socket activation.
  hardware.pulseaudio.enable = pkgs.lib.mkForce false;
  systemd.user.services.pipewire.wantedBy = [ "default.target" ];
  systemd.user.services.pipewire-pulse.wantedBy = [ "default.target" ];
  services.pipewire = {
    enable = true;
    socketActivation = false;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
  };

Using this config seems to make pipewire with Gnome/x11 work just fine.

It's weird. With that config I get the notification icon and the volume overlay working but only in gdm.
Once logged in I have none and my sound doesn't work. I had no output with pavucontrol.
Maybe it's a coincidence. In my config I also had jack.enable = true.
pipewire
-- Journal begins at Mon 2020-11-23 21:17:39 EST, ends at Thu 2020-12-31 14:36:47 EST. --
déc 31 04:41:30 desktop systemd[2044]: Started Multimedia Service.
déc 31 04:41:30 desktop pipewire[2053]: Failed to receive portal pid: org.freedesktop.DBus.Error.NameHasNoOwner: Could not get PID of name 'org.freedesktop.portal.Desktop': no such name
déc 31 04:41:30 desktop pipewire[2053]: could not make thread realtime: No such file or directory
déc 31 04:41:30 desktop pipewire-media-session[2067]: could not make thread realtime: No such file or directory
déc 31 04:41:30 desktop pipewire-media-session[2067]: can't open control for card hw:1: No such file or directory
déc 31 04:41:30 desktop pipewire-media-session[2067]: can't open control for card hw:0: No such file or directory
déc 31 04:41:30 desktop pipewire-media-session[2067]: can't open control for card hw:2: No such file or directory
déc 31 04:41:30 desktop pipewire-media-session[2067]: v4l2: Cannot open '/dev/video0': 13, Permission denied
déc 31 04:41:30 desktop pipewire-media-session[2067]: v4l2: Cannot open '/dev/video1': 13, Permission denied
déc 31 04:41:30 desktop pipewire-media-session[2067]: oFono: Register() failed: org.freedesktop.DBus.Error.ServiceUnknown
déc 31 04:41:30 desktop pipewire-media-session[2067]: RegisterApplication() failed: org.freedesktop.DBus.Error.ServiceUnknown
déc 31 04:41:30 desktop pipewire[2053]: ALSA lib seq_hw.c:466:(snd_seq_hw_open) open /dev/snd/seq failed: Permission denied
déc 31 04:41:30 desktop pipewire[2053]: open failed: Permission denied
déc 31 04:41:30 desktop pipewire[2053]: can't create node: Permission denied
déc 31 04:41:30 desktop pipewire-media-session[2067]: error id:3 seq:3 res:-13 (Permission denied): can't create node: Permission denied
déc 31 04:41:55 desktop pipewire-media-session[2067]: GetManagedObjects() failed: org.freedesktop.DBus.Error.NoReply
déc 31 04:45:00 desktop pipewire-media-session[2067]: no node found for 37

pipewire-pulse
-- Journal begins at Mon 2020-11-23 21:17:39 EST, ends at Thu 2020-12-31 14:36:47 EST. --
déc 31 04:41:30 desktop systemd[2044]: Started PipeWire PulseAudio.
déc 31 04:41:30 desktop pipewire-pulse[2052]: could not make thread realtime: No such file or directory
déc 31 04:45:00 desktop pipewire-pulse[2052]: stream 0x10cef90: error no node available
déc 31 04:45:00 desktop pipewire-pulse[2052]: pulse-server 0x10aaeb0: [Firefox] ERROR command:-1 (invalid) tag:5 error:25 (Input/output error)
déc 31 04:45:44 desktop pipewire-pulse[2052]: pulse-server 0x10d0fe0: [Contrôle du volume PulseAudio] ERROR command:87 (EXTENSION) tag:12 error:19 (Operation not supported)
déc 31 04:45:44 desktop pipewire-pulse[2052]: pulse-server 0x10d0fe0: [Contrôle du volume PulseAudio] ERROR command:87 (EXTENSION) tag:13 error:19 (Operation not supported)
déc 31 04:45:44 desktop pipewire-pulse[2052]: pulse-server 0x10d0fe0: [Contrôle du volume PulseAudio] ERROR command:87 (EXTENSION) tag:14 error:19 (Operation not supported)
déc 31 04:45:44 desktop pipewire-pulse[2052]: pulse-server 0x10d0fe0: [Contrôle du volume PulseAudio] ERROR command:87 (EXTENSION) tag:15 error:19 (Operation not supported)

Here's the logs when it works:
pipewire
-- Journal begins at Tue 2020-11-24 05:22:01 EST, ends at Thu 2020-12-31 14:36:47 EST. --
déc 30 23:54:38 desktop systemd[2037]: Started Multimedia Service.
déc 30 23:54:38 desktop pipewire[2403]: could not make thread realtime: No such file or directory
déc 30 23:54:38 desktop pipewire[2403]: Failed to receive portal pid: org.freedesktop.DBus.Error.NameHasNoOwner: Could not get PID of name 'org.freedesktop.portal.Desktop': no such name
déc 30 23:54:38 desktop pipewire-media-session[2428]: could not make thread realtime: No such file or directory
déc 30 23:54:38 desktop pipewire-media-session[2428]: oFono: Register() failed: org.freedesktop.DBus.Error.ServiceUnknown
déc 30 23:54:38 desktop pipewire-media-session[2428]: RegisterApplication() failed: org.freedesktop.DBus.Error.ServiceUnknown
déc 30 23:54:49 desktop pipewire-media-session[2428]: GetManagedObjects() failed: org.freedesktop.DBus.Error.TimedOut

pipewire-pulse
-- Journal begins at Tue 2020-11-24 05:22:01 EST, ends at Thu 2020-12-31 14:36:47 EST. --
déc 30 23:54:35 desktop systemd[2037]: Started PipeWire PulseAudio.
déc 30 23:54:36 desktop pipewire-pulse[2209]: could not make thread realtime: No such file or directory
déc 30 23:55:02 desktop pipewire-pulse[2209]: pulse-server 0x1100df0: [Contrôle du volume PulseAudio] ERROR command:87 (EXTENSION) tag:12 error:19 (Operation not supported)
déc 30 23:55:02 desktop pipewire-pulse[2209]: pulse-server 0x1100df0: [Contrôle du volume PulseAudio] ERROR command:87 (EXTENSION) tag:13 error:19 (Operation not supported)
déc 30 23:55:02 desktop pipewire-pulse[2209]: pulse-server 0x1100df0: [Contrôle du volume PulseAudio] ERROR command:87 (EXTENSION) tag:14 error:19 (Operation not supported)
déc 30 23:55:02 desktop pipewire-pulse[2209]: pulse-server 0x1100df0: [Contrôle du volume PulseAudio] ERROR command:87 (EXTENSION) tag:15 error:19 (Operation not supported)
déc 30 23:55:02 desktop pipewire-pulse[2209]: pulse-server 0x1100df0: [Contrôle du volume PulseAudio] ERROR command:87 (EXTENSION) tag:17 error:19 (Operation not supported)
déc 30 23:55:02 desktop pipewire-pulse[2209]: Failed to mlock memory 0x7fbff6520000 32832: This is not a problem but for best performance, consider increasing RLIMIT_MEMLOCK

@bbigras try to add both your user and gdm's user to the audio group

@bbigras try to add both your user and gdm's user to the audio group

It works. Thanks @ilya-fedin !

I am having a problem where no app detects pulse-bridge, even if I start it manually. Everything just prints "connection refused".

I am having a problem where no app detects pulse-bridge, even if I start it manually. Everything just prints "connection refused".

I am having a problem where no app detects pulse-bridge, even if I start it manually. Everything just prints "connection refused".

There's no pulse-bridge anymore, there's only pipewire-pulse

I am having a problem where no app detects pulse-bridge, even if I start it manually. Everything just prints "connection refused".

There's no pulse-bridge anymore, there's only pipewire-pulse

@pushqrdx I'm hitting this as well, sound is audible but KDE audio configuration doesn't work. qjackctl works fine.

@pushqrdx I'm hitting this as well, sound is audible but KDE audio configuration doesn't work. qjackctl works fine.

pacmd also aborts with No PulseAudio daemon running, or not running as session daemon.. For some reason I have neither pipewire-pulse nor pulse-bridge in my path with pipewire installed (I only find pipewire, pipewire-media-session and some pw-* tools).

pacmd also aborts with No PulseAudio daemon running, or not running as session daemon.. For some reason I have neither pipewire-pulse nor pulse-bridge in my path with pipewire installed (I only find pipewire, pipewire-media-session and some pw-* tools).

pacmd is hardcoded to work only with pulseaudio
https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/357

pacmd is hardcoded to work only with pulseaudio
https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/357

For some reason I have neither pipewire-pulse nor pulse-bridge in my path with pipewire installed

   ps aux | grep pipewire-pulse
ilya      1125  0.0  0.3  96388 18744 ?        Ssl  12:30   0:00 /nix/store/pl34m73jxmy2h495a8xfbc1pc82crmy5-pipewire-0.3.18-pulse/bin/pipewire-pulse
ilya      5624  0.0  0.0   6452  2240 pts/0    S+   13:29   0:00 /nix/store/134fdr0yrl4wgrrasxn9d3s8vzcm5lxq-gnugrep-3.6/bin/grep --color=auto pipewire-pulse

For some reason I have neither pipewire-pulse nor pulse-bridge in my path with pipewire installed

   ps aux | grep pipewire-pulse
ilya      1125  0.0  0.3  96388 18744 ?        Ssl  12:30   0:00 /nix/store/pl34m73jxmy2h495a8xfbc1pc82crmy5-pipewire-0.3.18-pulse/bin/pipewire-pulse
ilya      5624  0.0  0.0   6452  2240 pts/0    S+   13:29   0:00 /nix/store/134fdr0yrl4wgrrasxn9d3s8vzcm5lxq-gnugrep-3.6/bin/grep --color=auto pipewire-pulse

Pipewire 0.3.19 was recently released. The bad news is that the configuration format changed, which will require some packaging changes. The good news is that mSBC is working wonderfully if you're willing to apply a kernel patch. Besides enabling pipewire and enabling bluez5.msbc-support in /etc/pipewire/media-session.d/media-session.conf, my configuration is
  hardware.bluetooth.hsphfpd.enable = true;
  hardware.enableRedistributableFirmware = true; # don't know if this is needed
  boot.kernelPackages = pkgs.linuxPackages_5_9;
  boot.kernelPatches = [
    { name = "Bluetooth-btusb-Always-fallback-to-alt-1-for-WBS";
      patch = /etc/nixos/patches/Bluetooth-btusb-Always-fallback-to-alt-1-for-WBS.diff;
    }
  ];

where the patch is available at<EMAIL_ADDRESS>

Pipewire 0.3.19 was recently released. The bad news is that the configuration format changed, which will require some packaging changes. The good news is that mSBC is working wonderfully if you're willing to apply a kernel patch. Besides enabling pipewire and enabling bluez5.msbc-support in /etc/pipewire/media-session.d/media-session.conf, my configuration is
  hardware.bluetooth.hsphfpd.enable = true;
  hardware.enableRedistributableFirmware = true; # don't know if this is needed
  boot.kernelPackages = pkgs.linuxPackages_5_9;
  boot.kernelPatches = [
    { name = "Bluetooth-btusb-Always-fallback-to-alt-1-for-WBS";
      patch = /etc/nixos/patches/Bluetooth-btusb-Always-fallback-to-alt-1-for-WBS.diff;
    }
  ];

where the patch is available at<EMAIL_ADDRESS>

There are sample config files in the repo so changing the current module to generate a config in the new format shouldn't be too difficult. What is unclear to me is how the new config file relates to the /etc/pipewire-media-session.d/with-* files that were used to enable the compat modules. I'd like to update this ASAP for stability reasons as well (there are a bunch of very regularly occuring crashes in 0.3.18 that have been fixed in 0.3.19 AFAIK) but unfortunately I'm tied up with other things for the next few days.

I asked it at https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/548. It's a peculiar configuration format: you declare "bundles" in /etc/pipewire/media-session.d/media-session.conf, but a given bundle is only enabled if a file with the same name as the bundle exists in /etc/pipewire/media-session.d/

I asked it at https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/548. It's a peculiar configuration format: you declare "bundles" in /etc/pipewire/media-session.d/media-session.conf, but a given bundle is only enabled if a file with the same name as the bundle exists in /etc/pipewire/media-session.d/

Looks like they fixed the logind ACL race condition and the audio group workaround shouldn't be needed with 0.3.19

Looks like they fixed the logind ACL race condition and the audio group workaround shouldn't be needed with 0.3.19

Here's a subpar generation function that generally works for everything except objects (though you can see the subpar attempt). Not even sure how the language is even structured, so the quoting is left for the user to add.
  mkSPAValueString = v:
    if      builtins.isList       v then "[${lib.concatMapStringsSep " " mkSPAValueString v}]"
    else if lib.types.attrs.check v then
      "{${lib.concatStringsSep " " (mkSPAKeyValue { _SPA_DUP = v._type or "" == "_SPA_DUP"; } v)}}"
    else lib.generators.mkValueStringDefault {} v;

  mkSPAKeyValue = { _SPA_DUP ? false }: attrs: map (def: def.content) (lib.sortProperties
    (lib.mapAttrsToList
      (k: v:
      let
        keyValue = v': "${lib.escape ["="] k} = ${mkSPAValueString (v'._content or v')}";
      in lib.mkOrder (v._priority or 1000)
        (if _SPA_DUP
        then lib.concatMapStringsSep " " keyValue (v._content or [])
        else keyValue v))
      attrs));

  toSPAJSON = attrs: lib.concatStringsSep "\n" (mkSPAKeyValue {} attrs);

Here's a subpar generation function that generally works for everything except objects (though you can see the subpar attempt). Not even sure how the language is even structured, so the quoting is left for the user to add.
  mkSPAValueString = v:
    if      builtins.isList       v then "[${lib.concatMapStringsSep " " mkSPAValueString v}]"
    else if lib.types.attrs.check v then
      "{${lib.concatStringsSep " " (mkSPAKeyValue { _SPA_DUP = v._type or "" == "_SPA_DUP"; } v)}}"
    else lib.generators.mkValueStringDefault {} v;

  mkSPAKeyValue = { _SPA_DUP ? false }: attrs: map (def: def.content) (lib.sortProperties
    (lib.mapAttrsToList
      (k: v:
      let
        keyValue = v': "${lib.escape ["="] k} = ${mkSPAValueString (v'._content or v')}";
      in lib.mkOrder (v._priority or 1000)
        (if _SPA_DUP
        then lib.concatMapStringsSep " " keyValue (v._content or [])
        else keyValue v))
      attrs));

  toSPAJSON = attrs: lib.concatStringsSep "\n" (mkSPAKeyValue {} attrs);

I am having issues with an electron app (teams) not detecting any audio output, inputs are detected just fine. Other applications (firefox, mpv) can output audio just fine too.
Any way I can debug this? I guess something goes wrong during discovery?

Teams is working fine here. What does it look like in pavucontrol or one of the numerous JACK patchbays? (carla, patchage)

It appears briefly (as "chromium"), but disappears after a few seconds. The weird thing is I can make a test call which start playing the ringtone (which works) and when the other end accepts the call, it gives me a notification there is no speaker detected... (without any sound).I looked in patchage but it doesn't appear at all there.
I'll try to take a look at how teams performs its audio discovery.

It appears briefly (as "chromium"), but disappears after a few seconds. The weird thing is I can make a test call which start playing the ringtone (which works) and when the other end accepts the call, it gives me a notification there is no speaker detected... (without any sound).

I'll try to take a look at how

For me it obediently follows the defaults I have set in pavucontrol. Try nuking ~/.config/pipewire-media-session/* and then setting the default devices in pavucontrol before launching anything that plays audio. That fixed some applications reverting to the wrong soundcard for me.

I've updated the OP for the new config format. Please test the linked PR if you can and report possible problems. A lot of the old upstream issues have been fixed since the time of listing them in the OP so let me know if you encountered them before and they have disappeared now so I can remove them from the list.

Update: the problem originated in wrong audio driver settings. With the correct driver settings, things work perfectly :ok_hand:

I get a lot of hiccups when using ardour on my macbook air even without plugins & only one track. With jack things are running very smoothly. I think it may be helpful if there were options to change the global framerate & buffersize to try getting it more stable. Or does pipewire require more resources than jack and isn't suited for such low power devices anyway?

I tested the PR, it works great! Many thanks @jansol :) I had to use properties = { "bluez5.msbc-support" = true; "bluez5.sbc-xq-support" = true; }; instead of properties.bluez5 = { msbc-support = true; sbc-xq-support = true; } to enable the Bluetooth flags, though.

I wanted to try this, so I cherrypicked the commits onto nixos-unstable.
However, no inputs or outputs were detected in pavucontrol.
Here is the configuration I tried:
 security.rtkit.enable = true;
 services.pipewire = {
   enable = true;
   pulse.enable = true;
   alsa.enable = true;
   alsa.support32Bit = true;
 };
 services.pipewire.pwms = {
   enable = true;
   config = {
     modules = "with-pulseaudio";
   };
 };

What am I missing?

@underscore-j Try removing the services.pipewire.pwms.config part. I believe setting config replaces the whole default config file with your version.

@underscore-j Try removing the services.pipewire.pwms.config part. I believe setting config like that replaces the whole default media-session.conf file with your version.

Unfortunately, that didn't help. Still nothing

Updating to 0.3.21 from that PR fixed coredumps for me.
Also it fixed this issue:

If set volume to 0% with alsamixer, it is impossible to revert the volume to normal with it, but amixer works:

Finally i have a working audio setup on linux, without that much pain, i can actually do stuff now, yay~

pulseeffects segfaults at startup on NixOS unstable with pipewire pulse shim enabled.

Could you test if #112591 fixes that?

@jtojnar Yeah it does.

I've found an issue I haven't seen discussed here - apps built from AppImages.
An example being rambox-pro, they seem to completely ignore the PipeWire implementation and play through my inbuilt laptop speakers. I've changed the outputs from GNOME sound manager to my headset but they're being ignored.
Anyone have any ideas on this one? Would love to get this working properly.
P.S. Yes, I have JACK disabled so it's not that causing problems!

"Ignore the PipeWire implementation" sounds fishy. A patchbay should still show the app and what it is connected to. On the other hand the default routes in pipewire sometimes don't "stick" like you'd expect them to as it tries very hard to put them back to the output they were connected to previously. Try stopping the pipewire service, deleting ~/.config/pipewire-media-session/restore-stream and restarting the service.

"Ignore the PipeWire implementation" sounds fishy.

Maybe he is using old pipewire version with the libpulse shim?

"Ignore the PipeWire implementation" sounds fishy.

Maybe he is using old pipewire version with the libpulse shim?

root@thinkpad> nix-shell -p pipewire                                      ~
[nix-shell:~]# pipewire --version
pipewire
Compiled with libpipewire 0.3.18
Linked with libpipewire 0.3.18

As I say - this only affects (so far) AppImage based apps - I haven't yet figured out why. The audio does still play but a few observations:

AppImage based apps don't show up under "Volume Levels" under GNOME Settings - Sound options. (either with PipeWire or Pulse)
Audio for ALL apps works with both but with Pulse the default output device is respected by AppImage based apps meanwhile with PipeWire they are not and the inbuilt laptop speakers in my case are used as default despite not being set as the default in any settings at all.
Chrome (for example) works flawlessly either way - with either Pulse or PipeWire and respects the default output being set in GNOME settings.

The block I'm using to test here is:
{ pkgs, ... }:

{
  environment.systemPackages = with pkgs; [
    pavucontrol
  ];

  hardware.pulseaudio.enable = false;

  programs.dconf.enable = true;
  security.rtkit.enable = true;

  services.pipewire = {
    enable = true;
    alsa = {
      enable = true;
      support32Bit = true;
    };
    pulse.enable = true;
  };

  users.extraUsers.chrisaw.extraGroups = [ "audio" ];
}

Hopefully this provides some useful context to the issue I'm seeing here.

Linked with libpipewire 0.3.18

Yeah, this is the old version with libpulse shim. New versions are emulating pulse socket.

I haven't yet figured out why

It's worth to read terminal output and tell names of these apps so that we can know which libraries they using at least

In addition to AppImage apps (I tested multiple versions of osu!lazer), Wine's ALSA backend doesn't show up in pipewire and instead grabs the ALSA device for itself.

0.3.21 is up on the nixos-unstable channel and should fix most of the issues mentioned here recently, please do update and verify if you were affected. (just in time for upstream to release 0.3.22 :stuck_out_tongue: )

0.3.21 really works a way better, but pipewire stopped to work in interactive shell, I can't even check version:
   pipewire --version
[W][000001001.182000][main.c:76 load_config()] daemon 0x7fff94eaccb0: error loading config '/etc/pipewire/pipewire.conf': No such file or directory
[E][000001001.182115][main.c:394 main()] failed to load config: No such file or directory

systemd service works somehow even though no path to config is specified in the unit :thinking:

@ilya-fedin the 0.3.21 PR changes the nixos module so it doesn't put pipewire.conf into /etc at all and just sets an environment value to point to the file instead.This feature was removed upstream so from 0.3.22 it will be the way it used to again (since there will be a lot more config files).

Is there a way to make pipewire to remember using headphones as output instead of speakers?

@suhr if you set a default output in pavucontrol it should remember that. If not, remove ~/.config/pipewire/media-session.d/restore-stream to remove the application-specific cached output associations and set the default in pavucontrol again.

The environment variable thing doesn't work for me. pipewire and pipewire-pulse both complain that they can't find configuration files and refuse to start up.

The environment variable is only set for the systemd service, but you can get its value from /etc/systemd/user/pipewire.service.d/overrides.conf if you would like to see what it's set to.

@chvp You need to enable it with systemctl --user enable --now pipewire.service (run as user).

Yeah, it's from journalctl output that I got that, not from trying to run the binaries manually. systemctl --user cat pipewire{,-pulse}.service contained the correct env variable as well, so I'm not sure what was going wrong. This was after a clean reboot.

there was an issue yesterday with a pipewire update having been directly pushed to master. please make sure you're running pipewire 0.3.21 and NOT 0.3.22 which might still be in the latest nixos-unstable, even though it's been reverted in master.

Ah, I usually track unstable-small, so that might be it. I'm not at a machine I can test  on right now, but I'll check tomorrow.

@collares Pipewire sets the output in ~/.config/pipewire-media-session/default-routes, but after a reboot it uses line out again.
Additional info: in pavucontrol Line Out has (plugged in) after it, while Headphones does not. Maybe pipewire thinks that headphones are not connected, even though they are.

@suhr If this is https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/533 it was fixed (half an hour ago!) in master

Oh, so I have to wait until 0.3.23...

:eyes:  #114482

0.3.23 and jack no longer works damn... it even prevents all kinds of audio from the system

Renoise via JACK works fine here, try again with the latest version of #114482?

Renoise via JACK works fine here, try again with the latest version of #114482?

Seems to be an issue on my side connected to pipewire-media-session.

rtkit has a limit to rt priority by default, set to 20, pipewire uses 88, so it is being limited.
Guess PR is needed, to make it configurable through the rtkit module?
Increasing the limit requires a service override like this:
  security.rtkit.enable = true;
  systemd.services.rtkit-daemon.serviceConfig.ExecStart = [
    ""
    "${pkgs.rtkit}/libexec/rtkit-daemon --our-realtime-priority=95 --max-realtime-priority=90"
  ];

I managed to fix the issue for me, the problem was linked to pipewire-media-session and all I had to do was just comment this line in /etc/pipewire/pipewire.conf
context.exec = {
...
Line below should be commented out
#"/usr/bin/pipewire-media-session" = { args = "" }
...
}
the /usr/bin/pipewire-media-session one

The NixOS module was already taking care of the media-session exec line so no problem here. And now upstream has it commented out by default anyway.

It is recommended to be started through the systemd service.

In #114482 how do I set pulse.min.req = 32/48000 in pipewire.config.pipewire-pulse? If I set the value as a string, it is written with quotes in /etc/pipewire/pipewire-pulse.conf and PW doesn't pick that up.

In #114482 how do I set pulse.min.req = 32/48000 in pipewire.config.pipewire-pulse? If I set the value as a string, it is written with quotes in /etc/pipewire/pipewire-pulse.conf and PW doesn't pick that up.

That is currently not possible since nix fails to parse 32/48000 as a number and decides it's a string instead. It would be so nice if pipewire could just use fully conformant JSON as its config but for now it seems we just gotta pile hacks upon hacks to make config generation somehow work. Ironically there have been quite a few upstream commits recently about allowing writing various config entries in quotes. Guess this one just wasn't part of the list.

I thought PIpewire was supposed to accept every JSON file (up to ordering issues) as well as the abbreviated SPA JSON format. Is that not the case? If it isn't, fixing it upstream would be best.

AFAIK it kind of tries to, yes. But there is the matter of context.objects with its duplicate keys that while technically conformant, is strongly recommended against and straight up not supported in Nix (it merges or replaces duplicate keys instead) so I'll try to bring back some form of the _SPA_DUP hack to work around that. The fractional representation of 32/48000 is not valid JSON so not accepting that in quotes would be an upstream bug.

i talked to @wtay about this in irc the other day and they expressed interest in making context.objects, modules, etc an array instead of using duplicate keys.
another issue with the nixos module is that there's no way to remove default modules, for instance. in the current config format, setting context.modules.<name> to null enables that module, the only way to disable is to remove it from the config entirely.
if it was turned into an array, we would be able to generate that config, but we still have the issue of removing defaults. i think in that case if we could optionally override context.modules instead of merging it, that would be fine (something like mkOverride)

Changing context.objects to an array is excellent news! And makes a lot of sense conceptually anyway. If that is the case then I'll hold off of the _SPA_DUP hack for now.
Removing default modules... yes, that is currently not possible and is something that we'll probably have figure out sooner than later. I'm not sure how to go about it though. One way would be to change null values to something else when loading the JSON into the module, such as { _enable = true; } and if an object has an _enable field, only write that object if the field is set to true. Not very pretty but it would probably work.

if context.modules becomes an array then that won't work anyway. we would need a way to exclude the default modules from the array, either by filtering them out or just providing a way to override instead of merge the array (i prefer the second, it's much cleaner).

any idea when the volume controls in KDE might work? otherwise pipewire works perfectly.

@yourfavouriteuncle Try setting the default device with pavucontrol (it's the green circle with "Set as fallback" as tooltip). Does that make KDE volume controls work?

@collares the "set as fallback" is set

Arrays

Here we gooooo :tada:
https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/90b0410280da65f5b8f879da7f204735b6d27cb1

Has anyone got context.properties in pipewire.conf to change properly? I set my clock rate and quantum but pipewire doesn't listen to it at all

I feel like I have the same problem, but only in Pulseeffects.

Mine with whats below is doesn't change anything
   config.pipewire = {
      context.properties = {
        "link.max.buffers" = 16;
        "core.daemon" = true;
        "core.name" = "pipewire-0";
        "default.clock.rate" = 96000;
        "default.clock.quantum" = 128;
        "default.clock.min-quantum" = 128;
        "default.clock.max-quantum" = 128;
      };
    };

I'm glad that I can say I've been using pipewire quite successfully for past few days. Both as a pulse audio as well as jack audio replacement. Finally I can have both running reasonably well.

Alright so my issue is solved by using environment.etc to force override pipewire.conf

@cidkidnix you don't have context.properties quoted. you need
config.pipewire = {
  "context.properties" = {

ah I see that now, thank you. Haven't been using this module for quite awhile, been using one that was a bit easier initially for me

:tada: #116811
@fufexan I asked wtay on IRC and the rate should work when presented as a string in the config file (i.e. quoted with " "). If it is quoted correctly in the file(s) in /etc/pipewire generated by the module but pipewire does not pick it up that's an upstream bug.

The update to version 0.3.24 broke pipewire-pulse for me and I couldn't figure out why. Now that "context.modules" is an array, if you customize its values you have to also add the defaults specified in /etc/pipewire/pipewire-pulse.conf (it might be possible to use override in this case).
Here's the commit which adapted my configuration to the new version.

I hope you excuse me posting this here, but I am really frustrated with PipeWire on NixOS now. It has worked for some time, but stopped working and I don't understand why. If anyone is willing to help me, please head over to Discourse, at https://discourse.nixos.org/t/pipewire-pulse-cant-create-server-for-unix-device-or-resource-busy/12084

@lorenzleutgeb Your pipewire is not up to date, and there has been a lot of changes to the config both upstream and in the way the nixos module handles it in the past couple of versions so most likely your config is broken. Actually I remember coming across a similar problem while packaging 0.3.24. You can try your luck with overriding the PIPEWIRE_DEBUG environment variable and checking the logs from the pipewire daemon.
Most likely you are overriding something that gets replaced rather than merged with the defaults and as a result your config is missing some required options. Hard to say without seeing the relevant part of your configuration.nix though. #118154 should improve the situation.

@yourfavouriteuncle try manually installing kmix and plasma-pa, the problem seems to be that pipewire doesn't cause them to be installed.

Finally I got msbc working (the 16kHz mono codec for SCO connections, beyond the 8kHz cvsd). The option of msbc-support moved and in 0.3.24 it's in a different place than it was before. What I use:
  services.pipewire.enable = true;
  services.pipewire.pulse.enable = true;
  services.pipewire.media-session.config = {
    media-session = {
      "session.modules".default = [ "flatpak" "portal" "v4l2" "policy-node" "bluez5" ];
    };
    bluez-monitor.properties = {
      "bluez5.sbc-xq-support" = true;
      "bluez5.headset-roles" = [ "hfp_ag" ];
    };
    bluez-monitor.rules = [
      {
        matches = [ { "device.name" = "~bluez_card.*"; } ];
        actions = {
          "update-props" = {
             "bluez5.reconnect-profiles"  = [ "hfp_hf" "hsp_hs" "a2dp_sink" ];
             "bluez5.msbc-support" = true;
          };
        };
      }
      {
        matches = [
         { "node.name" = "~bluez_input.*"; }
         { "node.name" = "~bluez_output.*"; }
        ];
        actions = {
          "update-props" = {
             "node.pause-on-idle" = false;
          };
        };
      }
    ];
  };

After you set the profile to headset in pulseaudio:
$ pactl set-card-profile bluez_card.C9_50_76_E5_8D_58 headset-head-unit

you can check the codec used by:
$ pw-dump |grep bluez5.codec
        "api.bluez5.codec": "mSBC",
        "api.bluez5.codec": "mSBC",

First, thank you all for doing this work. A large part of why I switched to nixos was specifically so I could fearlessly experiment with my audio setup so I will be following this carefully.

How to enable logging:
# see https://docs.pipewire.org/#Logging for documentation on log levels
services.pipewire.config.pipewire."context.properties.log.level" = 5;

I noticed that a couple issues (i3status-rust reported the wrong output's volume, volume control did not correspond to the correct output) were fixed when I removed sound.enable = true.

Finally, I'd appreciate a link to any configs from people who use a DAC+Amp (e.g. a Chord Mojo) via USB.

pipewire 0.3.25 has been released https://gitlab.freedesktop.org/pipewire/pipewire/-/releases/0.3.25

And it's in master now: #118701
Updated the OP again with up to date config examples.
@viric the bluez module is already included in the with-pulseaudio list which gets loaded when pulse emulation is enabled so no need to add it to the default modules.

@viric thank you so so much for posting your configuration.
I started playing around with pipewire in february (after having just gotten a new laptop) specifically to have mSBC support, but I never got anything to work, I didn't have sound at all, so I gave up on it.
Today I copy-pasted your configuration and it works perfectly. Thank you!

if there are helpful configuration snippets a good place to put that is on the wiki

Guys, I wonder if We already can use pipewire only? without needed pulse or alsa compability? all just pipewire.

No, you need all applications to use pipewire API directly for that. I don't know any application except of PulseEffects that speaks on pipewire API.

I've just knew a friend that have deadbeef pipewire option in sound output, which I don't.

if there are helpful configuration snippets a good place to put that is on the wiki

Ok, I made https://nixos.wiki/wiki/Pipewire

I have moved the page to the proper name PipeWire, and added a low latency configuration example and a bit of walkthrough. I may add further sections like tweaking rtprio and other stuff.

Correction to the wik since I don't think I have an account there: there are module options for the media session config files (mentioned near the end of the OP):
services.pipewire.media-session.config.$basename so for the example on the wiki it would be services.pipewire.media-session.config.alsa-monitor = {};

Thanks, I will update accordingly.
Any other suggestions?

Basically everything that I have written down in the OP are things that I've come across multiple times by now and should probably be part of the wiki page. Mentioning the fact that arrays are replaced, not merged in Nix is pretty important since it can have unintended consequences when people copy & paste snippets from the wiki without being completely aware of what they are doing.
Bluetooth support is currently one of the big selling points of pipewire so everything related to setting that up would be good to have down in the documentation. (i.e. the mSBC setup for slightly better sound quality in calls) Maybe also some explanation of profile switching (A2DP vs HSP/HFP) with pavucontrol or some other tool.
And the Pro Audio profile for multichannel interfaces + null sinks for customizing, even if one isn't quite doing audio production work would be good too (for example the Komplete Audio 6 confuses pulse applications to no end so this is a relatively elegant workaround).
One thing that's soon obsolete from the OP is the script that uses jack_connect to connect the null sinks to the actual audio interfaces: pipewire 0.3.26 adds a pw-link utility which seems to do the same but without pulling in JACK packages: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Migrate-JACK#jack_connect-jack_disconnect so if you add that part, please do it with pw-link instead of jack_connect. I'll update the script in the OP as soon as the nixos package updates to 0.3.26
The manually-run script isn't exactly the most elegant solution but I guess it could be set up to run automatically when the DE starts (I haven't bothered figuring out how yet). Eventually I hope to get wireplumber packaged, which AFAIK should allow for automatically connecting nodes via lua scripts.

I have added what's in the OP slightly reworded, but there is still missing info. For example, steps to enable bluetooth or jack-specific configs. Routing audio with patchbays like Carla (I can't get Catia to work with PW) can also be useful to cover.
The page focuses on audio right now, but I'd like to ask Wayland users to add info about video sharing (if needed).
I will add more info in the following days, so if you have suggestions and no wiki account I'll happily add those.

Updated my example script for connecting nodes to use pw-link instead of jack_connect. This is the path of least dependencies once #120833 lands. The wiki has the script slightly wrong, so please update that @fufexan

having trouble starting PW:
May 01 13:04:33 hermes systemd[3090]: pipewire.socket: Failed to open /nix/store/a1zhla51z69dxc3ydw6j0nll1gkwnsni-pipewire-0.3.21/lib/systemd/user/pipewire.socket: No such file or directory

Audio output in mumble has been problematic since today for me. Could be related to the 0.3.26 update, but someone on the Pipewire tracker says they see it with 0.3.25 as well.
Basically audio output over ALSA suddenly stops working, if I reapply audio output settings in mumble, without changing anything, it starts working again. Until output suddenly vanishes again. Very annoying.

Good news: Mumbles Pipewire support has been merged, it is working well for me. They have drafted another development snapshot, the last according to IRC. Then in about a month there will be a first release candidate of the 1.4 series.
In the meantime I tried out an UltraStarDX bump #123416, but I am unable to get any microphone input going. I've opened an upstream issue at https://github.com/UltraStar-Deluxe/USDX/issues/581. Does microphone input work for anyone else?

I can confirm I also have troubles with Volume Up/Down/Mute keys on latest KDE Plasma (nixos-unstable 83d907fd760). Moreover, with pulseaudio I have an "audio" icon in the systray in KDE:

but it is not present with Pipewire... For now my only option to change volume is to run pavucontrol. Any idea how to solve that?

The volume icon is provided by a separate application, such as kmix or plasma-pa (default) however the plasma module currently does not install either of those when pulseaudio is disabled. Installing and launching one of them manually restores the volume icon. There was a mention of this in a plasma-related issue somewhere, can't remember which issue though.

0.3.28 is out!

@jansol Whoo, installing both kmix and plasma-pa made both volume keys and applet back O_o (not sure if only both are required or not) The fact that volume keys work again is just a coincidence or it can actually be linked? Shouldn't we add them back by default like what happens with pulseaudio? Also, this is only for KDE users right?

I made https://github.com/NixOS/nixpkgs/pull/123211 to add plasma-pa when using pulseaudio support in pipewire.

@mdevlamynck Cool, thanks a lot! Also, any idea how to get the pactl command (can be useful for instance to check that pipewire is used instead of pavucontrol with pactl info)? I know it's provided by "pulseaudio", but I'm afraid to have conflicts with pipewire.

@tobiasBora The two packages serve the same purpose so having both installed is largely pointless. kmix additionally provides a windows-like per-application volume control view. And yes they also handle volume keys. And yeah only applies to KDE, more specifically plasma users.
Pavucontrol is just a colume controller that connects to pipewire's fake pulse server with no problems. You can use pw-mon to see pavucontrol connecting to pipewire in real time. Or pw-top to get a quick overview of everything. For a more approachable view there is carla/catia/patchage (graphical patcbay tools made for JACK, they work with pipewire's JACK emulation just fine)

@tobiasBora I currently have pulseaudio (the package) installed alongside pipewire with no problems. Before pipewire added the configuration file way of adding virtual sinks, I used pactl to load modules, and it worked flawlessly. I imagine adding it to check info isn't dangerous

Most pactl uses are covered by pw-cli these days if you really want to avoid installing the pulseaudio package.

kmix is a generic application with a generic tray icon. It supports pulse and ALSA. plasma-pa is a Plasma applet (and it also can control applications as well IIRC).

@jansol @iagocq Thank you soo much for these clarifications, it is really helpful! Everything (or nearly) is clear now, thanks a lot!
Concerning kmix, I had some annoying "bugs": when I was increasing the sound from the applet (scroll on the applet), the sound was played on the main internal card instead of in the bluetooth device. So I will use plasma-pa instead I think, I also find it clearer. Concerning, pw-top/pw-mon, it's only to get information right, I guess you can't change anything from there.
But whooo I'm a bit lost: pipewire merges both Jack and Pulseaudio entries together (so pulseaudio appears in jack)? I was thinking that jack & pulseaudio protocols were still handled in parallel, but firefox appears in QJackctl:

and pavucontrol (so pulseaudio protocol) also list them:

Everything goes via pipewire protocol to pipewire daemon in the end. For PA, conversion is done in pipewire-pulse. For Jack, in jack replacement libraries.

Ok, super cool, thanks a lot. And there is no graphical applications (like pavucontrol) for the pipewire protocol directly? I can only change volume/connections via indirect interfaces to pulseaudio/jack?

I don't know any at least :(

The only one I've heard of so far is Helvum. Anyway you can think of the pulseaudio and JACK emulation layers as "windows" into the same pipewire server. Pulseaudio applications see everything in there that a normal pulse server could have, JACK applications see that, and a few more things since the JACK API supports some things that pulse does not. Pipewire handles them all largely the same under the thin per-API facade.

Cool, thanks a lot! (JACK applications can't deal with volume however I guess) I updated the wiki with everything I learnt today, thanks a lot!

AFAIK pactl comes with pulseaudio, not pavucontrol

@tobiasBora thanks for the additions! I made some changes to them, also reflecting @ilya-fedin's remark.

Looks like there's a pre-release of WirePlumber: https://gitlab.freedesktop.org/pipewire/wireplumber/-/releases/0.3.95
Want to try it :hmm:

Looks like there's a pre-release of WirePlumber: https://gitlab.freedesktop.org/pipewire/wireplumber/-/releases/0.3.95
Want to try it thinking

Be my guest. The easiest way to go about it is probably to just copy the pipewire-media-session module verbatim and replicate the config json generation step from the pipewire package in a separate wireplumber package (which adds a dependency on pipewire proper for spa-json-dump, but that is probably required anyway so no big deal). Ask away if you encounter problems with that. As for how to best handle the Lua side of things, I have no idea how to best deal with that.
I'm also interested in playing around with the above mentioned Helvum but that involves figuring out one of the many ways to package Rust applications, which is something I've been putting off for a long time already...

@jansol regarding Helvum, I almost got it working. One of the roadblocks though, seems to be #124163.

@jansol regarding Helvum, I almost got it working. One of the roadblocks though, seems to be #124163.

I got it working by adding clang to the buildInputs, for example this overlay works for me:
self: super: {
  helvum = self.rustPlatform.buildRustPackage rec {
    pname = "helvum";
    version = "git";
    src = self.fetchFromGitLab {
      domain = "gitlab.freedesktop.org";
      owner = "ryuukyu";
      repo = "helvum";
      rev = "24fd54affead16f1ed371935fff2c02ae4a50038";
      sha256 = "sha256-LtcPsde/h9rw6OoZfRlIEtzrMIPJDuYJRm/ncgWCgGM=";
    };

    cargoSha256 = "sha256-pCF7iMlu3Ds8NjUfo895fhzFmVXhxnJ/KPQDoFPITi0=";

    nativeBuildInputs = [
      self.pkg-config
      self.clang
    ];
    buildInputs = [
      self.gtk4
      self.glib
      self.pipewire
    ];

    LIBCLANG_PATH = self.llvmPackages.libclang.lib + "/lib/";
  };
}

Thanks, @BurNiinTRee, adding glib fixed it. I have opened a PR
#124274 that adds Helvum to nixpkgs. I'd be thankful if anyone wanted to review it.

I'm having issues with steam after having switched to pipewire. I used
pw-steam = pkgs.steam.override {
  extraLibraries = pkgs: with pkgs; [
    pipewire
  ];
};

and that got rid of the immediate error (about missing libpipewire), but it's still not launching and I'm not sure if it's related to pipewire or not. Stuck on "Connecting Steam account" and doesn't make progress.

That's a known problem with the steam beta client and not related to using pipewire as your audio server: #124308. A fix is apparently in the works upstream. Meanwhile you can work around it with the override you posted or by reverting to the stable version of the steam client by deleting ~/.steam/steam/package/beta.

Updated OP to mention the freewheeling driver (from #125311) that has to be included manually when creating custom nodes in the module config.

The sound.enable = false seems subpar, are there any plans to do anything about that?

libpipewire-module-filter-chain seems to be missing.

@YellowOnion the pipewire version in the release channels is still too old to have it, #125311 adds it.
@Ericson2314 agreed, it is quite misleading. I don't know anything about ALSA though so someone who does will have to figure out a better way to handle that.

Most basic additions to configuration.nix, this should be enough for most people:
  # Remove sound.enable or turn it off if you had it set previously, it seems to cause conflicts with pipewire
  #sound.enable = false;

  # rtkit is optional but recommended
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    # If you want to use JACK applications, uncomment this
    #jack.enable = true;

    # 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;
  };

When i add this to my configuration.nix and try rebuilding i get
error: The option `services.pipewire.alsa' defined in `/etc/nixos/configuration.nix' does not exist. (use '--show-trace' to show detailed location information) building Nix... error: The option `services.pipewire.alsa' defined in `/etc/nixos/configuration.nix' does not exist. (use '--show-trace' to show detailed location information) building the system configuration... error: The option `services.pipewire.alsa' defined in `/etc/nixos/configuration.nix' does not exist. (use '--show-trace' to show detailed location information)
I get similar errors also for pulse and jack, what's happening? how can i fix this?

Are you still on NixOS 20.09? These options only exist on NixOS 21.05 and NixOS unstable.

Are you still on NixOS 20.09? These options only exist on NixOS 21.05 and NixOS unstable.

Oh... makes sense, thanks!

The only feature I miss after migrating from PulseAudio to PipeWire is a system-wide service.  The system-wide service of PipeWire is disabled by default.  It can be enabled by setting the flag "-Dsystemd-system-service=enabled".
System-wide service is a rare use case.  But some people may consider it necessary.  It would be nice if a system-wide service option is provided by the services.pipewire module.

I'm currently dealing with the same issue as OP is here. That post is regarding Fedora but I'm getting the exact same errors and so forth. Sound buttons not working. This is after adding boilerplate from the wiki
[root@nixos:~]# pipewire --version
pipewire
Compiled with libpipewire 0.3.30
Linked with libpipewire 0.3.30

According the OP from that post it was a bug introduced in a recent update? How do I modify the boilerplate to control the version I'm using please?

0.3.31 is now merged (although it hasn't made it into the release channels quite yet)! Bluetooth users should find better compatibility with flaky devices thanks to the added device db. To override the defaults of the db you can write extra rules to the bluez-monitor config. Also note that the bluez5.reconnect-profiles property has been renamed to bluez5.auto-connect in the bluez-monitor rules.
Another new feature particularly relevant to anyone working with professional audio gear is support for Roc, a framework similar to AES67 and Dante. This is unfortunately not supported on NixOS since the toolkit is not packaged yet. If you have an interest in this, chime in on #129567 .

It would be nice if a system-wide service option is provided by the services.pipewire module.

Shouldn't it be that home-manager provides the user one and NixOS the system one? Maybe we can just provide some sort of warning that the system own is probably what one wants.

Also I managed to get my PC to act as a bluetooth "speaker" for my phone, which is a fun feature. Added the relevant part to the example config in the OP,

I'm not sure what happened, but 0.3.31 completely broke HDMI sound output for me. The "Digital Stereo HDMI" profile is missing from the graphics card and the only two available are "Off" or "Pro Audio".

I have the same on one of my laptops. The other is fine.

The HDMI breakage appears to be an alsa problem: problem reported on the pipewire tracker where discussion points towards an alsa-lib issue

Interesting, thanks for the link. I went over the issue tracker earlier but managed to miss it.

Intel Corporation Cannon Point-LP High Definition Audio Controller doesn't show any devices in Pipewire even though the card itself is visible: #130970

0.3.32 is out with a variety of bugfixes: #130982

0.3.33 is out, bluetooth users might be interested in automatic switching between A2DP and HFP depending on whether the microphone is being used: #132883

I thought I'd point out that it looks like Fedora is working on switching from pipwire-media-session to WirePlumber: https://fedoraproject.org/wiki/Changes/WirePlumber

What's the equivalent of pactl set-sink-volume 0 +5%?

but elsewhere on the 'net it seems people are suggesting to keep on using pactl.

Yeah I'd say just keep using pactl if it works. If you really want to know that's probably a question for the pipewire devs rather than this thread

You can use pw-cli, but you need to remember the id of the object, and edit the properties manually, so it's not very convenient. WirePlumber has a tool called wp-ctl that lets you adjust the volume, and otherwise I believe you're supposed to use pactl or another existing tool.

What's the equivalent of pactl set-sink-volume @DEFAULT_SINK@ +5%?

I use pulsemixer --change-volume {+,-}5

Yet more regressions on 0.3.33 for me.
Aug 12 09:43:29 cerulean kernel: usb 5-3: new high-speed USB device number 5 using xhci_hcd
Aug 12 09:43:32 cerulean kernel: usb 5-3: New USB device found, idVendor=046d, idProduct=082d, bcdDevice= 0.11
Aug 12 09:43:32 cerulean kernel: usb 5-3: New USB device strings: Mfr=0, Product=2, SerialNumber=1
Aug 12 09:43:32 cerulean kernel: usb 5-3: Product: HD Pro Webcam C920
Aug 12 09:43:32 cerulean kernel: usb 5-3: Found UVC 1.00 device HD Pro Webcam C920 (046d:082d)
Aug 12 09:43:32 cerulean kernel: input: HD Pro Webcam C920 as /devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:08.0/0000:27:00.3/usb5/5-3/5-3:1.0/input/input28
Aug 12 09:43:32 cerulean pipewire[2081]: ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.2.pcm.front.0:CARD=2'
Aug 12 09:43:32 cerulean pipewire[2081]: ALSA lib conf.c:5111:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
Aug 12 09:43:32 cerulean pipewire[2081]: ALSA lib conf.c:5599:(snd_config_expand) Evaluate error: No such file or directory
Aug 12 09:43:32 cerulean pipewire[2081]: ALSA lib pcm.c:2731:(snd_pcm_open_noupdate) Unknown PCM front:2
Aug 12 09:43:32 cerulean pipewire[2081]: 'front:2': capture open failed: No such file or directory
Aug 12 09:43:32 cerulean pipewire[2081]: adapter 0x5563cc422e00: can't get format: No such file or directory
Aug 12 09:43:32 cerulean pipewire[2081]: usage: node.name=<string>
Aug 12 09:43:32 cerulean pipewire-media-session[2082]: error id:28 seq:5123 res:-22 (Invalid argument): usage: node.name=<string>

https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1502

Needs https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/0a5a4c046d10c0a53c7d2120a523cc28663ad73b to be applied

Has anyone gotten Catia to work with pipewire yet? Qjackctl works fine here, but Catia fails to connect to JACK and prints this to stderr:
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started

This happens both with and without pw-jack.
I've seen non-NixOS users run Catia successfully, so I'm wondering if this is nixpkgs specific.

0.3.34 is out: #135819
This should fix the issues with devices not showing up, also it adds bidirectional FastStream support for bluetooth headsets so sound quality should no be a bit better when the microphone is used (if the headset supports that codec at least).

Looking forward to this getting to master.

Thank you for #135819, @Kranzes.

It seems like mpd + pipewire is broken. Since the version with a native pipewire backend is yet released, I tried both the pulseaudio and jack emulation. It was denied connection to both. I don't have much knowledge of either though, so I may have made a mistake.  Possibly relevant log Sep 03 17:38:08 nixos mpd[124877]: exception: Failed to enable output "Pulsef" (pulse); pa_context_connect() has failed: Connection refused

mpd with the pulseaudio output when using pipewire's pulseaudio emulation works fine for me, though i hate to say that i wasn't able to get the pipewire native output for mpd to work, adding pipewire to the dependencies of mpd did not work, it is out already on Arch for example...

It seems like mpd + pipewire is broken. Since the version with a native pipewire backend is yet released, I tried both the pulseaudio and jack emulation. It was denied connection to both. I don't have much knowledge of either though, so I may have made a mistake. Possibly relevant log Sep 03 17:38:08 nixos mpd[124877]: exception: Failed to enable output "Pulsef" (pulse); pa_context_connect() has failed: Connection refused

Are you running master on your system? because the unstable channel does not have  0.3.34 yet.

I am on 0.3.34 now, it hit unstable. Still no dice for normal mpd. I did manage to make it work by enabling it via home manager instead though.

On unstable. No audio in Firefox or Chromium. Pipewire 0.3.34. In pavucontrol everything seems normal to me — I have the devices I expect and the profiles I expect. When Firefox is supposed to be playing audio, I don't see it in pavucontrol's playback tab. Help? Firefox 92.0.2 installed using home-manager. With 0.3.33 I had no such issue.

Thats odd, because for me on 0.3.34 everything works fine, mpd, firefox, chromium.

Possibly relevant log Sep 03 17:38:08 nixos mpd[124877]: exception: Failed to enable output "Pulsef" (pulse); pa_context_connect() has failed: Connection refused

make sure mpd runs with the same user pipewire is running with. pipewire/pulseaudio are user-level daemons.

Have anyone figured how to make profile auto switching work? I've tried bluez5.autoswitch-profile=true; with no luck (FF with meet and youtube) - still have to manually switch between a2dp and hsp as meet doesn't detect microphone. I might be doing something wrong though 🤷🏻

I am on 0.3.34 now, it hit unstable. Still no dice for normal mpd. I did manage to make it work by enabling it via home manager instead though.

Is there some troubleshooting I can do? I tried the motherboard's built-in audio device and the problem seems the same. If anyone would like to have a session trying to figure this out on my system via remote desktop, we can do that. https://calendly.com/mightyiam . Alone it would take me much longer to narrow down the issue.

0.3.35 is out, with some workarounds for alsa problems so if you were missing your audio devices try again with #137533

On unstable. No audio in Firefox or Chromium. Pipewire 0.3.34. In pavucontrol everything seems normal to me — I have the devices I expect and the profiles I expect. When Firefox is supposed to be playing audio, I don't see it in pavucontrol's playback tab. Help? Firefox 92.0.2 installed using home-manager. With 0.3.33 I had no such issue.

Still the case with 0.3.35 :cry:
Same with Chromium.
Sep 19 21:28:59 mightyiam-desktop pipewire-media-session[2992]: GetManagedObjects() failed: org.freedesktop.DBus.Error.ServiceUnknown
Sep 19 21:29:40 mightyiam-desktop pipewire-pulse[3307]: stream 0x559344832b60: error wrong resource type/version
Sep 19 21:29:40 mightyiam-desktop pipewire-pulse[3307]: client 0x5593447b4650 [PulseAudio Volume Control]: ERROR command:-1 (invalid) tag:18 error:25 (Input/output error)
Sep 19 21:29:40 mightyiam-desktop pipewire-pulse[3307]: stream 0x55934483def0: error wrong resource type/version
Sep 19 21:29:40 mightyiam-desktop pipewire-pulse[3307]: client 0x5593447b4650 [PulseAudio Volume Control]: ERROR command:-1 (invalid) tag:19 error:25 (Input/output error)
Sep 19 21:30:24 mightyiam-desktop pipewire-pulse[3307]: stream 0x55934487af00: error wrong resource type/version
Sep 19 21:30:24 mightyiam-desktop pipewire-pulse[3307]: client 0x559344836c10 [Firefox]: ERROR command:-1 (invalid) tag:5 error:25 (Input/output error)
Sep 19 21:33:51 mightyiam-desktop pipewire-pulse[3307]: stream 0x559344c5ac50: error wrong resource type/version
Sep 19 21:33:51 mightyiam-desktop pipewire-pulse[3307]: client 0x5593447fbc70 [Chromium]: ERROR command:-1 (invalid) tag:2 error:25 (Input/output error)
Sep 19 21:33:58 mightyiam-desktop pipewire-pulse[3307]: stream 0x559344c1e700: error wrong resource type/version
Sep 19 21:33:58 mightyiam-desktop pipewire-pulse[3307]: client 0x559344c358f0 [PulseAudio Volume Control]: ERROR command:-1 (invalid) tag:18 error:25 (Input/output error)
Sep 19 21:33:58 mightyiam-desktop pipewire-pulse[3307]: stream 0x559344c52b00: error wrong resource type/version
Sep 19 21:33:58 mightyiam-desktop pipewire-pulse[3307]: client 0x559344c358f0 [PulseAudio Volume Control]: ERROR command:-1 (invalid) tag:19 error:25 (Input/output error)

Is this a good clue to anyone?

Have you tried regenerating the state directories of pipewire and pipewire-media-session?

@eadwu today I removed the files in .config/pipewire/media-session.d and they were never regenerated. Even after a reboot and login and trying to play some audio. Are there any other files?

@mightyiam /etc/pipewire

@fufexan, all of the files there seem to be links to /etc/static. I'm new to NixOS, but that sounds like they're products of derivations and not state that I could delete.

That directory will be repopulated when you rebuild. If they're links then there's not much that could've been changed.

Does pw-play work? (pw-play somefile.wav) The DBus error on the first line of that log looks suspicious to me.
Also note that master recently merged 0.3.36, which erroneously still reports 0.3.35 as its version so you'll have to readlink $(which pw-play) to which version you actually have. It doesn't seem like that build has made it to unstable yet, though.

.config/pipewire and apparently there's also .local/state/pipewire.

The DBus error on the first line of that log looks suspicious to me.

It's a try to access bluez. Not a problem if you don't use bluetooth.

Deleted .config/pipewire and .local/state/pipewire. Rebooted.
pw-play Downloads/file_example_WAV_1MG.wav
stream node<PHONE_NUMBER> error: wrong resource type/version
remote error: id=3 seq:4 res:-71 (Protocol error): wrong resource type/version
remote error: id=0 seq:5 res:-2 (No such file or directory): unknown resource 3 op:2

pipewire 0.3.36 (which reports itself as 0.3.35) and issue persists.

@mightyiam post the pipewire parts of your configuration.nix and/or try commenting out everything except the enable option.
Protocol error happened previously if certain modules weren't loaded in the config or were loaded in the wrong order. Beyond that, that node number is very suspicious, and I'd check with pw-dump that the stuff the daemon is aware of looks like it should.

When the only attribute set under pipepire is pipewire.enabled = true; I get the same result. pw-play fails in the same way.

Just found what seems to be the cause of my issue.

There are the referrers for the 0.3.30 old pipewire service I have running:
/nix/store/7cz4k6ab3z87cgrvcjfw4193jbh6y1vz-pipewire-0.3.30
/nix/store/3accqb66id153gvkgr857j4xsfyvlgbw-home-manager-path
/nix/store/iqdil2mamd0ph8k3szl0isz4ywbxvc2j-hm_pipewirepipewire.conf
/nix/store/4k7pphs23sgb261znaiq8gfx8k8vkvrv-home-manager-files
/nix/store/7iiw4y4izhfa6282dy2ahm79lljcyzjv-user-units
/nix/store/8r6688mj4jayprfjm6ivzfmk994y7h9p-user-units
/nix/store/8s75i8w27arbv3l37nh0jxrarqyv89lj-system-path
/nix/store/9n0ndgcl4j46dqhn07bjpqk3mcw1jbwa-home-manager-path
/nix/store/a9q66cyg7xdlhf6d2m1nnwbmdhnibasn-home-manager-path
/nix/store/ab3aiwnmv2qjxnw962q0w0as2kpbqgjb-pipewire.service
/nix/store/cn5myh08j0qkrkbg5j7hzapmcwi500kd-home-manager-files
/nix/store/crsfdd5f0m2mg8cbzj6f6zydd09s09wy-system-path
/nix/store/g7hqxn6qdmwa1fmrqibz6bi5w0qlrvh0-home-manager-path
/nix/store/gngrr2zvdrkz9cz3mvcd5gwrv8afr8va-user-units
/nix/store/h8z2vb2j3djs7n87qbjwxg86869rzwnq-home-manager-path
/nix/store/hg7gqdkay10k8cy7f3xvy1p25890bac0-home-manager-path
/nix/store/i7p1vil3h6yril2804awi17mnq85cvvf-system-path
/nix/store/l4bpsyqkmpiyqcwf20pwmk87g0vkk2rv-home-manager-path
/nix/store/mk9gi7vz9la5f5pgfhrcg2wnpwxah4zv-user-units
/nix/store/mn2nqriq8gi4da5srxh41bk44qpv5yhd-user-units
/nix/store/nhqfbagxbawc2zcjy9s2m02qjbjwnxrv-home-manager-path
/nix/store/p2dj5mmvk67hnfydca1v5yni7ay2d8cq-home-manager-path
/nix/store/phfzii9ribx35lzl7ychln6hb9whl1sw-home-manager-path
/nix/store/rzwrf049vvdfdlmc8w4j9y1jx1rr540f-home-manager-path
/nix/store/xffyshhc3kq6skpd509c5f1jw2xbhvcc-system-path
/nix/store/xfh9ffjgzpynm79bim4n92pc1sjqcap9-home-manager-files
/nix/store/yysj4qd8qxzrq4jfyqx1scarlqhq93vd-unit-systemd-udevd.service
/nix/store/zd14k1i4rmkb9gk0qq9whbcqadp8hrid-user-units

I thought home-manager is not supposed to start a pipewire service at all.

Is there a reason why services.pipewire.media-session.package doesn't default to config.services.pipewire.package.mediaSession? I changed pipewire.package and was surprised that the media session service didn't use the same package by default.

I can't remember any particular reason for it and didn't see any discussion about it in the PR that added the media-session module. Changing the default to the package used by the pipewire module sounds sensible.

I'm very new to nix and haven't studied much but here's my theory regarding what my issue was:
While debugging screen sharing I ran systemctl --user enable pipewire.service pipewire.socket or equivalent. That created symlinks the currently installed version of pipewire in the nix store from ~/.config/systemd/user.
Subsequent system generation upgrades of pipewire and home-manager generation upgrades of clients resulted in:

That particular version of pipewire sticking around(!)
At some point the clients were incompatible and could not communicate with the old version server.

One thing to learn from this is that in a system such as NixOS where executables will change their paths in the future, systems that have state that refers to those executables are bound to fail. Be careful. To be clear, I'm talking about the symlinks that systemd created. And this can fail in two ways:

They would eventually refer to an obsolete executable.
They would eventually refer to nothing, after nix-collect-garbage.

But a larger conclusion is: don't cut corners. Read the documentation of the systems you're using, especially if you're using NixOS and not e.g. Ubuntu.

@mightyiam ah yes, especially if you are doing things "manually" on NixOS (rather than through the module system) you really need to watch what you do.
In unrelated news, 0.3.37 is out with DSD passthrough, libcamera support built (but not enabled by default at runtime) and a pile of bugfixes: #139451

@jansol thanks for the help. I've been trying to convert this pulseaudio script to pipewire:
load-module module-udev-detect tsched=0
.include /etc/pulse/default.pa
set-card-profile alsa_card.pci-0000_07_00.4 output:analog-surround-51+input:analog-stereo
load-module module-remap-sink sink_name=headphones sink_properties="device.description='Headphones'" remix=no master=alsa_output.pci-0000_07_00.4.analog-surround-51 channels=2 master_channel_map=front-left,front-right channel_map=front-left,front-right
load-module module-remap-sink sink_name=speakers sink_properties="device.description='Speakers'" remix=no master=alsa_output.pci-0000_07_00.4.analog-surround-51 channels=2 master_channel_map=rear-left,rear-right channel_map=front-left,front-right
load-module module-virtual-surround-sink sink_name=vsurround channels=6 hrir=/home/daniel/.hrir/eq.wav sink_properties=device.description=VirtualSurround sink_master=headphones
set-default-sink vsurround

pacmd in pulseaudioLight package

Pipewire when auto started by dbus (I think?) cant access my sound card, I have to kill it and then use systemctl to start it again to get my audio working, I think starting pipewire from a terminal also has similar issues.
I also converted my pulseaudio script over with this: https://gist.github.com/a5cc07b6e70dadde5a35af0c349ae096

I have an interesting problem with pipewire (started via user-systemd) which is basically just a bit annoying that if the first program audio program that is started is using JACK (and not pulseaudio), then it can't find any outputs. Restarting the program (and thus reconnecting to pipewire) helps.

@YellowOnion from memory, pipewire is tarted by systemd.

https://github.com/NixOS/nixpkgs/pull/150548 packages wireplumber

Pipewire is socket-activated by systemd yes. Anything that tries to connect to pipewire proper or to the fake pulseaudio server should trigger it. However if the first thing you start is using JACK then I'm not sure how well the compat library handles it, or if your library path is even set up to point to the compat library before actual libjack by the time the application launches? Make sure to launch the application via pw-jack just in case.
As another workaround you can put some no-op invocation of one of the pipewire cli tools in a login script or other autostart setup. If you're feeling nostalgic you could even play a login sound with pw-play /some/file.wav just to make sure the pipewire server is running.

For the curious ones watching, there is a PR for a basic wireplumber module: #150548
There is also #150999 which bumps pipewire to the last release it will see this year, 0.3.42. As usual, please do help out with testing.

@jansol I think I found an issue which is what is causing my pipewire to fail to load:
Dec 22 11:34:44 Purple-Sunrise pipewire[2288360]: default: failed to load plugin 'librnnoise_ladspa': No such file or directory
Dec 22 11:34:44 Purple-Sunrise pipewire[2288360]: mod.filter-chain: no inputs
Dec 22 11:34:44 Purple-Sunrise pipewire[2288360]: mod.filter-chain: can't load graph: Invalid argument
Dec 22 11:34:44 Purple-Sunrise pipewire[2288360]: pw.conf: 0x557bea3d4c40: could not load mandatory module "libpipewire-module-filter-chain": Invalid argument

normally apps can't find ladspa plugins on nixos, and you need this in configuration.nix
{
  environment.variables = {
    VST_PATH    = "/nix/var/nix/profiles/default/lib/vst:/var/run/current-system/sw/lib/vst:~/.vst";
    LXVST_PATH  = "/nix/var/nix/profiles/default/lib/lxvst:/var/run/current-system/sw/lib/lxvst:~/.lxvst";
    LADSPA_PATH = "/nix/var/nix/profiles/default/lib/ladspa:/var/run/current-system/sw/lib/ladspa:~/.ladspa";
    LV2_PATH    = "/nix/var/nix/profiles/default/lib/lv2:/var/run/current-system/sw/lib/lv2:~/.lv2";
    DSSI_PATH   = "/nix/var/nix/profiles/default/lib/dssi:/var/run/current-system/sw/lib/dssi:~/.dssi";
  };
}

I'm not sure why these global environment variables aren't picked up via the auto start mechanism.

To run mpd with the native pipewire backend you have to setup XDG_RUNTIME_DIR, or else mpd will not find the pipewire instance.
{
  systemd.services.mpd.environment = {
    # https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/609
    XDG_RUNTIME_DIR = "/run/user/1000";
  };
}

This just came up on matrix and I was asked to share this information here.

To run mpd with the native pipewire backend you have to setup XDG_RUNTIME_DIR correctly, or else mpd will not find the pipewire instance.

Note that this was only tested with service.mpd.user = sameUserAsTheOneRunningPipewire.

I do have to add that I have mpd (via home-manager) work with the pipewire output just fine, without playing with that variable.
The variable might only be needed when using system-wide mpd configuration.

so I ended up with this wonderful piece of config to enable the echo cancellation module:
    config.pipewire = let
      defaultConf = lib.importJSON "${nixpkgs}/nixos/modules/services/desktops/pipewire/daemon/pipewire.conf.json";
    in lib.recursiveUpdate defaultConf {
      "context.modules" = defaultConf."context.modules" ++ [
        {
          name = "libpipewire-module-echo-cancel";
          args = {
            "source.props" = {
              "node.name" = "EC Source";
            };
            "sink.props" = {
              "node.name" = "EC Sink";
            };
...

I wonder if there is a saner way?

also, how do I make the echo-cancelling source & sink re-wire automatically when their underlying devices appear or go away (like when I [un]plug the docking station)?  and is there a way to specify preferred underlying devices?  docs are daunting and googling is unhelpful :(

On 24/01/22 17:33, Michael Livshin @.***> wrote:

also, how do I make the echo-cancelling source & sink re-wire
automatically when their underlying devices appear or go away (like when
I [un]plug the docking station)? and is there a way to specify preferred
underlying devices? docs are daunting and googling is unhelpful :(

You could try easyeffects?

The coupled streams examples mention that you can specify and args."capture.props"."node.target" and args."capture.props"."audio.position", not sure if that is aliased to args."sink.props".*.
I'm doing that with a filter-chain service running rnnoise and it's working great: https://github.com/NixOS/nixpkgs/issues/102547#issuecomment-953765041

The coupled streams examples mention that you can specify and args."capture.props"."node.target" and args."capture.props"."audio.position", not sure if that is aliased to args."sink.props".*.

pipewire (or its default "session manager", I guess?) already finds some devices to link to, just not the right ones when the computer is docked (not that I can blame it, given that it has to choose from 3 microphones and like 4 or 5 outputs), and also it would be great if one could say something like "when this [source0, sink0] are available, echo-cancel between them, otherwise between [source1, sink1]".  looks like I need to switch to wireplumber and write some lua?
[ <rant>am I crazy?  do I want something esoteric here?  echo cancelling should be the brainless default on a modern desktop -- just do it between the default source and sink, and only when the microphone is in use (why waste CPU otherwise), that's it.  argh</rant>.  but yeah, where would all the fun be then. :) ]

I'm doing that with a filter-chain service running rnnoise and it's working great: #102547 (comment)

what motivated bringing up a separate service?  I must be still missing something basic.

The capture.props thing is a thing in pipewire proper, no session managers involved. In fact, the git version of pipewire can be used without a session manager now (for very simple setups).
Yeah, it connects to the "first" device that has a port with a name matching the audio position, or the matching port of the target node if one was defined and it exists, quite reasonable IMHO, just not documented as aggressively as it probably should.
I run filter-chain as a separate service since that's how the example config documents it. It would probably work in the main pipewire config too, but I have been too lazy to change it and it provides an extra bit of isolation so filter-chain crashing won't take down the whole audio server. Not that that has been a problem after I got the config to work in the first place.
Echo/noise cancelling should definitely be the default for communication apps, but for other stuff it's not as obviously wanted.

Every single apps involving ALSA (pipewire.alsa.enable) seems to fail with ALSA lib control.c:1464:(snd_ctl_open_conf) Unknown field libs, which I believe is related to 49-pipewire-modules.conf that this option generates:
pcm_type.pipewire {
  libs.native = /nix/store/iyahs9mbnbpwqbmwbgwf8vyaa1a6clfa-pipewire-0.3.43-lib/lib/alsa-lib/libasound_module_pcm_pipewire.so ;
  libs.32Bit = /nix/store/qcg48l2qxa4g8afw0xv5yhjihn35d4bl-pipewire-0.3.43-lib/lib/alsa-lib/libasound_module_pcm_pipewire.so ;
}
ctl_type.pipewire {
  libs.native = /nix/store/iyahs9mbnbpwqbmwbgwf8vyaa1a6clfa-pipewire-0.3.43-lib/lib/alsa-lib/libasound_module_ctl_pipewire.so ;
  libs.32Bit = /nix/store/qcg48l2qxa4g8afw0xv5yhjihn35d4bl-pipewire-0.3.43-lib/lib/alsa-lib/libasound_module_ctl_pipewire.so ;
}
```.

I was able to find a workaround for this while I believe giving up 32Bit support:

pcm_type.pipewire {
lib /nix/store/iyahs9mbnbpwqbmwbgwf8vyaa1a6clfa-pipewire-0.3.43-lib/lib/alsa-lib/libasound_module_pcm_pipewire.so ;
}
ctl_type.pipewire {
lib /nix/store/iyahs9mbnbpwqbmwbgwf8vyaa1a6clfa-pipewire-0.3.43-lib/lib/alsa-lib/libasound_module_ctl_pipewire.so ;
}

However, I would like to know what would be a proper fix for this, and whether this is a problem on my end.

  sound.extraConfig = ''
    pcm_type.pipewire {
      libs.native = ${pkgs.pipewire.lib}/lib/alsa-lib/libasound_module_pcm_pipewire.so ;
      libs.32Bit = ${pkgs.pkgsi686Linux.pipewire.lib}/lib/alsa-lib/libasound_module_pcm_pipewire.so ;
    }
    ctl_type.pipewire {
      libs.native = ${pkgs.pipewire.lib}/lib/alsa-lib/libasound_module_ctl_pipewire.so ;
      libs.32Bit = ${pkgs.pkgsi686Linux.pipewire.lib}/lib/alsa-lib/libasound_module_ctl_pipewire.so ;
    }
    pcm.!default {
      type pipewire
    }
    ctl.!default {
      type pipewire
    }
  '';

should allow you to have still keep 32bit support

Nope, that didn't seem to fix the issue.
As I said before, using the libs at all seems to throw the ALSA lib control.c:1464:(snd_ctl_open_conf) Unknown field libs error.

afaik alsalib code section: https://github.com/alsa-project/alsa-lib/blob/3dbe072d8deba7c11f6e766ef80c0e50a69447d0/src/control/control.c#L1441-L1467
It seems it only supports keys comment, lib, open.

Indeed, I'm not really sure how this worked before. Maybe there was a breaking change recently?

no, if you look at the git blame of the function, you notice that it hasn't really changed in the past 7 years besides https://github.com/alsa-project/alsa-lib/commit/b2a4272ecb40d84556d8e043d0b6e89439acbc33, which appears to finish the ability to use relative paths for plugins, which is related to this problem, but I don't know how to use/apply it.

I was able to find a workaround for this while I believe giving up 32Bit support:
pcm_type.pipewire {
  lib /nix/store/iyahs9mbnbpwqbmwbgwf8vyaa1a6clfa-pipewire-0.3.43-lib/lib/alsa-lib/libasound_module_pcm_pipewire.so ;
}
ctl_type.pipewire {
  lib /nix/store/iyahs9mbnbpwqbmwbgwf8vyaa1a6clfa-pipewire-0.3.43-lib/lib/alsa-lib/libasound_module_ctl_pipewire.so ;
}

I'm facing this issue right now - where are you putting this? sound.extraConfig appears to be completely ignored - maybe I'm doing something dumb here?


column color is ok, but also image name would be useful

When many images to compares, the color is not enough immediate to understand.
A new column with image name would be useful.

tested on dev branch, so far so good!

merged in master


How to call dll?

How do you call the dll after injection?

What exactly do you want to do? If you want to run code once the dll is loaded, the solution depends on you operating system, and you can find a specific answer in Google.