summary refs log tree commit diff
path: root/nixos/modules/config
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/config')
-rw-r--r--nixos/modules/config/pulseaudio.nix89
1 files changed, 79 insertions, 10 deletions
diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix
index 7acf050a9a40..2939e67566c8 100644
--- a/nixos/modules/config/pulseaudio.nix
+++ b/nixos/modules/config/pulseaudio.nix
@@ -9,11 +9,36 @@ let
 
   systemWide = cfg.enable && cfg.systemWide;
   nonSystemWide = cfg.enable && !cfg.systemWide;
+  hasZeroconf = let z = cfg.zeroconf; in z.publish.enable || z.discovery.enable;
+
+  overriddenPackage = cfg.package.override
+    (optionalAttrs hasZeroconf { zeroconfSupport = true; });
+  binary = "${getBin overriddenPackage}/bin/pulseaudio";
+  binaryNoDaemon = "${binary} --daemonize=no";
 
   # Forces 32bit pulseaudio and alsaPlugins to be built/supported for apps
   # using 32bit alsa on 64bit linux.
   enable32BitAlsaPlugins = cfg.support32Bit && stdenv.isx86_64 && (pkgs_i686.alsaLib != null && pkgs_i686.libpulseaudio != null);
 
+
+  myConfigFile =
+    let
+      addModuleIf = cond: mod: optionalString cond "load-module ${mod}";
+      allAnon = optional cfg.tcp.anonymousClients.allowAll "auth-anonymous=1";
+      ipAnon =  let a = cfg.tcp.anonymousClients.allowedIpRanges;
+                in optional (a != []) ''auth-ip-acl=${concatStringsSep ";" a}'';
+    in writeTextFile {
+      name = "default.pa";
+        text = ''
+        .include ${cfg.configFile}
+        ${addModuleIf cfg.zeroconf.publish.enable "module-zeroconf-publish"}
+        ${addModuleIf cfg.zeroconf.discovery.enable "module-zeroconf-discover"}
+        ${addModuleIf cfg.tcp.enable (concatStringsSep " "
+           ([ "load-module module-native-protocol-tcp" ] ++ allAnon ++ ipAnon))}
+        ${cfg.extraConfig}
+      '';
+    };
+
   ids = config.ids;
 
   uid = ids.uids.pulseaudio;
@@ -26,7 +51,7 @@ let
   # are built with PulseAudio support (like KDE).
   clientConf = writeText "client.conf" ''
     autospawn=${if nonSystemWide then "yes" else "no"}
-    ${optionalString nonSystemWide "daemon-binary=${cfg.package.out}/bin/pulseaudio"}
+    ${optionalString nonSystemWide "daemon-binary=${binary}"}
     ${cfg.extraClientConf}
   '';
 
@@ -44,7 +69,7 @@ let
       hint.description "Default Audio Device (via PulseAudio)"
     }
     ctl_type.pulse {
-      libs.native = ${alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;
+      libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;
       ${lib.optionalString enable32BitAlsaPlugins
      "libs.32Bit = ${pkgs_i686.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;"}
     }
@@ -89,16 +114,25 @@ in {
       };
 
       configFile = mkOption {
-        type = types.path;
+        type = types.nullOr types.path;
         description = ''
-          The path to the configuration the PulseAudio server
+          The path to the default configuration options the PulseAudio server
           should use. By default, the "default.pa" configuration
           from the PulseAudio distribution is used.
         '';
       };
 
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Literal string to append to <literal>configFile</literal>
+          and the config file generated by the pulseaudio module.
+        '';
+      };
+
       extraClientConf = mkOption {
-        type = types.str;
+        type = types.lines;
         default = "";
         description = ''
           Extra configuration appended to pulse/client.conf file.
@@ -127,6 +161,31 @@ in {
           '';
         };
       };
+
+      zeroconf = {
+        discovery.enable =
+          mkEnableOption "discovery of pulseaudio sinks in the local network";
+        publish.enable =
+          mkEnableOption "publishing the pulseaudio sink in the local network";
+      };
+
+      # TODO: enable by default?
+      tcp = {
+        enable = mkEnableOption "tcp streaming support";
+
+        anonymousClients = {
+          allowAll = mkEnableOption "all anonymous clients to stream to the server";
+          allowedIpRanges = mkOption {
+            type = types.listOf types.str;
+            default = [];
+            example = literalExample ''[ "127.0.0.1" "192.168.1.0/24" ]'';
+            description = ''
+              A list of IP subnets that are allowed to stream to the server.
+            '';
+          };
+        };
+      };
+
     };
 
   };
@@ -139,11 +198,11 @@ in {
         source = clientConf;
       };
 
-      hardware.pulseaudio.configFile = mkDefault "${getBin cfg.package}/etc/pulse/default.pa";
+      hardware.pulseaudio.configFile = mkDefault "${getBin overriddenPackage}/etc/pulse/default.pa";
     }
 
     (mkIf cfg.enable {
-      environment.systemPackages = [ cfg.package ];
+      environment.systemPackages = [ overriddenPackage ];
 
       environment.etc = singleton {
         target = "asound.conf";
@@ -152,12 +211,21 @@ in {
 
       # Allow PulseAudio to get realtime priority using rtkit.
       security.rtkit.enable = true;
+
+    })
+
+    (mkIf hasZeroconf {
+      services.avahi.enable = true;
+    })
+    (mkIf cfg.zeroconf.publish.enable {
+      services.avahi.publish.enable = true;
+      services.avahi.publish.userServices = true;
     })
 
     (mkIf nonSystemWide {
       environment.etc = singleton {
         target = "pulse/default.pa";
-        source = cfg.configFile;
+        source = myConfigFile;
       };
 
       systemd.user = {
@@ -167,10 +235,11 @@ in {
           wantedBy = [ "default.target" ];
           serviceConfig = {
             Type = "notify";
-            ExecStart = "${getBin cfg.package}/bin/pulseaudio --daemonize=no";
+            ExecStart = binaryNoDaemon;
             Restart = "on-failure";
           };
           environment = { DISPLAY = ":${toString config.services.xserver.display}"; };
+          restartIfChanged = true;
         };
 
         sockets.pulseaudio = {
@@ -205,7 +274,7 @@ in {
         environment.PULSE_RUNTIME_PATH = stateDir;
         serviceConfig = {
           Type = "notify";
-          ExecStart = "${getBin cfg.package}/bin/pulseaudio --daemonize=no --log-level=${cfg.daemon.logLevel} --system -n --file=${cfg.configFile}";
+          ExecStart = "${binaryNoDaemon} --log-level=${cfg.daemon.logLevel} --system -n --file=${myConfigFile}";
           Restart = "on-failure";
         };
       };