From unknown Fri Jun 20 05:37:32 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#61900 <61900@debbugs.gnu.org> To: bug#61900 <61900@debbugs.gnu.org> Subject: Status: [PATCH] home: services: Add 'pulseaudio-rtp-sink' and 'pulseaudio-rtp-source'. Reply-To: bug#61900 <61900@debbugs.gnu.org> Date: Fri, 20 Jun 2025 12:37:32 +0000 retitle 61900 [PATCH] home: services: Add 'pulseaudio-rtp-sink' and 'pulsea= udio-rtp-source'. reassign 61900 guix-patches submitter 61900 Ludovic Court=C3=A8s severity 61900 normal tag 61900 patch thanks From debbugs-submit-bounces@debbugs.gnu.org Wed Mar 01 17:26:14 2023 Received: (at submit) by debbugs.gnu.org; 1 Mar 2023 22:26:14 +0000 Received: from localhost ([127.0.0.1]:55203 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pXUtp-0002hx-2R for submit@debbugs.gnu.org; Wed, 01 Mar 2023 17:26:13 -0500 Received: from lists.gnu.org ([209.51.188.17]:39260) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pXUtm-0002hp-Ad for submit@debbugs.gnu.org; Wed, 01 Mar 2023 17:26:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pXUtl-0003gB-VC for guix-patches@gnu.org; Wed, 01 Mar 2023 17:26:09 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pXUtl-0004Dm-0v; Wed, 01 Mar 2023 17:26:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:Date:Subject:To:From:in-reply-to: references; bh=7lwkYyVxSk/T40k3uGVX6lZhezfRtHY94PweS9El8NI=; b=i1RrQvgoftNsnt VTjCr0xchTmG/ArDxVIM7X5FJO3u2s2oBaJT7AtExnPv4q2rQbMI63N4tNoO//i3ZTlj4g++iK1IO /B8BVr8RTHGaj6GaKvT13KpkBUcLC829efGx927sAposrHOPR++zaxye0ND1rVkBSUsTxkspZdbm6 mmG4bcGextJ5lnHcQQMUAb0fmCGpcF2kCVfcy2CRL5K9164ew9P2K8wapVXg97KEeErUo/kWp9T45 O452J2LbcQ/cGHOJqaPfZUZqZlP5SjIDq4R9YSkiYmD8YIenH90g/t0xFbmFWMWnwnpm1kPArf6zb k8O+Z8mR/JPulj7bkVTg==; Received: from 91-160-117-201.subs.proxad.net ([91.160.117.201] helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pXUtk-0003Z3-5J; Wed, 01 Mar 2023 17:26:08 -0500 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= To: guix-patches@gnu.org Subject: [PATCH] home: services: Add 'pulseaudio-rtp-sink' and 'pulseaudio-rtp-source'. Date: Wed, 1 Mar 2023 23:26:01 +0100 Message-Id: <20230301222601.22216-1-ludo@gnu.org> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 X-Debbugs-Cc: , Andrew Tropin Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: submit Cc: =?UTF-8?q?Ludovic=20Court=C3=A8s?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) * gnu/home/services/sound.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. * doc/guix.texi (Sound Home Services): New section. --- doc/guix.texi | 114 ++++++++++++++++++++++++--- gnu/home/services/sound.scm | 151 ++++++++++++++++++++++++++++++++++++ gnu/local.mk | 3 +- 3 files changed, 258 insertions(+), 10 deletions(-) create mode 100644 gnu/home/services/sound.scm Hi there! Here’s a Guix Home service I’ve been using for some time. In a nutshell, when I want to send audio to a device that’s further away from my laptop, I run: herd start pulseaudio-rtp-sink That adds a PulseAudio “sink”, which I can select in pavucontrol or pulsemixer to send audio streams over there. And then to turn that off: herd stop pulseaudio-rtp-sink Thoughts? Ludo’. diff --git a/doc/guix.texi b/doc/guix.texi index a7ef00f421..7716686f87 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -41513,15 +41513,16 @@ service with the @code{simple-service} procedure from @code{(gnu services)}. @menu -* Essential Home Services:: Environment variables, packages, on-* scripts. -* Shells: Shells Home Services. POSIX shells, Bash, Zsh. -* Mcron: Mcron Home Service. Scheduled User's Job Execution. -* Power Management: Power Management Home Services. Services for battery power. -* Shepherd: Shepherd Home Service. Managing User's Daemons. -* SSH: Secure Shell. Setting up the secure shell client. -* Desktop: Desktop Home Services. Services for graphical environments. -* Guix: Guix Home Services. Services for Guix. -* Fonts: Fonts Home Services. Services for managing User's fonts. +* Essential Home Services:: Environment variables, packages, on-* scripts. +* Shells: Shells Home Services. POSIX shells, Bash, Zsh. +* Mcron: Mcron Home Service. Scheduled User's Job Execution. +* Power Management: Power Management Home Services. Services for battery power. +* Shepherd: Shepherd Home Service. Managing User's Daemons. +* SSH: Secure Shell. Setting up the secure shell client. +* Desktop: Desktop Home Services. Services for graphical environments. +* Guix: Guix Home Services. Services for Guix. +* Fonts: Fonts Home Services. Services for managing User's fonts. +* Sound: Sound Home Services. Dealing with audio. @end menu @c In addition to that Home Services can provide @@ -42435,6 +42436,101 @@ like this: @end lisp @end defvar +@node Sound Home Services +@subsection Sound Home Services + +The @code{(gnu home services sound)} module provides services related to +sound support. + +@cindex PulseAudio, home service +@cindex RTP, for PulseAudio + +The following services dynamically reconfigure the +@uref{https://pulseaudio.org,PulseAudio sound server}: they let you +toggle broadcast of audio output over the network using the +@acronym{RTP, real-time transport protocol} and, correspondingly, +playback of sound received over RTP. Once +@code{home-pulseaudio-rtp-sink-service-type} is among your home +services, you can start broadcasting audio output by running this +command: + +@example +herd start pulseaudio-rtp-sink +@end example + +You can then run a PulseAudio-capable mixer, such as @code{pavucontrol} +or @code{pulsemixer} (both from the same-named package) to control which +audio stream(s) should be sent to the RTP ``sink''. + +By default, audio is broadcasted to a multicast address: any device on +the @acronym{LAN, local area network} receives it and may play it. +Using multicast in this way puts a lot of pressure on the network and +degrades its performance, so you may instead prefer sending to +specifically one device. The first way to do that is by specifying the +IP address of the target device when starting the service: + +@example +herd start pulseaudio-rtp-sink 192.168.1.42 +@end example + +The other option is to specify this IP address as the one to use by +default in your home environment configuration: + +@lisp +(service home-pulseaudio-rtp-sink-service-type + "192.168.1.42") +@end lisp + +On the device where you intend to receive and play the RTP stream, you +can use @code{home-pulseaudio-rtp-source-service-type}, like so: + +@lisp +(service home-pulseaudio-rtp-source-service-type) +@end lisp + +This will then let you start the receiving module for PulseAudio: + +@example +herd start pulseaudio-rtp-source +@end example + +Again, by default it will listen on the multicast address. If, instead, +you'd like it to listen for direct incoming connections, you can do that +by running: + +@lisp +(service home-pulseaudio-rtp-source-service-type + "0.0.0.0") +@end lisp + +The reference of these services is given below. + +@defvar home-pulseaudio-rtp-sink-service-type +@defvarx home-pulseaudio-rtp-source-service-type +This is the type of the service to send, respectively receive, audio +streams over @acronym{RTP, real-time transport protocol}. + +The value associated with this service is the IP address (a string) +where to send, respectively receive, the audio stream. By default, +audio is sent/received on multicast address +@code{%pulseaudio-rtp-multicast-address}. + +This service defines one Shepherd service: @code{pulseaudio-rtp-sink}, +respectively @code{pulseaudio-rtp-source}. The service is not started +by default, so you have to explicitly start it when you want to turn it +on, as in this example: + +@example +herd start pulseaudio-rtp-sink +@end example + +Stopping the Shepherd service turns off broadcasting. +@end defvar + +@defvar %pulseaudio-rtp-multicast-address +This is the multicast address used by default by the two services above. +@end defvar + @node Invoking guix home @section Invoking @command{guix home} diff --git a/gnu/home/services/sound.scm b/gnu/home/services/sound.scm new file mode 100644 index 0000000000..22c1a99250 --- /dev/null +++ b/gnu/home/services/sound.scm @@ -0,0 +1,151 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2023 Ludovic Courtès +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (gnu home services sound) + #:use-module (gnu home services) + #:use-module (gnu home services shepherd) + #: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 support. +;;; + +(define (with-pulseaudio-connection sock exp) + ;; Wrap EXP in an expression where SOCK is bound to a socket connected to + ;; the user's PulseAudio command-line interface socket. + #~(let* ((#$sock (socket AF_UNIX SOCK_STREAM 0)) + (pulse-user-file + (lambda (name) + (string-append "/run/user/" (number->string (getuid)) + "/pulse/" name))) + (file (pulse-user-file "cli"))) + (let loop ((tries 0)) + (catch #t + (lambda () + (connect #$sock AF_UNIX file) + (let ((result #$exp)) + (close-port #$sock) + result)) + (lambda (key . args) + (if (and (eq? key 'system-error) + (= ENOENT (system-error-errno (cons key args))) + (< tries 3)) + ;; The CLI socket doesn't exist yet, so send pulseaudio + ;; SIGUSR2 so that it creates it and listens to it. + (let ((pid (call-with-input-file (pulse-user-file "pid") + read))) + (when (and (integer? pid) (> pid 1)) + (kill pid SIGUSR2)) + ((@ (fibers) sleep) 1) + (loop (+ tries 1))) + (begin + (close-port #$sock) + (apply throw key args)))))))) + +(define %pulseaudio-rtp-multicast-address + ;; Default address used by 'module-rtp-sink' and 'module-rtp-recv'. This is + ;; a multicast address, for the Session Announcement Protocol (SAP) and the + ;; Session Description Protocol (SDP). + "224.0.0.56") + +(define (pulseaudio-rtp-sink-shepherd-services destination-ip) + (list (shepherd-service + (provision '(pulseaudio-rtp-sink)) + (start + #~(lambda* (#:optional (destination-ip #$destination-ip)) + #$(with-pulseaudio-connection + #~sock + #~(begin + (display "\ +load-module module-null-sink \ +sink_name=rtp sink_properties=\"device.description='RTP network output'\"\n" + sock) + (display (string-append "\ +load-module module-rtp-send source=rtp.monitor" + (if destination-ip + (string-append + " destination_ip=" + destination-ip) + "") + "\n") + sock) + #t)))) + (stop + #~(lambda (_) + #$(with-pulseaudio-connection + #~sock + #~(begin + (display "unload-module module-rtp-send\n" + sock) + (display "unload-module module-null-sink\n" + sock) + #f)))) + (auto-start? #f)))) + +(define home-pulseaudio-rtp-sink-service-type + (service-type + (name 'pulseaudio-rtp-sink) + (extensions + (list (service-extension home-shepherd-service-type + pulseaudio-rtp-sink-shepherd-services))) + (description + "Define a PulseAudio sink to broadcast audio output over RTP, which can +then by played by another PulseAudio instance.") + + ;; By default, send to the SAP multicast address, 224.0.0.56, which can be + ;; network-intensive. + (default-value %pulseaudio-rtp-multicast-address))) + +(define (pulseaudio-rtp-source-shepherd-services source-ip) + (list (shepherd-service + (provision '(pulseaudio-rtp-source)) + (start + #~(lambda* (#:optional (source-ip #$source-ip)) + #$(with-pulseaudio-connection + #~sock + #~(begin + (format sock "\ +load-module module-rtp-recv sap_address=~a\n" source-ip) + #t)))) + (stop + #~(lambda (_) + #$(with-pulseaudio-connection + #~sock + #~(begin + (display "unload-module module-rtp-recv\n" + sock) + #f)))) + (auto-start? #f)))) + +(define home-pulseaudio-rtp-source-service-type + (service-type + (name 'pulseaudio-rtp-source) + (extensions + (list (service-extension home-shepherd-service-type + pulseaudio-rtp-source-shepherd-services))) + (description + "Define a PulseAudio source to receive audio broadcasted over RTP by +another PulseAudio instance.") + (default-value %pulseaudio-rtp-multicast-address))) diff --git a/gnu/local.mk b/gnu/local.mk index dd1d546be5..55b5295439 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2012-2021, 2021-2022 Ludovic Courtès +# Copyright © 2012-2023 Ludovic Courtès # Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2022 Andreas Enge # Copyright © 2016 Mathieu Lirzin # Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Mark H Weaver @@ -94,6 +94,7 @@ GNU_SYSTEM_MODULES = \ %D%/home/services/pm.scm \ %D%/home/services/shells.scm \ %D%/home/services/shepherd.scm \ + %D%/home/services/sound.scm \ %D%/home/services/ssh.scm \ %D%/home/services/mcron.scm \ %D%/home/services/utils.scm \ base-commit: ff5fbcc19bce6e94ead0cc79b27ae8ed0307463d -- 2.39.1 From debbugs-submit-bounces@debbugs.gnu.org Thu Mar 02 09:16:39 2023 Received: (at 61900) by debbugs.gnu.org; 2 Mar 2023 14:16:39 +0000 Received: from localhost ([127.0.0.1]:56237 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pXjja-0005it-02 for submit@debbugs.gnu.org; Thu, 02 Mar 2023 09:16:38 -0500 Received: from relay8-d.mail.gandi.net ([217.70.183.201]:38085) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pXjjX-0005ih-Ls for 61900@debbugs.gnu.org; Thu, 02 Mar 2023 09:16:36 -0500 Received: (Authenticated sender: andrew@trop.in) by mail.gandi.net (Postfix) with ESMTPSA id 914591BF208; Thu, 2 Mar 2023 14:16:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=trop.in; s=gm1; t=1677766589; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=X2jkMyNoQcCfjlsACKx0TPNRMICC8exnxmN0RW6PvDc=; b=CZA360hHnfMOhIS6S229C62NG3dJucAHfi90tDLAWHCKTn+YXbNp4qyG3SwY2WH9a/mt+F q2KoFnAZFZkKIyvOr7ADjlw/bRg58ZI0zxSfhPBjCZwK/+MVM0144MynDR6ZPh3X2XeTHT h8R2HVXmNTvhyAAyPCBg8BiZ/AlA9ANVyefXeRIOxFCrbn0yno0hREPVjgQ3mHXAss/WE/ K4RCLWVhd8PXwrH9kiIiWXPEHl/I6AGxdoWIWQY4yGdJSb5ujWGuaK770d8CFv2TqlEWB3 pBlOwZ7lr+jWoqKXk13IsDNgkgMQ/VCcQopCv+j7m63N4x3Rv8oxYjDNz53mYg== From: Andrew Tropin To: Ludovic =?utf-8?Q?Court=C3=A8s?= , 61900@debbugs.gnu.org Subject: Re: [bug#61900] [PATCH] home: services: Add 'pulseaudio-rtp-sink' and 'pulseaudio-rtp-source'. In-Reply-To: <20230301222601.22216-1-ludo@gnu.org> References: <20230301222601.22216-1-ludo@gnu.org> Date: Thu, 02 Mar 2023 18:16:24 +0400 Message-ID: <87y1ofb5mv.fsf@trop.in> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 61900 Cc: paren@disroot.org, Ludovic =?utf-8?Q?Court=C3=A8s?= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 2023-03-01 23:26, Ludovic Court=C3=A8s wrote: > * gnu/home/services/sound.scm: New file. > * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. > * doc/guix.texi (Sound Home Services): New section. > --- > doc/guix.texi | 114 ++++++++++++++++++++++++--- > gnu/home/services/sound.scm | 151 ++++++++++++++++++++++++++++++++++++ > gnu/local.mk | 3 +- > 3 files changed, 258 insertions(+), 10 deletions(-) > create mode 100644 gnu/home/services/sound.scm > > Hi there! > > Here=E2=80=99s a Guix Home service I=E2=80=99ve been using for some time.= In a nutshell, > when I want to send audio to a device that=E2=80=99s further away from my= laptop, > I run: > > herd start pulseaudio-rtp-sink > > That adds a PulseAudio =E2=80=9Csink=E2=80=9D, which I can select in pavu= control or > pulsemixer to send audio streams over there. And then to turn that off: > > herd stop pulseaudio-rtp-sink > > Thoughts? > > Ludo=E2=80=99. > > diff --git a/doc/guix.texi b/doc/guix.texi > index a7ef00f421..7716686f87 100644 > --- a/doc/guix.texi > +++ b/doc/guix.texi > @@ -41513,15 +41513,16 @@ service with the @code{simple-service} procedur= e from @code{(gnu > services)}. >=20=20 > @menu > -* Essential Home Services:: Environment variables, packages, on-* scrip= ts. > -* Shells: Shells Home Services. POSIX shells, Bas= h, Zsh. > -* Mcron: Mcron Home Service. Scheduled User's = Job Execution. > -* Power Management: Power Management Home Services. Services for batt= ery power. > -* Shepherd: Shepherd Home Service. Managing User's D= aemons. > -* SSH: Secure Shell. Setting up the se= cure shell client. > -* Desktop: Desktop Home Services. Services for grap= hical environments. > -* Guix: Guix Home Services. Services for Guix. > -* Fonts: Fonts Home Services. Services for mana= ging User's fonts. > +* Essential Home Services:: Environment variables, packages, on-* sc= ripts. > +* Shells: Shells Home Services. POSIX shells, Bash, Zsh. > +* Mcron: Mcron Home Service. Scheduled User's Job Execution. > +* Power Management: Power Management Home Services. Services for batter= y power. > +* Shepherd: Shepherd Home Service. Managing User's Daemons. > +* SSH: Secure Shell. Setting up the secure shell client. > +* Desktop: Desktop Home Services. Services for graphical environments. > +* Guix: Guix Home Services. Services for Guix. > +* Fonts: Fonts Home Services. Services for managing User's fonts. > +* Sound: Sound Home Services. Dealing with audio. > @end menu > @c In addition to that Home Services can provide >=20=20 > @@ -42435,6 +42436,101 @@ like this: > @end lisp > @end defvar >=20=20 > +@node Sound Home Services > +@subsection Sound Home Services > + > +The @code{(gnu home services sound)} module provides services related to > +sound support. > + > +@cindex PulseAudio, home service > +@cindex RTP, for PulseAudio > + > +The following services dynamically reconfigure the > +@uref{https://pulseaudio.org,PulseAudio sound server}: they let you > +toggle broadcast of audio output over the network using the > +@acronym{RTP, real-time transport protocol} and, correspondingly, > +playback of sound received over RTP. Once > +@code{home-pulseaudio-rtp-sink-service-type} is among your home > +services, you can start broadcasting audio output by running this > +command: > + > +@example > +herd start pulseaudio-rtp-sink > +@end example > + > +You can then run a PulseAudio-capable mixer, such as @code{pavucontrol} > +or @code{pulsemixer} (both from the same-named package) to control which > +audio stream(s) should be sent to the RTP ``sink''. > + > +By default, audio is broadcasted to a multicast address: any device on > +the @acronym{LAN, local area network} receives it and may play it. > +Using multicast in this way puts a lot of pressure on the network and > +degrades its performance, so you may instead prefer sending to > +specifically one device. The first way to do that is by specifying the > +IP address of the target device when starting the service: > + > +@example > +herd start pulseaudio-rtp-sink 192.168.1.42 > +@end example > + > +The other option is to specify this IP address as the one to use by > +default in your home environment configuration: > + > +@lisp > +(service home-pulseaudio-rtp-sink-service-type > + "192.168.1.42") > +@end lisp > + > +On the device where you intend to receive and play the RTP stream, you > +can use @code{home-pulseaudio-rtp-source-service-type}, like so: > + > +@lisp > +(service home-pulseaudio-rtp-source-service-type) > +@end lisp > + > +This will then let you start the receiving module for PulseAudio: > + > +@example > +herd start pulseaudio-rtp-source > +@end example > + > +Again, by default it will listen on the multicast address. If, instead, > +you'd like it to listen for direct incoming connections, you can do that > +by running: > + > +@lisp > +(service home-pulseaudio-rtp-source-service-type > + "0.0.0.0") > +@end lisp > + > +The reference of these services is given below. > + > +@defvar home-pulseaudio-rtp-sink-service-type > +@defvarx home-pulseaudio-rtp-source-service-type > +This is the type of the service to send, respectively receive, audio > +streams over @acronym{RTP, real-time transport protocol}. > + > +The value associated with this service is the IP address (a string) > +where to send, respectively receive, the audio stream. By default, > +audio is sent/received on multicast address > +@code{%pulseaudio-rtp-multicast-address}. > + > +This service defines one Shepherd service: @code{pulseaudio-rtp-sink}, > +respectively @code{pulseaudio-rtp-source}. The service is not started > +by default, so you have to explicitly start it when you want to turn it > +on, as in this example: > + > +@example > +herd start pulseaudio-rtp-sink > +@end example > + > +Stopping the Shepherd service turns off broadcasting. > +@end defvar > + > +@defvar %pulseaudio-rtp-multicast-address > +This is the multicast address used by default by the two services above. > +@end defvar > + > @node Invoking guix home > @section Invoking @command{guix home} >=20=20 > diff --git a/gnu/home/services/sound.scm b/gnu/home/services/sound.scm > new file mode 100644 > index 0000000000..22c1a99250 > --- /dev/null > +++ b/gnu/home/services/sound.scm > @@ -0,0 +1,151 @@ > +;;; GNU Guix --- Functional package management for GNU > +;;; Copyright =C2=A9 2023 Ludovic Court=C3=A8s > +;;; > +;;; This file is part of GNU Guix. > +;;; > +;;; GNU Guix is free software; you can redistribute it and/or modify it > +;;; under the terms of the GNU General Public License as published by > +;;; the Free Software Foundation; either version 3 of the License, or (at > +;;; your option) any later version. > +;;; > +;;; GNU Guix is distributed in the hope that it will be useful, but > +;;; WITHOUT ANY WARRANTY; without even the implied warranty of > +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +;;; GNU General Public License for more details. > +;;; > +;;; You should have received a copy of the GNU General Public License > +;;; along with GNU Guix. If not, see . > + > +(define-module (gnu home services sound) > + #:use-module (gnu home services) > + #:use-module (gnu home services shepherd) > + #: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 support. > +;;; > + > +(define (with-pulseaudio-connection sock exp) > + ;; Wrap EXP in an expression where SOCK is bound to a socket connected= to > + ;; the user's PulseAudio command-line interface socket. > + #~(let* ((#$sock (socket AF_UNIX SOCK_STREAM 0)) > + (pulse-user-file > + (lambda (name) > + (string-append "/run/user/" (number->string (getuid)) > + "/pulse/" name))) > + (file (pulse-user-file "cli"))) > + (let loop ((tries 0)) > + (catch #t > + (lambda () > + (connect #$sock AF_UNIX file) > + (let ((result #$exp)) > + (close-port #$sock) > + result)) > + (lambda (key . args) > + (if (and (eq? key 'system-error) > + (=3D ENOENT (system-error-errno (cons key args))) > + (< tries 3)) > + ;; The CLI socket doesn't exist yet, so send pulseaudio > + ;; SIGUSR2 so that it creates it and listens to it. > + (let ((pid (call-with-input-file (pulse-user-file "pid") > + read))) > + (when (and (integer? pid) (> pid 1)) > + (kill pid SIGUSR2)) > + ((@ (fibers) sleep) 1) > + (loop (+ tries 1))) > + (begin > + (close-port #$sock) > + (apply throw key args)))))))) > + > +(define %pulseaudio-rtp-multicast-address > + ;; Default address used by 'module-rtp-sink' and 'module-rtp-recv'. T= his is > + ;; a multicast address, for the Session Announcement Protocol (SAP) an= d the > + ;; Session Description Protocol (SDP). > + "224.0.0.56") > + > +(define (pulseaudio-rtp-sink-shepherd-services destination-ip) > + (list (shepherd-service > + (provision '(pulseaudio-rtp-sink)) > + (start > + #~(lambda* (#:optional (destination-ip #$destination-ip)) > + #$(with-pulseaudio-connection > + #~sock > + #~(begin > + (display "\ > +load-module module-null-sink \ > +sink_name=3Drtp sink_properties=3D\"device.description=3D'RTP network ou= tput'\"\n" > + sock) > + (display (string-append "\ > +load-module module-rtp-send source=3Drtp.monitor" > + (if destination-ip > + (string-append > + " destination_ip=3D" > + destination-ip) > + "") > + "\n") > + sock) > + #t)))) > + (stop > + #~(lambda (_) > + #$(with-pulseaudio-connection > + #~sock > + #~(begin > + (display "unload-module module-rtp-send\n" > + sock) > + (display "unload-module module-null-sink\n" > + sock) > + #f)))) > + (auto-start? #f)))) > + > +(define home-pulseaudio-rtp-sink-service-type > + (service-type > + (name 'pulseaudio-rtp-sink) > + (extensions > + (list (service-extension home-shepherd-service-type > + pulseaudio-rtp-sink-shepherd-services))) > + (description > + "Define a PulseAudio sink to broadcast audio output over RTP, which = can > +then by played by another PulseAudio instance.") > + > + ;; By default, send to the SAP multicast address, 224.0.0.56, which c= an be > + ;; network-intensive. > + (default-value %pulseaudio-rtp-multicast-address))) > + > +(define (pulseaudio-rtp-source-shepherd-services source-ip) > + (list (shepherd-service > + (provision '(pulseaudio-rtp-source)) > + (start > + #~(lambda* (#:optional (source-ip #$source-ip)) > + #$(with-pulseaudio-connection > + #~sock > + #~(begin > + (format sock "\ > +load-module module-rtp-recv sap_address=3D~a\n" source-ip) > + #t)))) > + (stop > + #~(lambda (_) > + #$(with-pulseaudio-connection > + #~sock > + #~(begin > + (display "unload-module module-rtp-recv\n" > + sock) > + #f)))) > + (auto-start? #f)))) > + > +(define home-pulseaudio-rtp-source-service-type > + (service-type > + (name 'pulseaudio-rtp-source) > + (extensions > + (list (service-extension home-shepherd-service-type > + pulseaudio-rtp-source-shepherd-services))) > + (description > + "Define a PulseAudio source to receive audio broadcasted over RTP by > +another PulseAudio instance.") > + (default-value %pulseaudio-rtp-multicast-address))) > diff --git a/gnu/local.mk b/gnu/local.mk > index dd1d546be5..55b5295439 100644 > --- a/gnu/local.mk > +++ b/gnu/local.mk > @@ -1,5 +1,5 @@ > # GNU Guix --- Functional package management for GNU > -# Copyright =C2=A9 2012-2021, 2021-2022 Ludovic Court=C3=A8s > +# Copyright =C2=A9 2012-2023 Ludovic Court=C3=A8s > # Copyright =C2=A9 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2022 = Andreas Enge > # Copyright =C2=A9 2016 Mathieu Lirzin > # Copyright =C2=A9 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 = Mark H Weaver > @@ -94,6 +94,7 @@ GNU_SYSTEM_MODULES =3D \ > %D%/home/services/pm.scm \ > %D%/home/services/shells.scm \ > %D%/home/services/shepherd.scm \ > + %D%/home/services/sound.scm \ > %D%/home/services/ssh.scm \ > %D%/home/services/mcron.scm \ > %D%/home/services/utils.scm \ > > base-commit: ff5fbcc19bce6e94ead0cc79b27ae8ed0307463d Hi Ludo, thank you for the interesting services! I expected them to have an ability to specify a port, but it seems it is supported only in pipewire, but not in pulseaudio. https://docs.pipewire.org/page_module_rtp_source.html The patch looks good to me. =2D-=20 Best regards, Andrew Tropin --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEKEGaxlA4dEDH6S/6IgjSCVjB3rAFAmQAr7gACgkQIgjSCVjB 3rCZSA//apns0iKRmYHIUa07n4MW/REGOivpQ5e/dnFtkQEQrB3HslFG6ZtiGB/j ku1e8wvNcyKzHR1wk2a+2BBah+y/h7OsQJKDN9NnSkuTqzYx0KpcJA998KiTdH4m wK0AWTligc1hsU8SjNVC8ezSTWOLsXO29oXKYiA4tyTFpokYvM+IFad1iuVxikYc SYbJsMQLpgCn4ZcDlSmUZ6HS2PvytkU7m4iF67P9MB7YYVE6wlO5ceC3esSGdMcl 4LH7/NhpiQ8cOEYnNgx0LouEA+o9EHUgA9zmErtdzF8GDRl19Ev+SYdNv1t9rb8k ekCULbdWMzox5b+9H5RuYbSmH5uiqCF8x8/cJWPP9qbYtSATDiWD4KAKzT1kbJYi QCOULYkgRpVV4N5J7tN9A4X7blXGu0hVzRAkWR3D4fa+LV5NoKiH/dgBVetmbTvu 5VfYY3gy5OXCPP6UGFa++ya4JBqNROawrHd0MO+wCjafhyPnrfonm3gFd51780bg 4YqJZv8F+mHK8Vz6eVPMaunAimoF+UeTikRp39LXaWCkC4VCkwk2/Fb0baOSXSJw lzFn10xs8C07UGDtmXwWbt/LJws33HN6ny3d8R7XVnAlSYeGtBHyPdP2giXZDpKP VAgtHZTXqQ+MgDrInOGmBGF5Uuvlxf8z3l3SThVLNVkMJLqHKpY= =m48N -----END PGP SIGNATURE----- --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sun Mar 05 17:20:32 2023 Received: (at 61900-done) by debbugs.gnu.org; 5 Mar 2023 22:20:32 +0000 Received: from localhost ([127.0.0.1]:40906 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pYwiW-0008Uh-65 for submit@debbugs.gnu.org; Sun, 05 Mar 2023 17:20:32 -0500 Received: from eggs.gnu.org ([209.51.188.92]:49684) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pYwiV-0008UU-6l for 61900-done@debbugs.gnu.org; Sun, 05 Mar 2023 17:20:31 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pYwiP-0003wZ-Po; Sun, 05 Mar 2023 17:20:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:In-Reply-To:Date:References:Subject:To: From; bh=t1VqYHyr5X2h9xAEuUIY0vs2O2kZ/0+LyAUWHV8e/+Y=; b=Sex6I5IIwXyoajX8O6dz voO4DVWDeb2hGfVcalkHkYe8RrndzWj0LOE+siOiQj0mnbXRPORmAlaBiNo4G6DMXushVFd6S+VS9 OvMCNzUKnxpm9WB0QwnSbREARINPYtqkRX7A6vBM6BZIfWA4x8ARavx0heZwUol6M4eyTGQp7TV9z ti2Icvw4yuR5S1vhYOujAumjQ3iP2vMBU4C0TiVhC2DdCi9NTNtR9PzXXSGhWAlkh7vNHywqwc1H9 eDVCLdm4J9zvzyTB4eh0KkQReph+xrau7dFFCMgks4k46p++y0QOEhXTxiVepMJxJ0mYHU01wW/hY +w15uNGm7Hy4eA==; Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pYwiP-0005D5-8m; Sun, 05 Mar 2023 17:20:25 -0500 From: =?utf-8?Q?Ludovic_Court=C3=A8s?= To: Andrew Tropin Subject: Re: bug#61900: [PATCH] home: services: Add 'pulseaudio-rtp-sink' and 'pulseaudio-rtp-source'. References: <20230301222601.22216-1-ludo@gnu.org> <87y1ofb5mv.fsf@trop.in> Date: Sun, 05 Mar 2023 23:20:22 +0100 In-Reply-To: <87y1ofb5mv.fsf@trop.in> (Andrew Tropin's message of "Thu, 02 Mar 2023 18:16:24 +0400") Message-ID: <87edq2on6h.fsf_-_@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 61900-done Cc: 61900-done@debbugs.gnu.org, paren@disroot.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Hi Andrew, Pushed as 674d8933169e018efa3471e4eac52e5ea1e6afee. Thanks for taking a look! Ludo=E2=80=99. From unknown Fri Jun 20 05:37:32 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Mon, 03 Apr 2023 11:24:05 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator