diff mbox series

[bug#63863] gnu: home: Add support for home-pipewire-service

Message ID 13252a733171e18f4d39d0185ddf3e8e3c06bc15.1685747062.git.bjc@spork.org
State New
Headers show
Series [bug#63863] gnu: home: Add support for home-pipewire-service | expand

Commit Message

Brian Cully June 2, 2023, 11:04 p.m. UTC
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-pipewire-pulse-shepherd-service), (home-wireplumber-shepherd-service),
(home-pipewire-shepherd-services), (generate-doc): new procedures.
(home-pipewire-service-type): new service type.
(home-pipewire-configuration): new struct.
* doc/guix.texi (Sound Home Services): document it.
---
 doc/guix.texi               | 34 +++++++++++++++++
 gnu/home/services/sound.scm | 74 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 107 insertions(+), 1 deletion(-)


base-commit: c11b92a8aae6fe7fad0da8257ec28f5009c37b35

Comments

Ludovic Courtès June 9, 2023, 8:22 p.m. UTC | #1
Hi,

Brian Cully <bjc@spork.org> skribis:

> 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-pipewire-pulse-shepherd-service), (home-wireplumber-shepherd-service),
> (home-pipewire-shepherd-services), (generate-doc): new procedures.
> (home-pipewire-service-type): new service type.
> (home-pipewire-configuration): new struct.
> * doc/guix.texi (Sound Home Services): document it.

[...]

> +@cindex 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.

Could you explain why a Home service is necessary (I’d expect it to be
started on-demand via D-Bus or similar, like PulseAudio)?

Also, please leave two spaces after end-of-sentence periods (this eases
navigation in Emacs).

> +@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.

Could you add a few words saying what each of these packages does,
especially the second one.

> +@item @code{enable-pulseaudio?} (default: @code{#t}) (type: boolean)
> +Enable PulseAudio replacement.

Maybe add: “When true, PulseAudio applications will talk to PipeWire,
which will handle them as if they were ``native'' PipeWire
applications.” (I’m making it up, but you get the idea.)

> +;;; PipeWire support.
> +;;;
> +(define-configuration/no-serialization home-pipewire-configuration

Please leave an empty line after the comment.

> +(define (home-pipewire-shepherd-service config)
> +  (shepherd-service
> +   (documentation "PipeWire screen and audio sharing.")
> +   (provision '(pipewire))
> +   (requirement '(dbus))
> +   (start #~(make-forkexec-constructor
> +             (list #$(file-append
> +                      (home-pipewire-configuration-pipewire config)
> +                      "/bin/pipewire"))))))

Please add the ‘stop’ method or the process will never be stopped.  :-)

> +   (start #~(make-forkexec-constructor
> +             (list #$(file-append
> +                      (home-pipewire-configuration-pipewire config)
> +                      "/bin/pipewire-pulse"))))))

Same here…

> +   (start #~(make-forkexec-constructor
> +             (list #$(file-append
> +                      (home-pipewire-configuration-wireplumber config)
> +                      "/bin/wireplumber"))))))

… and here.


> +(define (home-pipewire-shepherd-services config)
> +  (define shepherd-services
> +    (filter
> +     identity
> +     (list home-pipewire-shepherd-service home-wireplumber-shepherd-service
> +           (and (home-pipewire-configuration-enable-pulseaudio? config)
> +                home-pipewire-pulseaudio-shepherd-service))))
> +  (map (cut <> config) shepherd-services))

Rather:

  (cons* (home-pipewire-shepherd-service config)
         (home-wireplumber-shepherd-service config)
         (if …
             (list (home-pipewire-pulseaudio-shepherd-service config))
             '()))

> +   (description
> +    "Start essential PipeWire services.")

Can you add a couple of sentences?  That’s useful when running ‘guix
home search’ or similar.

> +
> +
> +;;;
> +;;; Generate documentation.
> +;;;
> +(define (generate-doc)
> +  (configuration->documentation 'home-pipewire-configuration))

This is unused, please remove it.

Could you send a v2?

Thanks!

Ludo’.
Andrew Tropin June 12, 2023, 5:50 a.m. UTC | #2
On 2023-06-02 19:04, Brian Cully via Guix-patches via wrote:

> 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-pipewire-pulse-shepherd-service), (home-wireplumber-shepherd-service),
> (home-pipewire-shepherd-services), (generate-doc): new procedures.
> (home-pipewire-service-type): new service type.
> (home-pipewire-configuration): new struct.
> * doc/guix.texi (Sound Home Services): document it.
> ---
>  doc/guix.texi               | 34 +++++++++++++++++
>  gnu/home/services/sound.scm | 74 ++++++++++++++++++++++++++++++++++++-
>  2 files changed, 107 insertions(+), 1 deletion(-)
>
> diff --git a/doc/guix.texi b/doc/guix.texi
> index 7f8d8d66e9..0b19c9301f 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -116,6 +116,7 @@
>  Copyright @copyright{} 2023 Karl Hallsby@*
>  Copyright @copyright{} 2023 Nathaniel Nicandro@*
>  Copyright @copyright{} 2023 Tanguy Le Carrour@*
> +Copyright @copyright{} 2023 Brian Cully@*
>  
>  Permission is granted to copy, distribute and/or modify this document
>  under the terms of the GNU Free Documentation License, Version 1.3 or
> @@ -43563,6 +43564,39 @@ Sound Home Services
>  This is the multicast address used by default by the two services above.
>  @end defvar
>  
> +@cindex 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.
> +
> +@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
> +
> +@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)
> +Enable PulseAudio replacement.
> +@end table
> +@end deftp
> +
>  @node Mail Home Services
>  @subsection Mail Home Services
>   
> diff --git a/gnu/home/services/sound.scm b/gnu/home/services/sound.scm
> index 22c1a99250..94d8bc7482 100644
> --- a/gnu/home/services/sound.scm
> +++ b/gnu/home/services/sound.scm
> @@ -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,77 @@
>  (define-module (gnu home services sound)
>    #:use-module (gnu home services)
>    #:use-module (gnu home services shepherd)
> +  #: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 (srfi srfi-26)
>    #: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) "Enable PulseAudio replacement."))
> +
> +(define (home-pipewire-shepherd-service config)
> +  (shepherd-service
> +   (documentation "PipeWire screen and audio sharing.")

The description seems a little bit missleading, while PipeWire can do
screensharing, it's not only or even primary role.

> +   (provision '(pipewire))
> +   (requirement '(dbus))
> +   (start #~(make-forkexec-constructor
> +             (list #$(file-append
> +                      (home-pipewire-configuration-pipewire config)
> +                      "/bin/pipewire"))))))
> +
> +(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"))))))
> +
> +(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"))))))
> +
> +(define (home-pipewire-shepherd-services config)
> +  (define shepherd-services
> +    (filter
> +     identity
> +     (list home-pipewire-shepherd-service home-wireplumber-shepherd-service
> +           (and (home-pipewire-configuration-enable-pulseaudio? config)
> +                home-pipewire-pulseaudio-shepherd-service))))
> +  (map (cut <> config) shepherd-services))
> +
> +(define home-pipewire-service-type
> +  (service-type
> +   (name 'pipewire)
> +   (extensions
> +    (list (service-extension home-shepherd-service-type
> +                             home-pipewire-shepherd-services)))
> +   (description
> +    "Start essential PipeWire services.")
> +   (default-value (home-pipewire-configuration))))
>  
>  
>  ;;;
> @@ -149,3 +214,10 @@ (define home-pulseaudio-rtp-source-service-type
>      "Define a PulseAudio source to receive audio broadcasted over RTP by
>  another PulseAudio instance.")
>     (default-value %pulseaudio-rtp-multicast-address)))
> +
> +
> +;;;
> +;;; Generate documentation.
> +;;;
> +(define (generate-doc)
> +  (configuration->documentation 'home-pipewire-configuration))
>
> base-commit: c11b92a8aae6fe7fad0da8257ec28f5009c37b35

Hi Brian,

Thank you for the patch!  You may also want to add pipewire backend for
alsa:
https://git.sr.ht/~abcdw/rde/tree/525f8c7f25783c6b8fa55f21c8e62237bc0d4a04/src/rde/features/linux.scm#L100
Brian Cully June 12, 2023, 3:56 p.m. UTC | #3
Andrew Tropin <andrew@trop.in> writes:
>> +(define (home-pipewire-shepherd-service config)
>> +  (shepherd-service
>> +   (documentation "PipeWire screen and audio sharing.")
>
> The description seems a little bit missleading, while PipeWire 
> can do
> screensharing, it's not only or even primary role.

I'm not sure I understand the objection. Would you rather I 
mention its audio capabilities before screen sharing? Or would 
something like "PipeWire media processing" seem to suit it better 
for you?

Truth be told, I find succinctly describing PipeWire for this 
context to be pretty difficult. It does a lot, and it's all pretty 
abstract. PipeWire is just plumbing for services people actually 
care about, and I don't think "PipeWire make media worky" is going 
to fly 😉.

> Thank you for the patch!  You may also want to add pipewire 
> backend for
> alsa:
> https://git.sr.ht/~abcdw/rde/tree/525f8c7f25783c6b8fa55f21c8e62237bc0d4a04/src/rde/features/linux.scm#L100

Thanks for the pointer. I'll try to dig through the documentation 
to see what I can do. I find the Linux sound ecosystem to be 
pretty confusing. For instance: I thought ALSA was the backend 
that PipeWire used on Linux already, so I don't understand how 
ALSA can also use PipeWire as a backend.

My use for this patch was Wayland-motivated, and everything 
outside of basic functionality (screen sharing and playing audio 
from Firefox and MPD) wasn't something I spent much time on — 
since I really don't know much about it — in the hopes that we 
could provide a minimum level of service for people and add better 
support as people needed it as time went on.

-bjc
Andrew Tropin June 13, 2023, 4:39 a.m. UTC | #4
On 2023-06-12 11:56, Brian Cully wrote:

> Andrew Tropin <andrew@trop.in> writes:
>>> +(define (home-pipewire-shepherd-service config)
>>> +  (shepherd-service
>>> +   (documentation "PipeWire screen and audio sharing.")
>>
>> The description seems a little bit missleading, while PipeWire 
>> can do
>> screensharing, it's not only or even primary role.
>
> I'm not sure I understand the objection. Would you rather I 
> mention its audio capabilities before screen sharing?

Nope.

> Or would something like "PipeWire media processing" seem to suit it
> better for you?

Yep.

> Truth be told, I find succinctly describing PipeWire for this 
> context to be pretty difficult. It does a lot, and it's all pretty 
> abstract. PipeWire is just plumbing for services people actually 
> care about, and I don't think "PipeWire make media worky" is going 
> to fly 😉.
>

"PipeWire make media worky" would work great! :D jk

Real-time multimedia capturing, processing and playback or low-latency,
graph-based audio and video processing engine or something like that.

>> Thank you for the patch!  You may also want to add pipewire 
>> backend for
>> alsa:
>> https://git.sr.ht/~abcdw/rde/tree/525f8c7f25783c6b8fa55f21c8e62237bc0d4a04/src/rde/features/linux.scm#L100
>
> Thanks for the pointer. I'll try to dig through the documentation 
> to see what I can do. I find the Linux sound ecosystem to be 
> pretty confusing. For instance: I thought ALSA was the backend 
> that PipeWire used on Linux already, so I don't understand how 
> ALSA can also use PipeWire as a backend.
>
> My use for this patch was Wayland-motivated, and everything 
> outside of basic functionality (screen sharing and playing audio 
> from Firefox and MPD) wasn't something I spent much time on — 
> since I really don't know much about it — in the hopes that we 
> could provide a minimum level of service for people and add better 
> support as people needed it as time went on.

Yep, we have similiar use cases in rde and configuration mentioned
earlier serves them quite well.  According to Alsa: I don't have deep
knowledge in this area too, but according to my knowledge pipewire can
be loaded as a shared library and injected into alsa user-facing API to
process requests, so maybe a backend for ALSA-based applications or
middleend for ALSA will be more apropriate name for the pipewire role
here :)

Anyway, without the config above alsamixer doesn't work on my system,
probably with some configuration it's possible to make it work, but
bypassing pipewire, however I think it would be nice to go full
pipewire.
Brian Cully June 13, 2023, 12:20 p.m. UTC | #5
Andrew Tropin <andrew@trop.in> writes:
>> Or would something like "PipeWire media processing" seem to 
>> suit it
>> better for you?
>
> Yep.

Works for me.

> Anyway, without the config above alsamixer doesn't work on my 
> system,
> probably with some configuration it's possible to make it work, 
> but
> bypassing pipewire, however I think it would be nice to go full
> pipewire.

I've just tried using ‘alsamixer’ from the ‘alsa-utils’ package 
this morning, and it works for me without any additional 
configuration. It shows both ‘Card’ and ‘Chip’ to be ‘PulseAudio’, 
and volume control works. Although, that is with PulseAudio 
emulation enabled. Should the ALSA configuration always be added? 
Or just if it's enabled in configuration (possibly defaulting #t)?

-bjc
Andrew Tropin June 14, 2023, 9:08 a.m. UTC | #6
On 2023-06-13 08:20, Brian Cully wrote:

> Andrew Tropin <andrew@trop.in> writes:
>>> Or would something like "PipeWire media processing" seem to 
>>> suit it
>>> better for you?
>>
>> Yep.
>
> Works for me.
>
>> Anyway, without the config above alsamixer doesn't work on my 
>> system,
>> probably with some configuration it's possible to make it work, 
>> but
>> bypassing pipewire, however I think it would be nice to go full
>> pipewire.
>
> I've just tried using ‘alsamixer’ from the ‘alsa-utils’ package 
> this morning, and it works for me without any additional 
> configuration. It shows both ‘Card’ and ‘Chip’ to be ‘PulseAudio’, 
> and volume control works. Although, that is with PulseAudio 
> emulation enabled.

With config mentioned earlier it shows PipeWire in Card and Chip.

> Should the ALSA configuration always be added?  Or just if it's
> enabled in configuration (possibly defaulting #t)?

Yep, I think it should be always added by default.

Also, it make sense to disable autospawn of pulseaudio to prevent
accidential interference.

Like this:
https://git.sr.ht/~abcdw/rde/tree/4365d81c0775beb0f623b756423e17275dbb2d00/src/rde/features/linux.scm#L128
Tanguy LE CARROUR Aug. 23, 2023, 8:25 a.m. UTC | #7
Hi Brian,

I came across you patch by chance and, as I had been waiting for a
PipeWire home service for a long time, I couldn't resist trying it out!

I copied it to my channel, added it to my home configuration,
reconfigured and… go this message:

```
guix home: error: service 'pipewire' requires 'dbus', which is not provided by any service
```

I was a little confused, because in the documentation, you wrote
"As PipeWire does not use @code{dbus} to start its services on demand".

I added it anyway, reconfigured and after rebooting (I currently have a
problem with shepherd not being properly reloaded! 😞) I can see
the new services as being "stopped" in `herd status` output.
Are they stopped on purpose? Who is supposed to start them?
Sorry, I'm not sure I understand how it's supposed to work.
I've tried joining a JitsiMeet conference. The video seems to be
working, but my mic‘ is marked as "broken".

I've had to roll back my home configuration for the time being,
but if there are more things I can try to make it work and help your
patch being merged, I would be more than happy to try them!

Anyway, thanks for you work on this patch! Can't wait for it to be
merged.
Brian Cully Aug. 23, 2023, 6:44 p.m. UTC | #8
Tanguy LE CARROUR <tanguy@bioneland.org> writes:

> I came across you patch by chance and, as I had been waiting for a
> PipeWire home service for a long time, I couldn't resist trying it out!

Thanks for helping test it!

> I copied it to my channel, added it to my home configuration,
> reconfigured and… go this message:
>
> ```
> guix home: error: service 'pipewire' requires 'dbus', which is not provided by any service
> ```
>
> I was a little confused, because in the documentation, you wrote
> "As PipeWire does not use @code{dbus} to start its services on demand".

Pipewire does not use dbus to start its services on demand, but it does
use it for communication between the pipewire daemon itself and the
session manager (typically wireplumber).

I guess this is confusing. I'll see if I can explain this
better. Although part of me wants to drop the dbus verbiage from the
documentation entirely, since it only exists right now to explain things
to people who might be migrating from Pulseaudio and used to not needing
a Shepherd service. I don't want to write a deep explainer on how DBus
is used. It's not the place for that, nor do I even know that much about
it.

> I added it anyway, reconfigured and after rebooting (I currently have a
> problem with shepherd not being properly reloaded! 😞) I can see
> the new services as being "stopped" in `herd status` output.
> Are they stopped on purpose? Who is supposed to start them?

The services should all start automatically, but they do all depend on
a user-session level dbus daemon running. I see you're using dbus, but
are you using it from ‘home-dbus-service-type’?

> Sorry, I'm not sure I understand how it's supposed to work.
> I've tried joining a JitsiMeet conference. The video seems to be
> working, but my mic‘ is marked as "broken".

If video sharing under Wayland is working, then I'd say that means
Pipewire+Wireguard are working. The mic doesn't work, but can you hear
audio through your speakers or headphones? Are your audio devices
visible? Are you using Pulseaudio emulation (which I recommend you do)?

> Anyway, thanks for you work on this patch! Can't wait for it to be
> merged.

/me pokes Ludo 😉

-bjc
Tanguy LE CARROUR Aug. 25, 2023, 6:44 a.m. UTC | #9
Hi Brian,


Quoting brian (2023-08-23 20:44:55)
> Tanguy LE CARROUR <tanguy@bioneland.org> writes:
> > I copied it to my channel, added it to my home configuration,
> > reconfigured and… go this message:
> >
> > ```
> > guix home: error: service 'pipewire' requires 'dbus', which is not provided by any service
> > ```
> >
> > I was a little confused, because in the documentation, you wrote
> > "As PipeWire does not use @code{dbus} to start its services on demand".
> 
> Pipewire does not use dbus to start its services on demand, but it does
> use it for communication between the pipewire daemon itself and the
> session manager (typically wireplumber).
> 
> I guess this is confusing. I'll see if I can explain this
> better. Although part of me wants to drop the dbus verbiage from the
> documentation entirely, since it only exists right now to explain things
> to people who might be migrating from Pulseaudio and used to not needing
> a Shepherd service. I don't want to write a deep explainer on how DBus
> is used. It's not the place for that, nor do I even know that much about
> it.

It's a bit confusing, indeed! … but I'm easily confused! 😅
What would be great would a mechanism to "pull/manage" service dependencies.


> > I added it anyway, reconfigured and after rebooting (I currently have a
> > problem with shepherd not being properly reloaded! 😞) I can see
> > the new services as being "stopped" in `herd status` output.
> > Are they stopped on purpose? Who is supposed to start them?
> 
> The services should all start automatically, but they do all depend on
> a user-session level dbus daemon running. I see you're using dbus, but
> are you using it from ‘home-dbus-service-type’?

Yes, I added it in my home configuration.


> > Sorry, I'm not sure I understand how it's supposed to work.
> > I've tried joining a JitsiMeet conference. The video seems to be
> > working, but my mic‘ is marked as "broken".
> 
> If video sharing under Wayland is working, then I'd say that means
> Pipewire+Wireguard are working. The mic doesn't work, but can you hear
> audio through your speakers or headphones? Are your audio devices
> visible? Are you using Pulseaudio emulation (which I recommend you do)?

I'll give it another try at the week-end! 🤞


> > Anyway, thanks for you work on this patch! Can't wait for it to be
> > merged.
> 
> /me pokes Ludo 😉

Poke poke 👉
taosabella@riseup.net Oct. 11, 2023, 11:34 a.m. UTC | #10
I've tested this patch and it works perfectly, with all Shepherd
services starting after activation and a reboot. Ludovic, are there any
other blockers to getting this into Guix proper?
Brian Cully Dec. 16, 2023, 3:17 p.m. UTC | #11

Hilton Chain <hako@ultrarare.space> writes:

> I'd prefer the following:
> 
> (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")))
> 
> 
> or:
> 
> (define (home-pipewire-asoundrc config)
>  (match-record config <home-pipewire-configuration>
>    (pipewire)
>    (mixed-text-file
>     "asoundrc"
>     #~(begin
>         (use-modules (ice-9 format))
>         (format #f "~
> <~a/share/alsa/alsa.conf.d/50-pipewire.conf>
> <~@*~a/share/alsa/alsa.conf.d/99-pipewire-default.conf>
> pcm_type.pipewire {
>  lib \"~@*~a/lib/alsa-lib/libasound_module_pcm_pipewire.so\"
> }
> ctl_type.pipewire {
>  lib \"~@*~a/lib/alsa-lib/libasound_module_ctl_pipewire.so\"
> }~%" #$pipewire)))))

I prefer the former to the latter; I often find ‘format’ strings to be pretty confusing, and the documentation doesn't tend to help much. I know I'm not alone in this, and since this is fairly simple, I'll use the straight concatenation, which has the additional benefit of preserving indentation.

> One thing to note: the wireplumber package is built with elogind integration, so
> it fails to start when elogind is not present:
> 
> [wireplumber] failed to start systemd logind monitor: -2 (No such file or directory)
> 
> I think we can add a wireplumber variant built with "-Delogind=disabled" and
> maybe mention it in the documentation.

Sounds reasonable. I don't know how long wireplumber has been able to be built without systemd stuff, just that I tried running it with seatd/greetd and it failed. Have you got it working without elogind?

I'm not sure when I'll be able to have a look at it, so I'd rather the current patch go in, and we can add elogind-less variants afterwards.

--
-bjc
Brian Cully Dec. 22, 2023, 3:22 p.m. UTC | #12
help-debbugs@gnu.org (GNU bug Tracking System) writes:

> Your bug report
>
> #63863: [PATCH] gnu: home: Add support for home-pipewire-service
>
> which was filed against the guix-patches package, has been 
> closed.

Was this intentional?

> The ‘home-pipewire-pulse-shepherd-service’ procedure is 
> missing. Do you
> have a code for this procedure or should it be removed from the 
> commit
> message?  The PipeWire service seems to work without it.

I'd renamed it to ‘home-pulseaudio-shepherd-service’ and forgot to 
update the commit message; v7 will have it fixed.

-bjc
Oleg Pykhalov Dec. 26, 2023, 12:57 p.m. UTC | #13
Brian Cully <bjc@spork.org> writes:

> help-debbugs@gnu.org (GNU bug Tracking System) writes:
>
>> Your bug report
>>
>> #63863: [PATCH] gnu: home: Add support for home-pipewire-service
>>
>> which was filed against the guix-patches package, has been closed.
>
> Was this intentional?

It was accidental, apologies.  I reopened the issue right after closing.

>> The ‘home-pipewire-pulse-shepherd-service’ procedure is missing. Do you
>> have a code for this procedure or should it be removed from the commit
>> message?  The PipeWire service seems to work without it.
>
> I'd renamed it to ‘home-pulseaudio-shepherd-service’ and forgot to update the
> commit message; v7 will have it fixed.

Pushed to master as afdbf7f271529573397474fdb8f1c9d00dceba37, following
the Guix convention style with a neatly formatted commit message.


Thanks,
Oleg.
diff mbox series

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index 7f8d8d66e9..0b19c9301f 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -116,6 +116,7 @@ 
 Copyright @copyright{} 2023 Karl Hallsby@*
 Copyright @copyright{} 2023 Nathaniel Nicandro@*
 Copyright @copyright{} 2023 Tanguy Le Carrour@*
+Copyright @copyright{} 2023 Brian Cully@*
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -43563,6 +43564,39 @@  Sound Home Services
 This is the multicast address used by default by the two services above.
 @end defvar
 
+@cindex 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.
+
+@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
+
+@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)
+Enable PulseAudio replacement.
+@end table
+@end deftp
+
 @node Mail Home Services
 @subsection Mail Home Services
  
diff --git a/gnu/home/services/sound.scm b/gnu/home/services/sound.scm
index 22c1a99250..94d8bc7482 100644
--- a/gnu/home/services/sound.scm
+++ b/gnu/home/services/sound.scm
@@ -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,77 @@ 
 (define-module (gnu home services sound)
   #:use-module (gnu home services)
   #:use-module (gnu home services shepherd)
+  #: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 (srfi srfi-26)
   #: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) "Enable PulseAudio replacement."))
+
+(define (home-pipewire-shepherd-service config)
+  (shepherd-service
+   (documentation "PipeWire screen and audio sharing.")
+   (provision '(pipewire))
+   (requirement '(dbus))
+   (start #~(make-forkexec-constructor
+             (list #$(file-append
+                      (home-pipewire-configuration-pipewire config)
+                      "/bin/pipewire"))))))
+
+(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"))))))
+
+(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"))))))
+
+(define (home-pipewire-shepherd-services config)
+  (define shepherd-services
+    (filter
+     identity
+     (list home-pipewire-shepherd-service home-wireplumber-shepherd-service
+           (and (home-pipewire-configuration-enable-pulseaudio? config)
+                home-pipewire-pulseaudio-shepherd-service))))
+  (map (cut <> config) shepherd-services))
+
+(define home-pipewire-service-type
+  (service-type
+   (name 'pipewire)
+   (extensions
+    (list (service-extension home-shepherd-service-type
+                             home-pipewire-shepherd-services)))
+   (description
+    "Start essential PipeWire services.")
+   (default-value (home-pipewire-configuration))))
 
 
 ;;;
@@ -149,3 +214,10 @@  (define home-pulseaudio-rtp-source-service-type
     "Define a PulseAudio source to receive audio broadcasted over RTP by
 another PulseAudio instance.")
    (default-value %pulseaudio-rtp-multicast-address)))
+
+
+;;;
+;;; Generate documentation.
+;;;
+(define (generate-doc)
+  (configuration->documentation 'home-pipewire-configuration))