2023-12-10 01:32:42 +01:00
|
|
|
{ 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-17 23:35:53 +01:00
|
|
|
etc."pipewire/pipewire.conf.d/audio-server.conf".text =
|
2023-12-10 01:32:42 +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
|
2023-12-17 23:35:53 +01:00
|
|
|
builtins.toJSON {
|
|
|
|
"context.exec" = let
|
|
|
|
path = "${pkgs.pulseaudio}/bin/pactl";
|
|
|
|
in [ {
|
|
|
|
inherit path;
|
|
|
|
args = "load-module module-zeroconf-publish";
|
|
|
|
} {
|
|
|
|
# https://wiki.archlinux.org/title/PulseAudio/Examples#PulseAudio_over_network
|
|
|
|
inherit path;
|
|
|
|
args = "load-module module-rtp-recv latency_msec=10 sap_address=0.0.0.0";
|
|
|
|
} ];
|
2023-12-10 01:32:42 +01:00
|
|
|
"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-12-13 15:54:30 +01:00
|
|
|
"udp:9875"
|
2023-12-10 01:32:42 +01:00
|
|
|
];
|
|
|
|
};
|
2023-05-24 00:41:47 +02:00
|
|
|
};
|
|
|
|
systemPackages = with pkgs; [
|
|
|
|
mpd
|
|
|
|
mpv
|
|
|
|
ncmpcpp
|
|
|
|
ncpamixer
|
|
|
|
pulseaudio # required for pactl
|
|
|
|
somafm-cli
|
|
|
|
];
|
|
|
|
};
|
2023-04-29 23:05:39 +02:00
|
|
|
|
|
|
|
hardware = {
|
2023-05-02 21:50:50 +02:00
|
|
|
bluetooth.settings = {
|
|
|
|
Policy.AutoEnable = true;
|
|
|
|
General.DiscoverableTimeout = 0;
|
2021-09-27 22:40:27 +02:00
|
|
|
};
|
|
|
|
|
2023-04-29 23:05:39 +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
|
|
|
|
2023-04-29 23:05:39 +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
|
2023-04-29 23:05:39 +02:00
|
|
|
];
|
|
|
|
allowedUDPPorts = [
|
|
|
|
5353 # mdns
|
2023-12-13 20:35:05 +01:00
|
|
|
9875 # pulseaudio/pipewire rtp sink
|
2023-04-29 23:05:39 +02:00
|
|
|
];
|
|
|
|
};
|
|
|
|
|
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;
|
|
|
|
})
|
|
|
|
];
|
|
|
|
|
2023-05-16 23:18:07 +02:00
|
|
|
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
|
2023-05-16 23:18:07 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
});
|
2023-05-26 19:32:45 +02:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// });
|
2023-05-16 23:18:07 +02:00
|
|
|
'';
|
|
|
|
rtkit.enable = true;
|
|
|
|
};
|
2023-04-29 23:05:39 +02:00
|
|
|
|
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;
|
2023-04-29 23:05:39 +02:00
|
|
|
nssmdns = true;
|
2021-09-27 22:40:27 +02:00
|
|
|
publish = {
|
|
|
|
enable = true;
|
|
|
|
addresses = true;
|
|
|
|
userServices = true;
|
|
|
|
};
|
|
|
|
};
|
2022-03-17 23:41:24 +01:00
|
|
|
|
2023-04-29 23:05:39 +02:00
|
|
|
sound.enable = true;
|
|
|
|
|
|
|
|
systemd = {
|
2023-05-21 21:24:29 +02:00
|
|
|
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 = ''
|
|
|
|
echo '{ "command": ["set_property", "pause", true] }' | ${pkgs.socat}/bin/socat - /tmp/mpvsocket
|
|
|
|
'';
|
|
|
|
serviceConfig = {
|
|
|
|
Type = "oneshot";
|
|
|
|
User = "root";
|
|
|
|
};
|
2023-04-29 23:05:39 +02:00
|
|
|
};
|
|
|
|
};
|
2023-05-21 21:24:29 +02:00
|
|
|
|
|
|
|
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-04-29 23:05:39 +02:00
|
|
|
};
|
2023-05-16 18:50:07 +02:00
|
|
|
pipewire-pulse.enable = true;
|
2022-03-17 23:41:24 +01:00
|
|
|
};
|
|
|
|
};
|
2022-09-17 22:15:13 +02:00
|
|
|
|
|
|
|
users = {
|
2022-09-28 20:29:42 +02:00
|
|
|
groups.pulse-access = { };
|
2023-05-02 21:51:12 +02:00
|
|
|
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;
|
2023-05-02 21:51:12 +02:00
|
|
|
packages = with pkgs; [
|
|
|
|
(yt-dlp.override { withAlias = true; })
|
|
|
|
];
|
|
|
|
};
|
2022-09-17 22:15:13 +02:00
|
|
|
};
|
2021-09-27 22:40:27 +02:00
|
|
|
};
|
|
|
|
}
|