From 00e2f4d87e2485782e7449b1c902569cd341ca69 Mon Sep 17 00:00:00 2001 From: Malte Tammena Date: Fri, 1 Nov 2024 19:52:41 +0100 Subject: [PATCH] fmt(host/cerithium-telescopium): audio-server --- hosts/cerithium-telescopium/audio-server.nix | 163 ++++++++++--------- modules/snapclient.nix | 7 +- 2 files changed, 92 insertions(+), 78 deletions(-) diff --git a/hosts/cerithium-telescopium/audio-server.nix b/hosts/cerithium-telescopium/audio-server.nix index 0543747..4f7ccd9 100644 --- a/hosts/cerithium-telescopium/audio-server.nix +++ b/hosts/cerithium-telescopium/audio-server.nix @@ -8,91 +8,100 @@ }: let snapcastPipewireFifo = "/run/snapserver/pipewire"; in { - # === Mopidy === - # services.mopidy = { - # enable = true; - # extensionPackages = [ - # pkgs.mopidy-mpd - # pkgs.mopidy-iris - # ]; - # configuration = '' - # [http] - # enabled = true - # hostname = 0.0.0.0 - # port = 6680 + # === Mopidy === + # services.mopidy = { + # enable = true; + # extensionPackages = [ + # pkgs.mopidy-mpd + # pkgs.mopidy-iris + # ]; + # configuration = '' + # [http] + # enabled = true + # hostname = 0.0.0.0 + # port = 6680 - # [audio] - # mixer = software - # mixer_volume = 100 - # output = audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink location=/run/snapserver/mopidy + # [audio] + # mixer = software + # mixer_volume = 100 + # output = audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink location=/run/snapserver/mopidy - # [file] - # enabled = false - # ''; - # }; - # networking.firewall.allowedTCPPorts = [6680]; + # [file] + # enabled = false + # ''; + # }; + # networking.firewall.allowedTCPPorts = [6680]; - # === Snapcast Server === - services.snapserver = { - enable = true; - openFirewall = true; - http.docRoot = "${pkgs.snapweb}/"; - streams = { - pipewire = { - type = "pipe"; - codec = "flac"; - location = snapcastPipewireFifo; - }; + # === Snapcast Server === + services.snapserver = { + enable = true; + openFirewall = true; + http.docRoot = "${pkgs.snapweb}/"; + streams = { + pipewire = { + type = "pipe"; + codec = "flac"; + location = snapcastPipewireFifo; }; }; - systemd.tmpfiles.settings."99-snapserver"."/run/snapserver".d = {}; + }; + systemd.tmpfiles.settings."99-snapserver"."/run/snapserver".d = {}; - # === Pipewire === - # Create a sink that writes everything to the snapcast fifo - services.pipewire.extraConfig.pipewire."20-snapcast-sink"."context.modules" = lib.singleton { - name = "libpipewire-module-pipe-tunnel"; - args = { - "tunnel.mode" = "sink"; - "pipe.filename" = snapcastPipewireFifo; - "audio.format" = "S16LE"; - "audio.rate" = "48000"; - "audio.channels" = "2"; - "audio.position" = [ "FL" "FR" ]; - "stream.props" = { - "node.name" = "Snapcast"; - }; + # === Pipewire === + # Create a sink that writes everything to the snapcast fifo + services.pipewire.extraConfig.pipewire."20-snapcast-sink"."context.modules" = lib.singleton { + name = "libpipewire-module-pipe-tunnel"; + args = { + "tunnel.mode" = "sink"; + "pipe.filename" = snapcastPipewireFifo; + "audio.format" = "S16LE"; + "audio.rate" = "48000"; + "audio.channels" = "2"; + "audio.position" = ["FL" "FR"]; + "stream.props" = { + "node.name" = "Snapcast"; }; }; - # Instruct pipewire to connect bluetooth input streams to the Snapcast sink - services.pipewire.extraConfig.pipewire."21-bluetooth-to-snapcast"."node.rules" = lib.singleton { - matches = lib.singleton { "node.name" = "~bluez_input.*"; }; - actions.update-props."target.object" = "Snapcast"; - }; - # TODO: - services.pipewire.extraConfig.pipewire-pulse."50-networking"."pulse.cmd" = [ - { cmd = "load-module"; args = "module-native-protocol-tcp listen=0.0.0.0"; } - { cmd = "load-module"; args = "module-zeroconf-discover"; } - { cmd = "load-module"; args = "module-zeroconf-publish"; } + }; + # Instruct pipewire to connect bluetooth input streams to the Snapcast sink + services.pipewire.extraConfig.pipewire."21-bluetooth-to-snapcast"."node.rules" = lib.singleton { + matches = lib.singleton {"node.name" = "~bluez_input.*";}; + actions.update-props."target.object" = "Snapcast"; + }; + # TODO: + services.pipewire.extraConfig.pipewire-pulse."50-networking"."pulse.cmd" = [ + { + cmd = "load-module"; + args = "module-native-protocol-tcp listen=0.0.0.0"; + } + { + cmd = "load-module"; + args = "module-zeroconf-discover"; + } + { + cmd = "load-module"; + args = "module-zeroconf-publish"; + } + ]; + + # === Bluetooth input === + hardware.bluetooth.settings = { + # Configure the bluetooth adapter to be an audio sink + General.Enable = "Source"; + General.DiscoverableTimeout = 0; + General.AlwaysPairable = true; + General.JustWorksRepairing = "always"; + }; + environment.etc."bluetooth/pin-file".text = '' + * 124356 + ''; + systemd.user.services.bluetooth-agent = { + wantedBy = [ + "default.target" ]; - - # === Bluetooth input === - hardware.bluetooth.settings = { - # Configure the bluetooth adapter to be an audio sink - General.Enable = "Source"; - General.DiscoverableTimeout = 0; - General.AlwaysPairable = true; - General.JustWorksRepairing = "always"; - }; - environment.etc."bluetooth/pin-file".text = '' - * 124356 - ''; - systemd.user.services.bluetooth-agent = { - wantedBy = [ - "default.target" - ]; - serviceConfig = { - ExecStart = "${pkgs.bluez-tools}/bin/bt-agent --pin /etc/bluetooth/pin-file --capability NoInputNoOutput"; - Slice="session.slice"; - }; + serviceConfig = { + ExecStart = "${pkgs.bluez-tools}/bin/bt-agent --pin /etc/bluetooth/pin-file --capability NoInputNoOutput"; + Slice = "session.slice"; }; + }; } diff --git a/modules/snapclient.nix b/modules/snapclient.nix index 322a22e..2180cfe 100644 --- a/modules/snapclient.nix +++ b/modules/snapclient.nix @@ -7,6 +7,11 @@ let cfg = config.services.snapclient; in { options.services.snapclient.enable = lib.mkEnableOption "a local snapclient service"; + options.services.snapclient.latency = lib.mkOption { + type = lib.types.number; + description = "latency of the PCM device"; + default = 0; + }; config.systemd.user.services.snapclient = lib.mkIf cfg.enable { wantedBy = lib.warnIfNot config.services.pipewire.enable "Pipewire is not running, snapclient won't work" [ @@ -17,7 +22,7 @@ let cfg = config.services.snapclient; in "pipewire.service" ]; serviceConfig = { - ExecStart = "${pkgs.snapcast}/bin/snapclient --host snapserver --player pulse"; + ExecStart = "${pkgs.snapcast}/bin/snapclient --host snapserver --player pulse --latency ${builtins.toString cfg.latency}"; Slice="session.slice"; }; };