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