···
[ "sound" "enableOSSEmulation" ]
[ "hardware" "alsa" "enableOSSEmulation" ]
+
(lib.mkRenamedOptionModule [ "sound" "extraConfig" ] [ "hardware" "alsa" "config" ])
options.hardware.alsa = {
···
example = lib.literalExpression ''
firefox = { device = "front"; maxVolume = -25.0; };
···
+
options.hardware.alsa.enablePersistence = lib.mkOption {
+
defaultText = lib.literalExpression "config.hardware.alsa.enable";
+
default = config.hardware.alsa.enable;
+
Whether to enable ALSA sound card state saving on shutdown.
+
This is generally not necessary if you're using an external sound server.
+
# Disable sound servers enabled by default and,
+
# if the user enabled one manually, cause a conflict.
+
services.pipewire.enable = false;
+
services.pulseaudio.enable = false;
+
# Read the capture and playback device from
+
# the ALSA_AUDIO_IN, ALSA_AUDIO_OUT variables
+
vars [ ALSA_AUDIO_OUT ]
+
(lib.optional cfg.enableRecorder ''
+
pcm.!default "splitter:fromenv,recorder"
+
# Send audio to two stereo devices
+
route_policy "duplicate"
+
# Device which records and plays back audio
+
slave.pcm "hw:loopback,1,0"
+
slave.pcm "hw:loopback,0,0"
+
(lib.mapAttrsToList mkControl cfg.controls)
+
(lib.mapAttrsToList (n: v: "pcm.${n} ${quote v}") cfg.deviceAliases)
+
lib.mkBefore (lib.concatStringsSep "\n" (lib.flatten conf));
+
hardware.alsa.cardAliases = lib.mkIf cfg.enableRecorder {
+
loopback.driver = "snd_aloop";
+
# Set default PCM devices
+
environment.sessionVariables = defaultDeviceVars;
+
systemd.globalEnvironment = defaultDeviceVars;
+
environment.etc."asound.conf".text = cfg.config;
+
++ lib.optionals cfg.enableOSSEmulation [
+
++ lib.optionals cfg.enableRecorder [ "snd_aloop" ];
+
# Assign names to the sound cards
+
boot.extraModprobeConfig = lib.concatStringsSep "\n" cardsConfig;
+
# Provide alsamixer, aplay, arecord, etc.
+
environment.systemPackages = [ pkgs.alsa-utils ];
+
(lib.mkIf config.hardware.alsa.enablePersistence {
+
# Install udev rules for restoring card settings on boot
+
services.udev.extraRules = ''
+
ACTION=="add", SUBSYSTEM=="sound", KERNEL=="controlC*", KERNELS!="card*", GOTO="alsa_restore_go"
+
GOTO="alsa_restore_end"
+
LABEL="alsa_restore_go"
+
TEST!="/etc/alsa/state-daemon.conf", RUN+="${alsactl} restore -gU $attr{device/number}"
+
TEST=="/etc/alsa/state-daemon.conf", RUN+="${alsactl} nrestore -gU $attr{device/number}"
+
LABEL="alsa_restore_end"
+
# Service to store/restore the sound card settings
+
systemd.services.alsa-store = {
+
description = "Store Sound Card State";
+
wantedBy = [ "multi-user.target" ];
+
restartIfChanged = false;
+
RequiresMountsFor = "/var/lib/alsa";
+
ConditionVirtualization = "!systemd-nspawn";
+
RemainAfterExit = true;
+
StateDirectory = "alsa";
+
# Note: the service should never be restated, otherwise any
+
# setting changed between the last `store` and now will be lost.
+
# To prevent NixOS from starting it in case it has failed we
+
# expand the exit codes considered successful
+
ExecStart = "${alsactl} restore -gU";
+
ExecStop = "${alsactl} store -gU";
meta.maintainers = with lib.maintainers; [ rnhmjoj ];