Subject: [bug#53676] [PATCH 4/5] services: pulseaudio: Add an extra-script-files configuration field.

From: Liliana Marie Prikler <[email-masked]>
Date: Tue, 01 Feb 2022 20:56:28 +0100

Hi,

Am Montag, dem 31.01.2022 um 23:19 -0500 schrieb Maxim Cournoyer:
> * gnu/services/sound.scm (<pulseaudio-configuration>)
> [extra-script-files]: Add field.
> (extra-script-files->file-union): Add procedure.
> (pulseaudio-etc): Use it.
> * doc/guix.texi: Document it.
> ---
>  doc/guix.texi          | 27 +++++++++++++++++++++++++++
>  gnu/services/sound.scm | 19 +++++++++++++++++--
>  2 files changed, 44 insertions(+), 2 deletions(-)
> 
> diff --git a/doc/guix.texi b/doc/guix.texi
> index a002670030..2f8df03461 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -21393,9 +21393,36 @@ List of settings to set in
> @file{daemon.conf}, formatted just like
>  @item @code{script-file} (default: @code{(file-append pulseaudio
> "/etc/pulse/default.pa")})
>  Script file to use as @file{default.pa}.
>  
> +@item @code{extra-script-files} (default: @code{'())})
> +A list of file-like objects defining extra PulseAudio scripts to run
> at
> +the initialization of the @command{pulseaudio} daemon.  For a
> reference
> +of the available 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}.
>  @end table
> +
> +The example below sets the default PulseAudio card profile, the
> default
> +sink and the default source to use for a old SoundBlaster Audigy
> sound
> +card:
> +@lisp
> +(pulseaudio-configuration
> + (extra-script-files
> +  (list (plain-file "configure-audigy-card"
> +                    (string-append "\
> +set-card-profile alsa_card.pci-0000_01_01.0 \
> +  output:analog-surround-40+input:analog-mono
> +set-default-source alsa_input.pci-0000_01_01.0.analog-mono
> +set-default-sink alsa_output.pci-0000_01_01.0.analog-surround-
> 40\n")))))
> +@end lisp
> +
> +Note that @code{pulseaudio-service-type} is part of
> +@code{%desktop-services}; if your operating system declaration was
> +derived from one of the desktop templates, you'll want to adjust the
> +above example to modify the existing @code{pulseaudio-service-type}
> via
> +@code{modify-services} (@pxref{Service Reference,
> +@code{modify-services}}), instead of defining a new one.
> +
>  @end deftp
>  
>  @deffn {Scheme Variable} ladspa-service-type
> diff --git a/gnu/services/sound.scm b/gnu/services/sound.scm
> index 19eccfc860..f529188a7c 100644
> --- a/gnu/services/sound.scm
> +++ b/gnu/services/sound.scm
> @@ -34,6 +34,7 @@ (define-module (gnu services sound)
>    #:use-module (gnu packages linux)
>    #:use-module (gnu packages pulseaudio)
>    #:use-module (ice-9 match)
> +  #:use-module (srfi srfi-1)
>    #:export (alsa-configuration
>              alsa-service-type
>  
> @@ -125,6 +126,8 @@ (define-record-type* <pulseaudio-configuration>
>                 (default '((flat-volumes . no))))
>    (script-file pulseaudio-configuration-script-file
>                 (default (file-append pulseaudio
> "/etc/pulse/default.pa")))
> +  (extra-script-files pulseaudio-configuration-extra-script-files
> +                      (default '()))
>    (system-script-file pulseaudio-configuration-system-script-file
>                        (default
>                          (file-append pulseaudio
> "/etc/pulse/system.pa"))))
> @@ -145,14 +148,26 @@ (define pulseaudio-environment
>         ("PULSE_CLIENTCONFIG" . ,(apply mixed-text-file "client.conf"
>                                         (map pulseaudio-conf-entry
> client-conf)))))))
>  
> +(define (extra-script-files->file-union extra-script-files)
> +  "Return a G-exp obtained by processing EXTRA-SCRIPT-FILES with
> FILE-UNION.
> +Each file is named \"snippet-n.pa\", where N is their 1-offset
> index."
> +  (let ((labels (map (lambda (n) (format #f "snippet-~a.pa" n))
> +                     (iota (length extra-script-files) 1))))
> +    (file-union "default.pa.d" (zip labels extra-script-files))))
> +
>  (define pulseaudio-etc
>    (match-lambda
> -    (($ <pulseaudio-configuration> _ _ default-script-file system-
> script-file)
> +    (($ <pulseaudio-configuration> _ _ default-script-file extra-
> script-files
> +                                   system-script-file)
>       `(("pulse"
>          ,(file-union
>            "pulse"
>            `(("default.pa" ,default-script-file)
> -            ("system.pa" ,system-script-file))))))))
> +            ("system.pa" ,system-script-file)
> +            ,@(if (null? extra-script-files)
> +                  '()
> +                  `(("default.pa.d" ,(extra-script-files->file-union
> +                                      extra-script-files)))))))))))
>  
>  (define pulseaudio-service-type
>    (service-type
Is there a particular use-case for this (other than working around the
location issue of default.pa et al.)?  If not, I'd rather make it s.t.
our other files can more easily be stitched together in-place.

Also, assuming that we're using file-like objects here, I think we
should use the store name minus prefix and hash for the file name. 
E.g. if Alice adds soundblaster.pa, it'd make sense to label it
soundblaster.pa, so that changes to snippet order don't mess up any
configuration referring to those files.

Cheers