From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from atuin.qyliss.net (localhost [IPv6:::1]) by atuin.qyliss.net (Postfix) with ESMTP id A5EE117E1D; Mon, 21 Jul 2025 09:42:12 +0000 (UTC) Received: by atuin.qyliss.net (Postfix, from userid 993) id 5DCF417DDB; Mon, 21 Jul 2025 09:42:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on atuin.qyliss.net X-Spam-Level: * X-Spam-Status: No, score=1.2 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DMARC_MISSING,PDS_OTHER_BAD_TLD,RCVD_IN_DNSWL_LOW, SPF_HELO_PASS autolearn=no autolearn_force=no version=4.0.1 Received: from fhigh-a1-smtp.messagingengine.com (fhigh-a1-smtp.messagingengine.com [103.168.172.152]) by atuin.qyliss.net (Postfix) with ESMTPS id C957D17DD2 for ; Mon, 21 Jul 2025 09:42:06 +0000 (UTC) Received: from phl-compute-05.internal (phl-compute-05.phl.internal [10.202.2.45]) by mailfhigh.phl.internal (Postfix) with ESMTP id 083AA14000EB; Mon, 21 Jul 2025 05:42:06 -0400 (EDT) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-05.internal (MEProxy); Mon, 21 Jul 2025 05:42:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alyssa.is; h=cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1753090926; x=1753177326; bh=JxXm7DlWa1 5F16oatg+PTymJUTsRZd01o5ynwvvlAjM=; b=nwqWhjnLWS18J13Q+Ax7TrACdI rjEVwy/4IKKy0Ka6sC9JPXkRC+8z9Cjr7PJJOKfQk9Ucg0/32VVjfzA09nt3kXRR QiB4hCz/+yAAyEcKbB7SatJ0/+FPMo9kr/2aNCzvcQ2Sh6U96Gd+s3NSpdiyk2iZ uVl/UY3IhwDfdtxVS9G0qFOqVA7Uxz3Q8qzc4LANAHQgHJDLPTcHfo6FMhRKp0MP JAkDGl+xNPiA8dsEmAP9jlVCHg4sqkGIVEIy/bXDKRyLAqz/TcAqio/RvamCbbjn bh2+vtlNx529rWimA6O8CFEGJcbYNsGufKvxOQ9cyXnMMbpeb9LUwkN4up+A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1753090926; x=1753177326; bh=JxXm7DlWa15F16oatg+PTymJUTsRZd01o5y nwvvlAjM=; b=g68mNyTq2mxO0dTuFfdWO+1j19NWj8I9EKEGaWvEaF32labfJCL vnqUguApRe+rlKfO/lTPJyBTHafiuGJD2BmLGNFYIwSaMzrwNA79YrwAydUc5uJt PZK38Ulx+bFg8cRpfWgJqc4n5+grr/hjvn1rFKiax+19LFDCFXyoQho1IBve+mis ARtWtuvU8RGtV0Xth//lE/PEAAPGhSYOlZ0StY1//7nGbXeM6lvU8BPHlT8mepdf vtXOb534bHYo4sdNe2OsaRmORlPDFQysb0u4COciUh48deqzY+nWJWINJ0k6NIYX 9bHuGMba5h8J/iGCemlBmUuUQvQ4u17c3Qg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdefgdejudejhecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjug hrpefhvffujghffffkgggtsehgtderredttdejnecuhfhrohhmpeetlhihshhsrgcutfho shhsuceohhhisegrlhihshhsrgdrihhsqeenucggtffrrghtthgvrhhnpeegfeektdeije fgveeigfeuveefgeeigffggeduffdvueevffetgeekueelvdelfeenucffohhmrghinhep shhhuhhtughofihnrdhfihhnrghlpdgtrghrugdrnhgrmhgvpdhptghmrdhsthhrvggrmh enucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehhihes rghlhihsshgrrdhishdpnhgspghrtghpthhtohepvddpmhhouggvpehsmhhtphhouhhtpd hrtghpthhtohepuggvmhhiohgsvghnohhurhesghhmrghilhdrtghomhdprhgtphhtthho peguvghvvghlsehsphgvtghtrhhumhdqohhsrdhorhhg X-ME-Proxy: Feedback-ID: i12284293:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 21 Jul 2025 05:42:05 -0400 (EDT) Received: by sf.qyliss.net (Postfix, from userid 1000) id 471FF2CCBAB11; Mon, 21 Jul 2025 11:42:04 +0200 (CEST) From: Alyssa Ross To: Demi Marie Obenour , Spectrum OS Development Subject: Re: [PATCH v5 8/8] img/app: Run PipeWire and WirePlumber in the VMs In-Reply-To: <7f88f09b-5671-4f1e-86d7-df08dc2561eb@gmail.com> References: <7f88f09b-5671-4f1e-86d7-df08dc2561eb@gmail.com> Date: Mon, 21 Jul 2025 11:42:02 +0200 Message-ID: <87seiplw2d.fsf@alyssa.is> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" Message-ID-Hash: KC6AUAQARSRMZY2BZ6EQOKXRFBPOAZJN X-Message-ID-Hash: KC6AUAQARSRMZY2BZ6EQOKXRFBPOAZJN X-MailFrom: hi@alyssa.is X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-devel.spectrum-os.org-0; header-match-devel.spectrum-os.org-1; header-match-devel.spectrum-os.org-2; header-match-devel.spectrum-os.org-3; header-match-devel.spectrum-os.org-4; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: Patches and low-level development discussion Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Demi Marie Obenour writes: > WirePlumber is completely overkill as a session manager here, and > ideally a trivial session manager would be used instead. I did build a > Spectrum OS image and found that PipeWire and WirePlumber both > successfully started. PipeWire is configured to listen on the > PulseAudio socket, so PulseAudio compatibility works. This does bring a > log of unnecessary files into the VMs, which will hopefully be removed > later as part of a debloating effort. > > Signed-off-by: Demi Marie Obenour > --- > img/app/Makefile | 17 +- > img/app/default.nix | 3 + > img/app/etc/mdev.conf | 3 + > img/app/etc/pipewire/pipewire.conf | 199 +++++++ > .../etc/s6-rc/app/dependencies.d/wireplumber | 0 > .../s6-rc/pipewire/dependencies.d/directories | 0 > .../etc/s6-rc/pipewire/dependencies.d/mdevd | 0 > img/app/etc/s6-rc/pipewire/notification-fd | 1 + > .../s6-rc/pipewire/notification-fd.license | 2 + > img/app/etc/s6-rc/pipewire/run | 25 + > img/app/etc/s6-rc/pipewire/type | 1 + > img/app/etc/s6-rc/pipewire/type.license | 2 + > .../etc/s6-rc/wireplumber/dependencies.d/dbus | 0 > .../s6-rc/wireplumber/dependencies.d/pipewire | 0 > img/app/etc/s6-rc/wireplumber/run | 4 + > img/app/etc/s6-rc/wireplumber/type | 1 + > img/app/etc/s6-rc/wireplumber/type.license | 2 + > img/app/etc/wireplumber/wireplumber.conf | 536 ++++++++++++++++++ > 18 files changed, 794 insertions(+), 2 deletions(-) > create mode 100644 img/app/etc/pipewire/pipewire.conf > create mode 100644 img/app/etc/s6-rc/app/dependencies.d/wireplumber > create mode 100644 img/app/etc/s6-rc/pipewire/dependencies.d/directories > create mode 100644 img/app/etc/s6-rc/pipewire/dependencies.d/mdevd > create mode 100644 img/app/etc/s6-rc/pipewire/notification-fd > create mode 100644 img/app/etc/s6-rc/pipewire/notification-fd.license > create mode 100644 img/app/etc/s6-rc/pipewire/run > create mode 100644 img/app/etc/s6-rc/pipewire/type > create mode 100644 img/app/etc/s6-rc/pipewire/type.license > create mode 100644 img/app/etc/s6-rc/wireplumber/dependencies.d/dbus > create mode 100644 img/app/etc/s6-rc/wireplumber/dependencies.d/pipewire > create mode 100644 img/app/etc/s6-rc/wireplumber/run > create mode 100644 img/app/etc/s6-rc/wireplumber/type > create mode 100644 img/app/etc/s6-rc/wireplumber/type.license > create mode 100644 img/app/etc/wireplumber/wireplumber.conf > > diff --git a/img/app/Makefile b/img/app/Makefile > index e11be09a3c6ca801d9211e49b58e3d05d57e344e..734a76f018dfc1deaa9bf2cfb= d4fa0d6885f0546 100644 > --- a/img/app/Makefile > +++ b/img/app/Makefile > @@ -53,7 +53,10 @@ VM_FILES =3D \ > etc/s6-linux-init/scripts/rc.init \ > etc/s6-linux-init/scripts/rc.shutdown \ > etc/s6-linux-init/scripts/rc.shutdown.final \ > - etc/xdg/xdg-desktop-portal/portals.conf > + etc/xdg/xdg-desktop-portal/portals.conf \ > + etc/pipewire/pipewire.conf \ > + etc/wireplumber/wireplumber.conf Sorting > diff --git a/img/app/etc/pipewire/pipewire.conf b/img/app/etc/pipewire/pi= pewire.conf > new file mode 100644 > index 0000000000000000000000000000000000000000..cbea25d2c7ca274db8a3c8772= 439b0d3a8279f13 > --- /dev/null > +++ b/img/app/etc/pipewire/pipewire.conf > @@ -0,0 +1,199 @@ > +# SPDX-License-Identifier: MIT > + > +# Copyright =C2=A9 2018 Wim Taymans > +# Copyright =C2=A9 2025 Demi Marie Obenour > +# > +# Permission is hereby granted, free of charge, to any person obtaining a > +# copy of this software and associated documentation files (the "Softwar= e"), > +# to deal in the Software without restriction, including without limitat= ion > +# the rights to use, copy, modify, merge, publish, distribute, sublicens= e, > +# and/or sell copies of the Software, and to permit persons to whom the > +# Software is furnished to do so, subject to the following conditions: > +# > +# The above copyright notice and this permission notice (including the n= ext > +# paragraph) shall be included in all copies or substantial portions of = the > +# Software. > +# > +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRES= S OR > +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILIT= Y, > +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHA= LL > +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR O= THER > +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > +# DEALINGS IN THE SOFTWARE. > + > +# This file is based on the upstream default configuration. This can be > +# found in upstream GitLab or in any distro with a recent version of Pip= eWire. > +# The following changes have been made: > +# > +# - Conditions that have known values in Spectrum VMs are omitted. > +# - Modules for hardware devices Spectrum VMs don't have are not loaded. > +# - The PulseAudio emulation server is loaded. > +# - Settings for VMs are applied unconditionally. > +# - Most comments in the upstream files have been removed. > +# - Device nodes for virtio-sound devices have been added. > +# - Integration with udev and logind is removed. > +context.properties =3D { > + # Upstream defaults. > + link.max-buffers =3D 16 > + core.daemon =3D true > + core.name =3D pipewire-0 > + # Account for running in a VM > + default.clock.min-quantum =3D 1024 > +} > + > +# Upstream defaults, with support for AVB, V4L2, libcamera > +# bluez, Vulkan, JACK, and video conversion omitted. > +context.spa-libs =3D { > + audio.convert.* =3D audioconvert/libspa-audioconvert > + api.alsa.* =3D alsa/libspa-alsa > + support.* =3D support/libspa-support > +} Any reason not to enable JACK? > + > +context.modules =3D [ > + # Upstream defaults > + { name =3D libpipewire-module-rt > + args =3D { nice.level =3D -11, rt.prio =3D 88 } > + } > + { name =3D libpipewire-module-protocol-native } > + { name =3D libpipewire-module-metadata } > + { name =3D libpipewire-module-spa-device-factory } > + { name =3D libpipewire-module-spa-node-factory } > + { name =3D libpipewire-module-client-node } > + { name =3D libpipewire-module-access } > + { name =3D libpipewire-module-client-device } > + { name =3D libpipewire-module-portal } > + { name =3D libpipewire-module-adapter } > + { name =3D libpipewire-module-link-factory } > + { name =3D libpipewire-module-session-manager } > + > + # Load the PulseAudio server into PipeWire. > + # This avoids needing a separate pipewire-pulse > + # process. The args are those used when running > + # in a VM. > + { name =3D libpipewire-module-protocol-pulse > + args =3D { > + server.address =3D [ "unix:native" ] > + pulse.min.quantum =3D 1024/48000 > + } > + } So does upstream not load it into PipeWire? > +] > + > +context.objects =3D [ > + # Upstream defaults > + { factory =3D spa-node-factory > + args =3D { > + factory.name =3D support.node.driver > + node.name =3D Dummy-Driver > + node.group =3D pipewire.dummy > + node.sync-group =3D sync.dummy > + priority.driver =3D 200000 > + } > + } > + { factory =3D spa-node-factory > + args =3D { > + factory.name =3D support.node.driver > + node.name =3D Freewheel-Driver > + priority.driver =3D 190000 > + node.group =3D pipewire.freewheel > + node.sync-group =3D sync.dummy > + node.freewheel =3D true > + } > + } > + > + # Spectrum doesn't use udev, so device nodes must be created statica= lly. > + # Creating them with pw-cli works as long as pw-cli is running, but > + # the nodes are destroyed when pw-cli exits. > + { factory =3D adapter > + args =3D { > + alsa.card =3D 0, > + alsa.card_name =3D "VirtIO SoundCard" > + alsa.device =3D 0 > + alsa.driver_name =3D "virtio_snd" > + alsa.id =3D "SoundCard" > + alsa.long_card_name =3D "VirtIO SoundCard at pci/0000:00:= 01.0/virtio0" > + alsa.name =3D "VirtIO SoundCard" > + alsa.subdevice =3D 0 > + alsa.subdevice_name =3D "subdevice #0" > + api.alsa.card.longname =3D "VirtIO SoundCard at pci/0000:00:= 01.0/virtio0" > + api.alsa.card.name =3D "VirtIO SoundCard" > + api.alsa.headroom =3D 0 > + api.alsa.path =3D "hw:0,0,0" > + api.alsa.pcm.card =3D 0, > + api.alsa.pcm.stream =3D "playback" > + audio.allowed-rates =3D [ ] > + audio.channels =3D 2 > + audio.format =3D "S32" > + audio.position =3D "FL,FR" > + audio.rate =3D 48000 > + factory.name =3D "api.alsa.pcm.sink" > + media.class =3D "Audio/Sink" > + node.name =3D "alsa_output" > + node.suspend-on-idle =3D true > + } > + } > + { factory =3D adapter > + args =3D { > + alsa.card =3D 0, > + alsa.card_name =3D "VirtIO SoundCard" > + alsa.device =3D 0 > + alsa.driver_name =3D "virtio_snd" > + alsa.id =3D "SoundCard" > + alsa.long_card_name =3D "VirtIO SoundCard at pci/0000:00:= 01.0/virtio0" > + alsa.name =3D "VirtIO SoundCard" > + alsa.subdevice =3D 0 > + alsa.subdevice_name =3D "subdevice #0" > + api.alsa.card.longname =3D "VirtIO SoundCard at pci/0000:00:= 01.0/virtio0" > + api.alsa.card.name =3D "VirtIO SoundCard" > + api.alsa.headroom =3D 0 > + api.alsa.path =3D "hw:0,0,0" > + api.alsa.pcm.card =3D 0, > + api.alsa.pcm.stream =3D "capture" > + audio.allowed-rates =3D [ ] > + audio.channels =3D 2 > + audio.format =3D "S32" > + audio.position =3D "FL,FR" > + audio.rate =3D 48000 > + factory.name =3D "api.alsa.pcm.source" > + media.class =3D "Audio/Source" > + node.name =3D "alsa_input" > + node.suspend-on-idle =3D true > + } > + } > +] > + > +# Load the modules that are in the default config *except* > +# for ones whose job is to maintain state. > +pulse.cmd =3D [ > + { cmd =3D "load-module" args =3D "module-always-sink" flags =3D [ ] } > + { cmd =3D "load-module" args =3D "module-device-manager" flags =3D [= ] } > +] > + > +# More default stuff. > +pulse.rules =3D [ > + { > + matches =3D [ > + { application.process.binary =3D "teams" } > + { application.process.binary =3D "teams-insiders" } > + { application.process.binary =3D "teams-for-linux" } > + { application.process.binary =3D "skypeforlinux" } > + ] > + actions =3D { quirks =3D [ force-s16-info ] } > + } > + { > + matches =3D [ { application.process.binary =3D "firefox" } ] > + actions =3D { quirks =3D [ remove-capture-dont-move ] } > + } > + { > + matches =3D [ { application.name =3D "~speech-dispatcher.*" } ] > + actions =3D { > + update-props =3D { > + pulse.min.req =3D 512/48000 > + pulse.min.quantum =3D 512/48000 > + pulse.idle.timeout =3D 5 > + } > + } > + } > +] > + > +context.exec =3D [] I like this a lot better now, thanks! > diff --git a/img/app/etc/s6-rc/pipewire/dependencies.d/mdevd b/img/app/et= c/s6-rc/pipewire/dependencies.d/mdevd > new file mode 100644 > index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae7= 75ad8c2e48c5391 Probably not necessary, given we wait for the device anyway? > diff --git a/img/app/etc/wireplumber/wireplumber.conf b/img/app/etc/wirep= lumber/wireplumber.conf > new file mode 100644 > index 0000000000000000000000000000000000000000..68871e93083572976bba29b44= f07eb35b86c0275 > --- /dev/null > +++ b/img/app/etc/wireplumber/wireplumber.conf > @@ -0,0 +1,536 @@ > +# SPDX-License-Identifier: MIT > + > +# Copyright =C2=A9 2019-2021 Collabora Ltd. > +# > +# Permission is hereby granted, free of charge, to any person obtaining a > +# copy of this software and associated documentation files (the "Softwar= e"), > +# to deal in the Software without restriction, including without limitat= ion > +# the rights to use, copy, modify, merge, publish, distribute, sublicens= e, > +# and/or sell copies of the Software, and to permit persons to whom the > +# Software is furnished to do so, subject to the following conditions: > +# > +# The above copyright notice and this permission notice (including the n= ext > +# paragraph) shall be included in all copies or substantial portions of = the > +# Software. > +# > +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRES= S OR > +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILIT= Y, > +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHA= LL > +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR O= THER > +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > +# DEALINGS IN THE SOFTWARE. > + > +# This file is based on the upstream default configuration. This can be > +# found in upstream GitLab or in any distro with a recent version of Wir= ePlumber. > +# The following changes have been made: > +# > +# - Conditions that have known values in Spectrum VMs are omitted. > +# - Modules for hardware devices Spectrum VMs don't have are not loaded. > +# - Settings for VMs are applied unconditionally. > +# - Most comments in the upstream files have been removed. > +# - Integration with udev and logind is removed. > +# - RT scheduling for the data thread is enabled. > +# - The settings are those appropriate for a system-wide instance. > + > +context.spa-libs =3D { > + api.alsa.* =3D alsa/libspa-alsa > + audio.convert.* =3D audioconvert/libspa-audioconvert > + support.* =3D support/libspa-support > +} > + > +# Upstream default, with RT scheduling enabled. > +context.modules =3D [ > + { > + name =3D libpipewire-module-rt > + args =3D { nice.level =3D -11, rt.prio =3D 88 } > + } > + { name =3D libpipewire-module-protocol-native } > + { name =3D libpipewire-module-metadata } > +] > + > +wireplumber.profiles =3D { > + main =3D { > + metadata.sm-settings =3D required > + metadata.sm-objects =3D required > + > + policy.standard =3D required > + > + hardware.audio =3D required > + > + # PipeWire Media Session is not running. > + # Do not bother to check. > + check.no-media-session =3D disabled > + > + # No Bluetooth > + hardware.bluetooth =3D disabled > + bluetooth.use-persistent-storage =3D disabled > + bluetooth.autoswitch-to-headset-profile =3D disabled It's enabled by default? --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQRV/neXydHjZma5XLJbRZGEIw/wogUCaH4LawAKCRBbRZGEIw/w oj3fAQC4EMSGXCVRq+txeCzM0+x4DILyz0Q+g4RM6LAmXdwG5wD/Xh3vToZ+1+eX otXucL3hjFadpDAnxxFSE2T8T1qNDAw= =KvWt -----END PGP SIGNATURE----- --=-=-=--