nix-config/modules/audio-server.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

243 lines
7.0 KiB
Nix
Raw Permalink Normal View History

{ config, lib, pkgs, ... }:
2022-06-12 17:26:32 +02:00
2023-05-24 00:41:47 +02:00
let
2023-10-04 00:11:11 +02:00
cfg = config.c3d2.audioServer;
2023-05-24 00:41:47 +02:00
in
2021-09-27 22:40:27 +02:00
{
options.c3d2.audioServer = {
2023-10-04 00:11:11 +02:00
enable = lib.mkEnableOption "PulseAudio and Bluetooth sinks";
ledfx = lib.mkEnableOption "LedFX service";
2021-09-27 22:40:27 +02:00
};
2023-10-04 00:11:11 +02:00
config = lib.mkIf cfg.enable {
2023-05-18 16:19:57 +02:00
boot.kernelPackages = lib.mkOverride 900 pkgs.linuxPackages-rt_latest;
2023-05-16 23:17:58 +02:00
2023-05-24 00:41:47 +02:00
environment = {
2023-12-22 14:57:58 +01:00
# _____ _______ ____ _____
# / ____|__ __/ __ \| __ \
# | (___ | | | | | | |__) |
# \___ \ | | | | | | ___/
# ____) | | | | |__| | |
# |_____/ |_| \____/|_|
#
# errors such as:
# mod.zeroconf-publish: error id:47 seq:349 res:-2 (No such file or directory): enum params id:16 (Spa:Enum:ParamId:ProcessLatency) failed
# are harmless and can be ignored. You most likely want to restart your local avahi-daemon: sudo systemctl restart avahi-daemon
etc = {
"pipewire/pipewire.conf.d/audio-server.conf".text = builtins.toJSON {
"context.modules" = [ {
# https://wiki.archlinux.org/title/PulseAudio/Examples#PulseAudio_over_network
name = "libpipewire-module-rtp-sap";
args = {
"sap.ip" = "0.0.0.0";
"sess.latency.msec" = 10;
};
} ];
};
"pipewire/pipewire-pulse.conf.d/audio-server.conf".text = builtins.toJSON {
"context.exec" = [ {
path = "${pkgs.pulseaudio}/bin/pactl";
args = "load-module module-zeroconf-publish";
} ];
"pulse.properties" = {
"auth-ip-acl" = [
"127.0.0.0/8"
"::1/128"
"fd23:42:c3d2:500::/56"
"172.22.99.0/24"
"172.20.72.0/21"
"2a00:8180:2c00:200::/56"
"2a0f:5382:acab:1400::/56"
];
"pulse.default.tlength" = "96000/48000";
"server.address" = [
"unix:native"
"tcp:4713"
];
};
};
2023-05-24 00:41:47 +02:00
};
2023-12-22 14:57:58 +01:00
2023-05-24 00:41:47 +02:00
systemPackages = with pkgs; [
mpd
# draws in mesa
(wrapMpv (mpv-unwrapped.override { drmSupport = false; }) { })
2023-05-24 00:41:47 +02:00
ncmpcpp
ncpamixer
pulseaudio # required for pactl
somafm-cli
];
};
hardware = {
bluetooth.settings = {
Policy.AutoEnable = true;
General.DiscoverableTimeout = 0;
2021-09-27 22:40:27 +02:00
};
pulseaudio = {
enable = !config.services.pipewire.pulse.enable;
systemWide = true;
tcp = {
enable = true;
anonymousClients.allowedIpRanges = [
"127.0.0.0/8"
"::1/128"
"fd23:42:c3d2:500::/56"
"172.22.99.0/24"
"172.20.72.0/21"
"2a00:8180:2c00:200::/56"
"2a0f:5382:acab:1400::/56"
];
};
zeroconf.publish.enable = true;
package = (pkgs.pulseaudio.override {
bluetoothSupport = true;
advancedBluetoothCodecs = true;
zeroconfSupport = true;
}).overrideAttrs (_: {
# one test times out
doCheck = false;
});
2022-09-17 22:15:31 +02:00
};
2021-09-27 22:40:27 +02:00
};
2022-06-12 17:26:32 +02:00
networking.firewall = {
2023-10-04 00:11:11 +02:00
allowedTCPPorts = lib.optional cfg.ledfx 80 ++ [
2023-12-13 20:35:05 +01:00
4713 # pulseaudio/pipewire tcp sink
];
allowedUDPPorts = [
5353 # mdns
2023-12-13 20:35:05 +01:00
9875 # pulseaudio/pipewire rtp sink
];
};
2023-04-29 23:26:17 +02:00
nixpkgs.overlays = [
(final: prev: {
python3 = prev.python3.override {
2023-05-24 00:41:57 +02:00
packageOverrides = python-final: python-prev:
(lib.optionalAttrs config.environment.noXlibs {
# remove x11 dependencies from pkgs.ledfx
pystray = null;
} // {
2023-05-15 20:36:58 +02:00
# avoid dependency on x11 libraries
2023-04-29 23:26:17 +02:00
samplerate = python-prev.samplerate.overrideAttrs (_: {
dontUseSetuptoolsCheck = true;
});
2023-05-24 00:41:57 +02:00
});
2023-04-29 23:26:17 +02:00
};
python3Packages = final.python3.pkgs;
})
];
security = {
polkit.extraConfig = /* javascript */ ''
2023-05-26 19:32:37 +02:00
// https://www.reddit.com/r/voidlinux/comments/o74i76/comment/h2z9u11/?utm_source=reddit&utm_medium=web2x&context=3
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.RealtimeKit1.acquire-high-priority"
|| action.id == "org.freedesktop.RealtimeKit1.acquire-real-time") {
return polkit.Result.YES;
}
});
// broader alternative if the above ever breaks
// polkit.addRule(function(action, subject) {
// if (subject.isInGroup("rtkit")) {
// if (action.id.indexOf("org.freedesktop.RealtimeKit1.") == 0) {
// return polkit.Result.YES;
// }
// }
// });
'';
rtkit.enable = true;
};
2022-09-25 19:47:58 +02:00
services.pipewire = {
enable = true;
2023-10-04 00:11:11 +02:00
alsa.enable = lib.mkIf cfg.ledfx true; # required for ledfx
2022-09-25 19:47:58 +02:00
pulse.enable = true;
};
2022-06-12 17:26:32 +02:00
2022-09-28 20:29:42 +02:00
# tell Avahi to publish services like Pipewire/PulseAudio
2021-09-27 22:40:27 +02:00
services.avahi = {
enable = true;
nssmdns4 = true;
2021-09-27 22:40:27 +02:00
publish = {
enable = true;
addresses = true;
userServices = true;
};
};
sound.enable = true;
2023-12-22 22:38:33 +01:00
system.userActivationScripts.symlinkPipewireSystemdUnit.text = lib.mkIf config.c3d2.k-ot.enable /* bash */ ''
2024-02-03 19:18:47 +01:00
if [[ $USERNAME == k-ot ]]; then
2023-12-22 22:38:33 +01:00
systemctl --user enable pipewire-pulse
fi
'';
systemd = {
services = {
bluetooth-agent = lib.mkIf config.hardware.bluetooth.enable {
description = "Allow anyone to pair via Bluetooth";
wantedBy = [ "multi-user.target" ];
requires = [ "bluetooth.target" ];
after = [ "bluetooth.service" ];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.bluez-tools}/bin/bt-agent -c NoInputNoOutput";
Restart = "on-failure";
RestartSec = 60;
};
};
mpv-pause = {
script = ''
2023-12-22 00:19:13 +01:00
echo '{ "command": ["set_property", "pause", true] }' | ${lib.getExe pkgs.socat} - /tmp/mpvsocket
'';
serviceConfig = {
Type = "oneshot";
User = "root";
};
};
};
timers.mpv-pause = {
wantedBy = [ "timers.target" ];
timerConfig = {
Unit = "mpv-pause.service";
OnCalendar = "*-*-* 05:30:00";
};
};
2023-05-16 18:50:07 +02:00
user.services = {
2023-10-04 00:11:11 +02:00
ledfx = lib.mkIf cfg.ledfx {
2023-05-16 18:50:07 +02:00
after = [ "pipewire.target" ];
wantedBy = [ "default.target" ];
serviceConfig = {
2023-10-04 00:11:11 +02:00
ExecStart = lib.getExe pkgs.ledfx;
2023-05-16 18:50:07 +02:00
};
};
2023-05-16 18:50:07 +02:00
pipewire-pulse.enable = true;
};
};
2022-09-17 22:15:13 +02:00
users = {
2022-09-28 20:29:42 +02:00
groups.pulse-access = { };
users.k-ot = lib.mkIf config.c3d2.k-ot.enable {
extraGroups = [
"pipewire"
"pulse-access" # required for system wide pulseaudio
"rtkit"
];
2023-12-22 00:19:01 +01:00
linger = true;
packages = with pkgs; [
(yt-dlp.override { withAlias = true; })
];
};
2022-09-17 22:15:13 +02:00
};
2021-09-27 22:40:27 +02:00
};
}