Personal Nix setup
at main 3.3 kB view raw
1{ lib, pkgs, config, user, ... }: 2 3with lib; 4let 5 inherit (generators) toLua; 6 cfg = config.modules.desktop; 7in { 8 options.modules.desktop.audio = { 9 enable = mkOption { 10 default = true; 11 example = true; 12 description = "Whether to enable Pipewire audio."; 13 type = types.bool; 14 }; 15 16 lowLatency = mkOption { 17 default = true; 18 example = true; 19 description = "Whether to enable Pipewire low latency."; 20 type = types.bool; 21 }; 22 23 quantum = mkOption { 24 description = "Minimum quantum to set"; 25 type = types.int; 26 default = 64; 27 example = 32; 28 }; 29 30 rate = mkOption { 31 description = "Rate to set"; 32 type = types.int; 33 default = 48000; 34 example = 96000; 35 }; 36 }; 37 38 config = mkIf cfg.audio.enable { 39 security.rtkit.enable = true; 40 41 services = { 42 pipewire = let 43 quantum = cfg.audio.quantum; 44 rate = cfg.audio.rate; 45 qr = "${toString quantum}/${toString rate}"; 46 in { 47 enable = cfg.audio.enable; 48 pulse.enable = true; 49 jack.enable = true; 50 alsa = { 51 enable = true; 52 support32Bit = mkDefault true; 53 }; 54 55 # write extra config 56 extraConfig.pipewire = mkIf cfg.audio.lowLatency { 57 "99-lowlatency" = { 58 context = { 59 properties.default.clock.min-quantum = quantum; 60 modules = [ 61 { 62 name = "libpipewire-module-rtkit"; 63 flags = ["ifexists" "nofail"]; 64 args = { 65 nice.level = -15; 66 rt = { 67 prio = 88; 68 time.soft = 200000; 69 time.hard = 200000; 70 }; 71 }; 72 } 73 { 74 name = "libpipewire-module-protocol-pulse"; 75 args = { 76 server.address = ["unix:native"]; 77 pulse.min = { 78 req = qr; 79 quantum = qr; 80 frag = qr; 81 }; 82 }; 83 } 84 ]; 85 86 stream.properties = { 87 node.latency = qr; 88 resample.quality = 1; 89 }; 90 }; 91 }; 92 }; 93 94 wireplumber = { 95 enable = true; 96 configPackages = let 97 # generate "matches" section of the rules 98 matches = toLua { 99 multiline = false; # looks better while inline 100 indent = false; 101 } [[["node.name" "matches" "alsa_output.*"]]]; # nested lists are to produce `{{{ }}}` in the output 102 103 # generate "apply_properties" section of the rules 104 apply_properties = toLua {} { 105 "audio.format" = "S32LE"; 106 "audio.rate" = rate * 2; 107 "api.alsa.period-size" = 2; 108 }; 109 in [ 110 (pkgs.writeTextDir "share/lowlatency.lua.d/99-alsa-lowlatency.lua" '' 111 -- Generated by nix-gaming 112 alsa_monitor.rules = { 113 { 114 matches = ${matches}; 115 apply_properties = ${apply_properties}; 116 } 117 } 118 '') 119 ]; 120 }; 121 }; 122 }; 123 }; 124}