PipeWire: Difference between revisions

From NixOS Wiki
imported>Fufexan
m Fixed config example
imported>Fufexan
Add low-latency config section
Line 41: Line 41:
   };
   };
};
};
</syntaxHighlight>
==Low-latency setup==
Audio production and rhythm games require lower latency audio than general applications. PipeWire can achieve the required latency with much less CPU usage compared to PulseAudio, with the appropriate configuration.
The minimum period size controls how small a buffer can be. The lower it is, the less latency there is. PipeWire has a value of 32 by default, which amounts to 1.33ms. It can be brought lower if needed:
<syntaxHighlight lang="nix">
services.pipewire = {
  config.pipewire = {
    "context.properties" = {
      "default.clock.min-quantum" = 16 # going lower may cause crackles and distorted audio
    };
  };
};
</syntaxHighlight>
===PulseAudio backend===
Applications using the Pulse backend have a separate configuration. The default minimum value is 1024, so it needs to be tweaked if low-latency audio is desired.
<syntaxHighlight lang="nix">
services.pipewire = {
  config.pipewire-pulse = {
    "context.modules" = [
      {
        name = "libpipewire-module-protocol-pulse";
        args = {
          "pulse.min.quantum" = 16; # controls minimum playback quant
          "pulse.min.req" = 16; # controls minimum recording quant
          "pulse.min.frag" = 16; # controls minimum fragment size
          "server.address" = [ "unix:native" ]; # the default address of the server
        };
      };
    ];
  };
};
</syntaxHighlight>
As a general rule, the values in <code>pipewire-pulse</code> should not be lower than the ones in <code>pipewire</code>.
===Controlling the ALSA devices===
It is possible to configure various aspects of soundcards through <code>/etc/pipewire/media-session.d/alsa-monitor.conf</code>. Since there's no config option for it in the module, the file needs to be manually written:
<syntaxHighlight lang="nix">
environment.etc."pipewire/media-session.d/alsa-monitor.conf".text = ''
  rules = [
    {
      matches = [ { node.name = alsa_output.* } ]
      actions = {
        update-props = {
          audio.format = "S16LE"
          audio.rate = 48000
          api.alsa.period-size = 160 # defaults to 1024, tweak by trial-and-error
          #api.alsa.disable-batch = true # generally, USB soundcards use the batch mode
        }
      }
    }
  ];
'';
</syntaxHighlight>
The <code>matches</code> attribute applies the <code>actions</code> to the devices/properties listed there. It is usually used with soundcard names, like shown in the config above. <code><alsa_device></code> can be one of the outputs of
<syntaxHighlight lang="bash">
$ pw-dump | grep node.name | grep alsa
</syntaxHighlight>
</syntaxHighlight>



Revision as of 11:24, 24 April 2021

PipeWire is a new low-level multimedia framework. It aims to offer capture and playback for both audio and video with minimal latency and support for PulseAudio-, JACK-, ALSA- and GStreamer-based applications.

The daemon based on the framework can be configured to be both an audio server (with PulseAudio and JACK features) and a video capture server.

Enabling PipeWire

Add to your configuration:

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

Some useful knobs if you want to finetune or debug your setup:

services.pipewire = {
  config.pipewire = {
    "context.properties" = {
      #"link.max-buffers" = 64;
      "link.max-buffers" = 16; # version < 3 clients can't handle more than this
      "log.level" = 2; # https://docs.pipewire.org/#Logging
      #"default.clock.rate" = 48000;
      #"default.clock.quantum" = 1024;
      #"default.clock.min-quantum" = 32;
      #"default.clock.max-quantum" = 8192;
  };
};

Low-latency setup

Audio production and rhythm games require lower latency audio than general applications. PipeWire can achieve the required latency with much less CPU usage compared to PulseAudio, with the appropriate configuration. The minimum period size controls how small a buffer can be. The lower it is, the less latency there is. PipeWire has a value of 32 by default, which amounts to 1.33ms. It can be brought lower if needed:

services.pipewire = {
  config.pipewire = {
    "context.properties" = {
      "default.clock.min-quantum" = 16 # going lower may cause crackles and distorted audio
    };
  };
};

PulseAudio backend

Applications using the Pulse backend have a separate configuration. The default minimum value is 1024, so it needs to be tweaked if low-latency audio is desired.

services.pipewire = {
  config.pipewire-pulse = {
    "context.modules" = [
      {
        name = "libpipewire-module-protocol-pulse";
        args = {
          "pulse.min.quantum" = 16; # controls minimum playback quant
          "pulse.min.req" = 16; # controls minimum recording quant
          "pulse.min.frag" = 16; # controls minimum fragment size
          "server.address" = [ "unix:native" ]; # the default address of the server
        };
      };
    ];
  };
};

As a general rule, the values in pipewire-pulse should not be lower than the ones in pipewire.

Controlling the ALSA devices

It is possible to configure various aspects of soundcards through /etc/pipewire/media-session.d/alsa-monitor.conf. Since there's no config option for it in the module, the file needs to be manually written:

environment.etc."pipewire/media-session.d/alsa-monitor.conf".text = ''
  rules = [
    {
      matches = [ { node.name = alsa_output.* } ]
      actions = {
        update-props = {
          audio.format = "S16LE"
          audio.rate = 48000
          api.alsa.period-size = 160 # defaults to 1024, tweak by trial-and-error
          #api.alsa.disable-batch = true # generally, USB soundcards use the batch mode
        }
      }
    }
  ];
'';

The matches attribute applies the actions to the devices/properties listed there. It is usually used with soundcard names, like shown in the config above. <alsa_device> can be one of the outputs of

$ pw-dump | grep node.name | grep alsa

See also