# source: https://github.com/fufexan/nix-gaming/raw/master/modules/pipewireLowLatency.nix { config, pkgs, lib, ... }: let inherit (lib.modules) mkIf; inherit (lib.options) mkOption mkEnableOption; inherit (lib.types) int; inherit (lib.generators) toLua; cfg = config.services.pipewire.lowLatency; qr = "${toString cfg.quantum}/${toString cfg.rate}"; in { # low-latency PipeWire configuration # extends the nixpkgs module meta.maintainers = with lib.maintainers; [ fufexan ]; options = { services.pipewire.lowLatency = { enable = mkEnableOption '' low latency for PipeWire. This will also set `services.pipewire.enable` and `services.pipewire.wireplumber.enable` to true. ''; quantum = mkOption { description = "Minimum quantum to set"; type = int; default = 64; example = 32; }; rate = mkOption { description = "Rate to set"; type = int; default = 48000; example = 96000; }; }; }; config = mkIf cfg.enable { services.pipewire = { # make sure PipeWire is enabled if the module is imported # and low latency is enabledd enable = true; # write extra config extraConfig.pipewire = { "99-lowlatency" = { context = { properties.default.clock.min-quantum = cfg.quantum; modules = [ { name = "libpipewire-module-rtkit"; flags = [ "ifexists" "nofail" ]; args = { nice.level = -15; rt = { prio = 88; time.soft = 200000; time.hard = 200000; }; }; } { name = "libpipewire-module-protocol-pulse"; args = { server.address = [ "unix:native" ]; pulse.min = { req = qr; quantum = qr; frag = qr; }; }; } ]; stream.properties = { node.latency = qr; resample.quality = 1; }; }; }; }; # ensure WirePlumber is enabled explicitly (defaults to true while PW is enabled) # and write extra config to ship low latency rules for alsa wireplumber = { enable = true; configPackages = let # generate "matches" section of the rules matches = toLua { multiline = false; # looks better while inline indent = false; } [ [ [ "node.name" "matches" "alsa_output.*" ] ] ]; # nested lists are to produce `{{{ }}}` in the output # generate "apply_properties" section of the rules apply_properties = toLua { } { "audio.format" = "S32LE"; "audio.rate" = cfg.rate * 2; "api.alsa.period-size" = 2; }; in [ (pkgs.writeTextDir "share/lowlatency.lua.d/99-alsa-lowlatency.lua" '' -- Generated by nix-gaming alsa_monitor.rules = { { matches = ${matches}; apply_properties = ${apply_properties}; } } '') ]; }; }; }; }