From de8b977d4e62bca47f696f7f1debf69a3b9078d4 Mon Sep 17 00:00:00 2001 From: Liliana Marie Prikler Date: Wed, 4 Feb 2026 10:20:55 +0100 Subject: [PATCH] services: Generalize alsa-configuration. * gnu/packages/sound.scm (alsa-pcm-configuration, alsa-ctl-configuration): New configuration records. (serialize-alsa-pcm-configuration, serialize-alsa-ctl-configuration): New variables. (): Remove alsa-plugins and pulseaudio?. Add default-pcm and default-ctl. Rename extra-options to options. (alsa-config-file): Adjust accordingly. (alsa-servcice-type): Add compose and extend. (): Add alsa-lib. (pulseaudio-alsa-configuration): New procedure. (pulseaudio-service-type): Extend alsa-servcice-type. --- doc/guix.texi | 58 +++++++++++---- gnu/services/sound.scm | 159 ++++++++++++++++++++++++++++++----------- 2 files changed, 163 insertions(+), 54 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 44873afa2a..b0ab0c1db5 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -27878,24 +27878,47 @@ record as in this example: See below for details about @code{alsa-configuration}. @end defvar +@deftp {Data Type} alsa-pcm-configuration +Data type representing an ALSA @code{pcm} block. + +@table @asis +@item @code{alsa-pcm-configuration-type} (type: symbol) +The type of the PCM (if not builtin to alsa, should be introduced via a ``pcm_type'' block). +@item @code{alsa-pcm-configuration-hint} (type: maybe-string) +A human-readable description of the PCM. + +@item @code{alsa-pcm-configuration-configuration} (type: list-of-string) +Raw additional configuration. +Each item will be printed on a separate line. +@end table +@end deftp + +@deftp {Data Type} alsa-ctl-configuration +Data type representing an ALSA @code{ctl} block. + +@table @asis +@item @code{alsa-pcm-configuration-type} (type: symbol) +The type of the ctl (if not builtin to alsa, should be introduced via a ``ctl_type'' block). + +@item @code{alsa-pcm-configuration-configuration} (type: list-of-string) +Raw additional configuration. +Each item will be printed on a separate line. +@end table +@end deftp + @deftp {Data Type} alsa-configuration Data type representing the configuration for @code{alsa-service}. @table @asis -@item @code{alsa-plugins} (default: @var{alsa-plugins}) -@code{alsa-plugins} package to use. +@item @code{default-pcm} (default: #f) +The configuration to use for the default @code{pcm}. -@item @code{pulseaudio?} (default: @var{#t}) -Whether ALSA applications should transparently be made to use the -@uref{https://www.pulseaudio.org/, PulseAudio} sound server. - -Using PulseAudio allows you to run several sound-producing applications -at the same time and to individual control them @i{via} -@command{pavucontrol}, among other things. - -@item @code{extra-options} (default: @var{""}) -String to append to the @file{/etc/asound.conf} file. +@item @code{default-ctl} (default: #f) +The configuration to use for the default @code{ctl}. +@item @code{options} (default: '()) (type: list-of-strings) +Additional configuration strings to +append to the @file{/etc/asound.conf} file. @end table @end deftp @@ -27934,6 +27957,12 @@ pcm.!default @{ See @uref{https://www.alsa-project.org/main/index.php/Asoundrc} for the details. +Services can likewise extend alsa-service-type to add options and +configure the default PCM and CTL. One service, which transparently +extends alsa-service-type to make use of the +@uref{https://www.pulseaudio.org/, PulseAudio} sound server, +is the pulseaudio-service-type, shown below. + @defvar pulseaudio-service-type This is the type for the @uref{https://www.pulseaudio.org/, PulseAudio} sound server. It exists to allow system overrides of the default settings @@ -27985,6 +28014,11 @@ commands, refer to @command{man pulse-cli-syntax}. @item @code{system-script-file} (default: @code{(file-append pulseaudio "/etc/pulse/system.pa")}) Script file to use as @file{system.pa}. + +@item @code{alsa-lib} +The alsa-lib package to use for defining the “pulse” pcm_type +and ctl_type. + @end table The example below sets the default PulseAudio card profile, the default diff --git a/gnu/services/sound.scm b/gnu/services/sound.scm index b41ff3921b..4c31915344 100644 --- a/gnu/services/sound.scm +++ b/gnu/services/sound.scm @@ -41,11 +41,20 @@ #:use-module (gnu packages rust-apps) #:use-module (ice-9 match) #:use-module (srfi srfi-1) - #:export (alsa-configuration + #:export (alsa-pcm-configuration + alsa-pcm-configuration-type + alsa-pcm-configuration-hint + alsa-pcm-configuration-configuration + + alsa-ctl-configuration + alsa-ctl-configuration-type + alsa-ctl-configuration-configuration + + alsa-configuration alsa-configuration? - alsa-configuration-alsa-plugins - alsa-configuration-pulseaudio? - alsa-configuration-extra-options + alsa-configuration-default-ctl + alsa-configuration-default-pcm + alsa-configuration-options alsa-service-type pulseaudio-configuration @@ -81,48 +90,70 @@ ;;; ALSA ;;; +(define-maybe/no-serialization string) + +(define-configuration/no-serialization alsa-pcm-configuration + (type symbol "The PCM type.") + (hint maybe-string "A human-readable description of the PCM.") + (configuration + list-of-strings + "Additional configuration. Each item will be printed on a separate line.")) + +(define-configuration/no-serialization alsa-ctl-configuration + (type symbol "The CTL type.") + (configuration + list-of-strings + "Additional configuration. Each item will be printed on a separate line.")) + (define-record-type* alsa-configuration make-alsa-configuration alsa-configuration? - (alsa-plugins alsa-configuration-alsa-plugins ;file-like - (default alsa-plugins)) - (pulseaudio? alsa-configuration-pulseaudio? ;boolean - (default #t)) - (extra-options alsa-configuration-extra-options ;string - (default ""))) + (default-pcm alsa-configuration-default-pcm (default #f)) + (default-ctl alsa-configuration-default-ctl (default #f)) + (options alsa-configuration-options ; string + (default (list)))) + +(define (serialize-alsa-pcm-configuration config name) + (match-record config + (type hint configuration) + #~(string-append + "pcm." #$name " {\n" + " type " #$(symbol->string type) "\n" + #$(if hint + (string-append " hint { show on; description \"" hint "\" }\n") + "") + #$(if (null? configuration) "" " ") + #$(string-join configuration "\n ") + "\n}"))) + +(define (serialize-alsa-ctl-configuration config name) + (match-record config + (type configuration) + #~(string-append + "ctl." #$name " {\n" + " type " #$(symbol->string type) "\n" + #$(if (null? configuration) "" " ") + #$(string-join configuration "\n ") + "\n}"))) (define alsa-config-file ;; Return the ALSA configuration file. (match-lambda - (($ alsa-plugins pulseaudio? extra-options) - (apply mixed-text-file "asound.conf" - `("# Generated by 'alsa-service'.\n\n" - ,@(if pulseaudio? - `("# Use PulseAudio by default -pcm_type.pulse { - lib \"" ,#~(string-append #$alsa-plugins:pulseaudio - "/lib/alsa-lib/libasound_module_pcm_pulse.so") "\" -} - -ctl_type.pulse { - lib \"" ,#~(string-append #$alsa-plugins:pulseaudio - "/lib/alsa-lib/libasound_module_ctl_pulse.so") "\" -} - -pcm.!default { - type pulse - fallback \"sysdefault\" - hint { - show on - description \"Default ALSA Output (currently PulseAudio Sound Server)\" - } -} - -ctl.!default { - type pulse - fallback \"sysdefault\" -}\n\n") - '()) - ,extra-options))))) + (($ default-pcm default-ctl options) + (mixed-text-file + "asound.conf" + #~(string-join + (list + "# Generated by 'alsa-service'" + #$@options + #$@(if default-pcm + (list + (serialize-alsa-pcm-configuration default-pcm "!default")) + '()) + #$@(if default-ctl + (list + (serialize-alsa-ctl-configuration default-ctl "!default")) + '())) + "\n"))))) (define (alsa-etc-service config) (list `("asound.conf" ,(alsa-config-file config)))) @@ -132,6 +163,22 @@ ctl.!default { (name 'alsa) (extensions (list (service-extension etc-service-type alsa-etc-service))) + (compose concatenate) + (extend (lambda (config extensions) + (let* ((configs (cons config extensions)) + (options (append-map (lambda (cfg) + (alsa-configuration-options cfg)) + configs)) + (default-pcm (any (lambda (cfg) + (alsa-configuration-default-pcm cfg)) + (reverse configs))) + (default-ctl (any (lambda (cfg) + (alsa-configuration-default-ctl cfg)) + (reverse configs)))) + (alsa-configuration + (default-pcm default-pcm) + (default-ctl default-ctl) + (options options))))) (default-value (alsa-configuration)) (description "Configure low-level Linux sound support, ALSA."))) @@ -156,7 +203,10 @@ ctl.!default { (default '())) (system-script-file pulseaudio-configuration-system-script-file (default - (file-append pulseaudio "/etc/pulse/system.pa")))) + (file-append pulseaudio "/etc/pulse/system.pa"))) + (alsa-lib pulseaudio-alsa-lib + (default #~(string-append #$alsa-plugins:pulseaudio + "/lib/alsa-lib")))) (define (pulseaudio-conf-entry arg) (match arg @@ -237,11 +287,36 @@ computed-file object~%") file)))) ,(apply mixed-text-file "client.conf" (map pulseaudio-conf-entry client-conf))))))))) +(define pulseaudio-alsa-configuration + (match-record-lambda + (alsa-lib) + (list + (alsa-configuration + (default-pcm + (alsa-pcm-configuration + (type 'pulse) + (hint "Default ALSA Output (currently PulseAudio Sound Server)") + (configuration (list "fallback \"sysdefault\"")))) + (default-ctl + (alsa-ctl-configuration + (type 'pulse) + (configuration (list "fallback \"sysdefault\"")))) + (options + (list + #~(string-append "pcm_type.pulse { + lib \"" #$alsa-lib "/libasound_module_pcm_pulse.so\" +}") + #~(string-append "ctl_type.pulse { + lib \"" #$alsa-lib "/libasound_module_ctl_pulse.so\" +}"))))))) + (define pulseaudio-service-type (service-type (name 'pulseaudio) (extensions - (list (service-extension session-environment-service-type + (list (service-extension alsa-service-type + pulseaudio-alsa-configuration) + (service-extension session-environment-service-type pulseaudio-environment) (service-extension etc-service-type pulseaudio-etc) (service-extension udev-service-type (const (list pulseaudio)))))