~ruther/guix-local

afdbf7f271529573397474fdb8f1c9d00dceba37 — Brian Cully 2 years ago a4a14ab
gnu: home: Add home-pipewire service.

This adds a set of home Shepherd services which will start the required
services for a functional PipeWire setup.

* gnu/home/services/sound.scm (home-pipewire-shepherd-service,
home-wireplumber-shepherd-service, home-pipewire-shepherd-services,
home-pipewire-asoundrc, home-pipewire-xdg-configuration,
home-pipewire-pulseaudio-shepherd-service): New procedures.
(home-pipewire-service-type): New service type.
(home-pipewire-configuration): New struct.
(home-pipewire-disable-pulseaudio-auto-start): New variable.
* doc/guix.texi (Sound Home Services): Document it.

Change-Id: I99e0ae860de91d459c3c554ec5503bf35f785a2a
Signed-off-by: Oleg Pykhalov <go.wigust@gmail.com>
2 files changed, 173 insertions(+), 1 deletions(-)

M doc/guix.texi
M gnu/home/services/sound.scm
M doc/guix.texi => doc/guix.texi +72 -0
@@ 45069,6 45069,7 @@ sound support.

@cindex PulseAudio, home service
@cindex RTP, for PulseAudio
@subsubheading PulseAudio RTP Streaming Services

The following services dynamically reconfigure the
@uref{https://pulseaudio.org,PulseAudio sound server}: they let you


@@ 45156,6 45157,77 @@ Stopping the Shepherd service turns off broadcasting.
This is the multicast address used by default by the two services above.
@end defvar

@cindex PipeWire, home service
@subsubheading PipeWire Home Service

@uref{https://pipewire.org, PipeWire} provides a low-latency,
graph-based audio and video processing service.  In addition to its
native protocol, it can also be used as a replacement for both JACK and
PulseAudio.

While PipeWire provides the media processing and API, it does not,
directly, know about devices such as sound cards, nor how you might want
to connect applications, hardware, and media processing filters.
Instead, PipeWire relies on a @dfn{session manager} to specify all these
relationships.  While you may use any session manager you wish, for most
people the @url{https://pipewire.pages.freedesktop.org/wireplumber/,
WirePlumber} session manager, a reference implementation provided by the
PipeWire project itself, suffices, and that is the one
@code{home-pipewire-service-type} uses.

PipeWire can be used as a replacement for PulseAudio by setting
@code{enable-pulseaudio?} to @code{#t} in
@code{home-pipewire-configuration}, so that existing PulseAudio clients
may use it without any further configuration.

In addition, JACK clients may connect to PipeWire by using the
@command{pw-jack} program, which comes with PipeWire.  Simply prefix the
command with @command{pw-jack} when you run it, and audio data should go
through PipeWire:

@example
pw-jack mpv -ao=jack sound-file.wav
@end example

For more information on PulseAudio emulation, see
@uref{https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio},
for JACK, see
@uref{https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-JACK}.

As PipeWire does not use @code{dbus} to start its services on demand
(as PulseAudio does), @code{home-pipewire-service-type} uses Shepherd
to start services when logged in, provisioning the @code{pipewire},
@code{wireplumber}, and, if configured, @code{pipewire-pulseaudio}
services.  @xref{Shepherd Home Service}.

@defvar home-pipewire-service-type
This provides the service definition for @command{pipewire}, which will
run on login.  Its value is a @code{home-pipewire-configuration} object.

To start the service, add it to the @code{service} field of your
@code{home-environment}, such as:

@lisp
(service home-pipewire-service-type)
@end lisp
@end defvar

@deftp {Data Type} home-pipewire-configuration
Available @code{home-pipewire-configuration} fields are:

@table @asis
@item @code{pipewire} (default: @code{pipewire}) (type: file-like)
The PipeWire package to use.

@item @code{wireplumber} (default: @code{wireplumber}) (type: file-like)
The WirePlumber package to use.

@item @code{enable-pulseaudio?} (default: @code{#t}) (type: boolean)
When true, enable PipeWire's PulseAudio emulation support, allowing
PulseAudio clients to use PipeWire transparently.
@end table
@end deftp

@node Mail Home Services
@subsection Mail Home Services
 

M gnu/home/services/sound.scm => gnu/home/services/sound.scm +101 -1
@@ 1,5 1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2023 Brian Cully <bjc@spork.org>
;;;
;;; This file is part of GNU Guix.
;;;


@@ 19,13 20,112 @@
(define-module (gnu home services sound)
  #:use-module (gnu home services)
  #:use-module (gnu home services shepherd)
  #:use-module (gnu home services xdg)
  #:use-module (gnu packages linux)
  #:use-module (gnu services configuration)
  #:use-module (guix records)
  #:use-module (guix gexp)
  #:use-module (srfi srfi-1)
  #:use-module (ice-9 match)
  #:export (home-pulseaudio-rtp-sink-service-type
            home-pulseaudio-rtp-source-service-type
            %pulseaudio-rtp-multicast-address))
            %pulseaudio-rtp-multicast-address

            home-pipewire-configuration
            home-pipewire-service-type))


;;;
;;; PipeWire support.
;;;

(define-configuration/no-serialization home-pipewire-configuration
  (pipewire
   (file-like pipewire)
   "The PipeWire package to use.")
  (wireplumber
   (file-like wireplumber)
   "The WirePlumber package to use.")
  (enable-pulseaudio?
   (boolean #t)
   "When true, enable PipeWire's PulseAudio emulation support, allowing
PulseAudio clients to use PipeWire transparently."))

(define (home-pipewire-shepherd-service config)
  (shepherd-service
   (documentation "PipeWire media processing.")
   (provision '(pipewire))
   (requirement '(dbus))
   (start #~(make-forkexec-constructor
             (list #$(file-append
                      (home-pipewire-configuration-pipewire config)
                      "/bin/pipewire"))))
   (stop #~(make-kill-destructor))))

(define (home-pipewire-pulseaudio-shepherd-service config)
  (shepherd-service
   (documentation "Drop-in PulseAudio replacement service for PipeWire.")
   (provision '(pipewire-pulseaudio))
   (requirement '(pipewire))
   (start #~(make-forkexec-constructor
             (list #$(file-append
                      (home-pipewire-configuration-pipewire config)
                      "/bin/pipewire-pulse"))))
   (stop #~(make-kill-destructor))))

(define (home-wireplumber-shepherd-service config)
  (shepherd-service
   (documentation "WirePlumber session management for PipeWire.")
   (provision '(wireplumber))
   (requirement '(pipewire))
   (start #~(make-forkexec-constructor
             (list #$(file-append
                      (home-pipewire-configuration-wireplumber config)
                      "/bin/wireplumber"))))
   (stop #~(make-kill-destructor))))

(define (home-pipewire-shepherd-services config)
  (cons* (home-pipewire-shepherd-service config)
         (home-wireplumber-shepherd-service config)
         (if (home-pipewire-configuration-enable-pulseaudio? config)
             (list (home-pipewire-pulseaudio-shepherd-service config))
             '())))

(define (home-pipewire-asoundrc config)
  (match-record config <home-pipewire-configuration>
                (pipewire)
    (mixed-text-file
     "asoundrc"
     "<" pipewire "/share/alsa/alsa.conf.d/50-pipewire.conf>\n"
     "<" pipewire "/share/alsa/alsa.conf.d/99-pipewire-default.conf>\n"
     "pcm_type.pipewire {\n"
     "  lib \"" pipewire "/lib/alsa-lib/libasound_module_pcm_pipewire.so\"\n"
     "}\n"
     "ctl_type.pipewire {\n"
     "  lib \"" pipewire "/lib/alsa-lib/libasound_module_ctl_pipewire.so\"\n"
     "}\n")))

(define home-pipewire-disable-pulseaudio-auto-start
  (plain-file "client.conf" "autospawn = no"))

(define (home-pipewire-xdg-configuration config)
  (cons* `("alsa/asoundrc" ,(home-pipewire-asoundrc config))
         (if (home-pipewire-configuration-enable-pulseaudio? config)
             `(("pulse/client.conf"
                ,home-pipewire-disable-pulseaudio-auto-start))
             '())))

(define home-pipewire-service-type
  (service-type
   (name 'pipewire)
   (extensions
    (list (service-extension home-shepherd-service-type
                             home-pipewire-shepherd-services)
          (service-extension home-xdg-configuration-files-service-type
                             home-pipewire-xdg-configuration)))
   (description
    "Start essential PipeWire services.")
   (default-value (home-pipewire-configuration))))


;;;