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}