1# ALSA sound support. 2{ config, lib, pkgs, ... }: 3 4with lib; 5 6let 7 8 inherit (pkgs) alsaUtils; 9 10in 11 12{ 13 14 ###### interface 15 16 options = { 17 18 sound = { 19 20 enable = mkOption { 21 type = types.bool; 22 default = true; 23 description = '' 24 Whether to enable ALSA sound. 25 ''; 26 }; 27 28 enableOSSEmulation = mkOption { 29 type = types.bool; 30 default = true; 31 description = '' 32 Whether to enable ALSA OSS emulation (with certain cards sound mixing may not work!). 33 ''; 34 }; 35 36 enableMediaKeys = mkOption { 37 type = types.bool; 38 default = false; 39 description = '' 40 Whether to enable volume and capture control with keyboard media keys. 41 42 Enabling this will turn on <option>services.actkbd</option>. 43 ''; 44 }; 45 46 extraConfig = mkOption { 47 type = types.lines; 48 default = ""; 49 example = '' 50 defaults.pcm.!card 3 51 ''; 52 description = '' 53 Set addition configuration for system-wide alsa. 54 ''; 55 }; 56 57 }; 58 59 }; 60 61 62 ###### implementation 63 64 config = mkIf config.sound.enable { 65 66 environment.systemPackages = [ alsaUtils ]; 67 68 environment.etc = mkIf (config.sound.extraConfig != "") 69 [ 70 { source = pkgs.writeText "asound.conf" config.sound.extraConfig; 71 target = "asound.conf"; 72 } 73 ]; 74 75 # ALSA provides a udev rule for restoring volume settings. 76 services.udev.packages = [ alsaUtils ]; 77 78 boot.kernelModules = optional config.sound.enableOSSEmulation "snd_pcm_oss"; 79 80 systemd.services."alsa-store" = 81 { description = "Store Sound Card State"; 82 wantedBy = [ "multi-user.target" ]; 83 unitConfig.RequiresMountsFor = "/var/lib/alsa"; 84 unitConfig.ConditionVirtualization = "!systemd-nspawn"; 85 serviceConfig = { 86 Type = "oneshot"; 87 RemainAfterExit = true; 88 ExecStart = "${pkgs.coreutils}/bin/mkdir -p /var/lib/alsa"; 89 ExecStop = "${alsaUtils}/sbin/alsactl store --ignore"; 90 }; 91 }; 92 93 services.actkbd = mkIf config.sound.enableMediaKeys { 94 enable = true; 95 bindings = [ 96 # "Mute" media key 97 { keys = [ 113 ]; events = [ "key" ]; command = "${alsaUtils}/bin/amixer -q set Master toggle"; } 98 99 # "Lower Volume" media key 100 { keys = [ 114 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master 1- unmute"; } 101 102 # "Raise Volume" media key 103 { keys = [ 115 ]; events = [ "key" "rep" ]; command = "${alsaUtils}/bin/amixer -q set Master 1+ unmute"; } 104 105 # "Mic Mute" media key 106 { keys = [ 190 ]; events = [ "key" ]; command = "${alsaUtils}/bin/amixer -q set Capture toggle"; } 107 ]; 108 }; 109 110 }; 111 112}