Commit | Line | Data |
---|---|---|
8cd1e8e8 | 1 | ;;; GNU Guix --- Functional package management for GNU |
a66ee82a | 2 | ;;; Copyright © 2018, 2020 Oleg Pykhalov <go.wigust@gmail.com> |
719bbcc1 | 3 | ;;; Copyright © 2020 Liliana Marie Prikler <liliana.prikler@gmail.com> |
3ed94ed8 | 4 | ;;; Copyright © 2020 Marius Bakke <mbakke@fastmail.com> |
1cc9060c | 5 | ;;; Copyright © 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com> |
8cd1e8e8 OP |
6 | ;;; |
7 | ;;; This file is part of GNU Guix. | |
8 | ;;; | |
9 | ;;; GNU Guix is free software; you can redistribute it and/or modify it | |
10 | ;;; under the terms of the GNU General Public License as published by | |
11 | ;;; the Free Software Foundation; either version 3 of the License, or (at | |
12 | ;;; your option) any later version. | |
13 | ;;; | |
14 | ;;; GNU Guix is distributed in the hope that it will be useful, but | |
15 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;;; GNU General Public License for more details. | |
18 | ;;; | |
19 | ;;; You should have received a copy of the GNU General Public License | |
20 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. | |
21 | ||
22 | (define-module (gnu services sound) | |
23 | #:use-module (gnu services base) | |
24 | #:use-module (gnu services configuration) | |
25 | #:use-module (gnu services shepherd) | |
26 | #:use-module (gnu services) | |
a66ee82a | 27 | #:use-module (gnu system pam) |
8cd1e8e8 | 28 | #:use-module (gnu system shadow) |
60cb647a | 29 | #:use-module (guix diagnostics) |
8cd1e8e8 OP |
30 | #:use-module (guix gexp) |
31 | #:use-module (guix packages) | |
32 | #:use-module (guix records) | |
33 | #:use-module (guix store) | |
60cb647a | 34 | #:use-module (guix ui) |
a66ee82a | 35 | #:use-module (gnu packages audio) |
1e3861eb | 36 | #:use-module (gnu packages linux) |
8cd1e8e8 OP |
37 | #:use-module (gnu packages pulseaudio) |
38 | #:use-module (ice-9 match) | |
60cb647a | 39 | #:use-module (srfi srfi-1) |
8cd1e8e8 | 40 | #:export (alsa-configuration |
a66ee82a OP |
41 | alsa-service-type |
42 | ||
f5474262 | 43 | pulseaudio-configuration |
f1022fbf LP |
44 | pulseaudio-service-type |
45 | ||
46 | ladspa-configuration | |
47 | ladspa-service-type)) | |
8cd1e8e8 OP |
48 | |
49 | ;;; Commentary: | |
50 | ;;; | |
51 | ;;; Sound services. | |
52 | ;;; | |
53 | ;;; Code: | |
54 | ||
55 | \f | |
56 | ;;; | |
57 | ;;; ALSA | |
58 | ;;; | |
59 | ||
60 | (define-record-type* <alsa-configuration> | |
61 | alsa-configuration make-alsa-configuration alsa-configuration? | |
892f1b72 | 62 | (alsa-plugins alsa-configuration-alsa-plugins ;file-like |
1e3861eb | 63 | (default alsa-plugins)) |
8cd1e8e8 OP |
64 | (pulseaudio? alsa-configuration-pulseaudio? ;boolean |
65 | (default #t)) | |
66 | (extra-options alsa-configuration-extra-options ;string | |
67 | (default ""))) | |
68 | ||
1e3861eb OP |
69 | (define alsa-config-file |
70 | ;; Return the ALSA configuration file. | |
71 | (match-lambda | |
72 | (($ <alsa-configuration> alsa-plugins pulseaudio? extra-options) | |
73 | (apply mixed-text-file "asound.conf" | |
74 | `("# Generated by 'alsa-service'.\n\n" | |
75 | ,@(if pulseaudio? | |
76 | `("# Use PulseAudio by default | |
77 | pcm_type.pulse { | |
78 | lib \"" ,#~(string-append #$alsa-plugins:pulseaudio | |
79 | "/lib/alsa-lib/libasound_module_pcm_pulse.so") "\" | |
80 | } | |
81 | ||
82 | ctl_type.pulse { | |
83 | lib \"" ,#~(string-append #$alsa-plugins:pulseaudio | |
84 | "/lib/alsa-lib/libasound_module_ctl_pulse.so") "\" | |
85 | } | |
86 | ||
8cd1e8e8 OP |
87 | pcm.!default { |
88 | type pulse | |
89 | fallback \"sysdefault\" | |
90 | hint { | |
91 | show on | |
92 | description \"Default ALSA Output (currently PulseAudio Sound Server)\" | |
93 | } | |
94 | } | |
95 | ||
96 | ctl.!default { | |
97 | type pulse | |
98 | fallback \"sysdefault\" | |
1e3861eb OP |
99 | }\n\n") |
100 | '()) | |
101 | ,extra-options))))) | |
8cd1e8e8 OP |
102 | |
103 | (define (alsa-etc-service config) | |
104 | (list `("asound.conf" ,(alsa-config-file config)))) | |
105 | ||
106 | (define alsa-service-type | |
107 | (service-type | |
108 | (name 'alsa) | |
109 | (extensions | |
110 | (list (service-extension etc-service-type alsa-etc-service))) | |
111 | (default-value (alsa-configuration)) | |
112 | (description "Configure low-level Linux sound support, ALSA."))) | |
113 | ||
a66ee82a OP |
114 | \f |
115 | ;;; | |
116 | ;;; PulseAudio | |
117 | ;;; | |
118 | ||
f5474262 LP |
119 | (define-record-type* <pulseaudio-configuration> |
120 | pulseaudio-configuration make-pulseaudio-configuration | |
121 | pulseaudio-configuration? | |
1cc9060c | 122 | (client-conf pulseaudio-configuration-client-conf |
f5474262 | 123 | (default '())) |
1cc9060c | 124 | (daemon-conf pulseaudio-configuration-daemon-conf |
f6f91811 LP |
125 | ;; Flat volumes may cause unpleasant experiences to users |
126 | ;; when applications inadvertently max out the system volume | |
127 | ;; (see e.g. <https://bugs.gnu.org/38172>). | |
128 | (default '((flat-volumes . no)))) | |
1cc9060c | 129 | (script-file pulseaudio-configuration-script-file |
f5474262 | 130 | (default (file-append pulseaudio "/etc/pulse/default.pa"))) |
60cb647a MC |
131 | (extra-script-files pulseaudio-configuration-extra-script-files |
132 | (default '())) | |
1cc9060c | 133 | (system-script-file pulseaudio-configuration-system-script-file |
f5474262 LP |
134 | (default |
135 | (file-append pulseaudio "/etc/pulse/system.pa")))) | |
136 | ||
f5474262 LP |
137 | (define (pulseaudio-conf-entry arg) |
138 | (match arg | |
139 | ((key . value) | |
140 | (format #f "~a = ~s~%" key value)) | |
141 | ((? string? _) | |
142 | (string-append arg "\n")))) | |
143 | ||
3ed94ed8 MB |
144 | (define pulseaudio-environment |
145 | (match-lambda | |
146 | (($ <pulseaudio-configuration> client-conf daemon-conf default-script-file) | |
e680c408 MC |
147 | ;; These config files kept at a fixed location, so that the following |
148 | ;; environment values are stable and do not require the user to reboot to | |
149 | ;; effect their PulseAudio configuration changes. | |
150 | '(("PULSE_CONFIG" . "/etc/pulse/daemon.conf") | |
151 | ("PULSE_CLIENTCONFIG" . "/etc/pulse/client.conf"))))) | |
3ed94ed8 | 152 | |
60cb647a MC |
153 | (define (extra-script-files->file-union extra-script-files) |
154 | "Return a G-exp obtained by processing EXTRA-SCRIPT-FILES with FILE-UNION." | |
155 | ||
156 | (define (file-like->name file) | |
157 | (match file | |
158 | ((? local-file?) | |
159 | (local-file-name file)) | |
160 | ((? plain-file?) | |
161 | (plain-file-name file)) | |
162 | ((? computed-file?) | |
163 | (computed-file-name file)) | |
164 | (_ (leave (G_ "~a is not a local-file, plain-file or \ | |
165 | computed-file object~%") file)))) | |
166 | ||
167 | (define (assert-pulseaudio-script-file-name name) | |
168 | (unless (string-suffix? ".pa" name) | |
169 | (leave (G_ "`~a' lacks the required `.pa' file name extension~%") name)) | |
170 | name) | |
171 | ||
172 | (let ((labels (map (compose assert-pulseaudio-script-file-name | |
173 | file-like->name) | |
174 | extra-script-files))) | |
175 | (file-union "default.pa.d" (zip labels extra-script-files)))) | |
176 | ||
177 | (define (append-include-directive script-file) | |
178 | "Append an include directive to source scripts under /etc/pulse/default.pa.d." | |
179 | (computed-file "default.pa" | |
180 | #~(begin | |
181 | (use-modules (ice-9 textual-ports)) | |
182 | (define script-text | |
183 | (call-with-input-file #$script-file get-string-all)) | |
184 | (call-with-output-file #$output | |
185 | (lambda (port) | |
186 | (format port (string-append script-text " | |
187 | ### Added by Guix to include scripts specified in extra-script-files. | |
188 | .nofail | |
189 | .include /etc/pulse/default.pa.d~%"))))))) | |
190 | ||
f5474262 LP |
191 | (define pulseaudio-etc |
192 | (match-lambda | |
e680c408 MC |
193 | (($ <pulseaudio-configuration> client-conf daemon-conf default-script-file |
194 | extra-script-files system-script-file) | |
f5474262 LP |
195 | `(("pulse" |
196 | ,(file-union | |
197 | "pulse" | |
60cb647a MC |
198 | `(("default.pa" |
199 | ,(if (null? extra-script-files) | |
200 | default-script-file | |
201 | (append-include-directive default-script-file))) | |
202 | ("system.pa" ,system-script-file) | |
203 | ,@(if (null? extra-script-files) | |
204 | '() | |
205 | `(("default.pa.d" ,(extra-script-files->file-union | |
e680c408 MC |
206 | extra-script-files)))) |
207 | ,@(if (null? daemon-conf) | |
208 | '() | |
209 | `(("daemon.conf" | |
210 | ,(apply mixed-text-file "daemon.conf" | |
211 | "default-script-file = " default-script-file "\n" | |
212 | (map pulseaudio-conf-entry daemon-conf))))) | |
213 | ,@(if (null? client-conf) | |
214 | '() | |
215 | `(("client.conf" | |
216 | ,(apply mixed-text-file "client.conf" | |
217 | (map pulseaudio-conf-entry client-conf)))))))))))) | |
a66ee82a OP |
218 | |
219 | (define pulseaudio-service-type | |
220 | (service-type | |
221 | (name 'pulseaudio) | |
222 | (extensions | |
223 | (list (service-extension session-environment-service-type | |
f5474262 | 224 | pulseaudio-environment) |
fff4daa5 MC |
225 | (service-extension etc-service-type pulseaudio-etc) |
226 | (service-extension udev-service-type (const (list pulseaudio))))) | |
f5474262 | 227 | (default-value (pulseaudio-configuration)) |
a66ee82a OP |
228 | (description "Configure PulseAudio sound support."))) |
229 | ||
f1022fbf LP |
230 | \f |
231 | ;;; | |
232 | ;;; LADSPA | |
233 | ;;; | |
234 | ||
235 | (define-record-type* <ladspa-configuration> | |
236 | ladspa-configuration make-ladspa-configuration | |
237 | ladspa-configuration? | |
238 | (plugins ladspa-plugins (default '()))) | |
239 | ||
240 | (define (ladspa-environment config) | |
241 | ;; Define this variable in the global environment such that | |
242 | ;; pulseaudio swh-plugins (and similar LADSPA plugins) work. | |
243 | `(("LADSPA_PATH" . | |
244 | (string-join | |
245 | ',(map (lambda (package) (file-append package "/lib/ladspa")) | |
246 | (ladspa-plugins config)) | |
247 | ":")))) | |
248 | ||
249 | (define ladspa-service-type | |
250 | (service-type | |
251 | (name 'ladspa) | |
252 | (extensions | |
253 | (list (service-extension session-environment-service-type | |
254 | ladspa-environment))) | |
255 | (default-value (ladspa-configuration)) | |
256 | (description "Configure LADSPA plugins."))) | |
257 | ||
8cd1e8e8 | 258 | ;;; sound.scm ends here |