patches and low-level development discussion
 help / color / mirror / code / Atom feed
From: Demi Marie Obenour <demiobenour@gmail.com>
To: Spectrum OS Development <devel@spectrum-os.org>
Cc: Alyssa Ross <hi@alyssa.is>, Demi Marie Obenour <demiobenour@gmail.com>
Subject: [PATCH v10] img/app: Run PipeWire and WirePlumber in the VMs
Date: Wed, 30 Jul 2025 05:59:10 -0400	[thread overview]
Message-ID: <20250730-pipewire-v10-v10-1-0f7a7ee80943@gmail.com> (raw)
In-Reply-To: <cover.1753748336.git.demiobenour@gmail.com>

WirePlumber is completely overkill as a session manager here, and
ideally a trivial session manager would be used instead.  PipeWire is
configured to listen on the PulseAudio socket, so PulseAudio
compatibility works.  pw-record and pw-play both work, and if PulseAudio
is installed paplay and parecord also work.  This does install a lot of
unnecessary files into the VMs, which will hopefully be removed
later as part of a debloating effort.

Only run-qemu has had a virtio-sound device added, as crosvm and Cloud
Hypervisor require a virtio-user sound device and that is more complex
to set up.

PipeWire and WirePlumber require that "$XDG_RUNTIME_DIR" exist, so
create it in rc.init.  Having a separate service to create a single
directory is not worthwhile.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Changes since v9:
- Consider PipeWire to be ready as soon as its sockets are listening,
  rather than waiting for the sound device to be available.
- Pull WirePlumber in via ok-all instead of app.  This avoids blocking
  app startup until WirePlumber is started.
- Have the app depend on PipeWire now that it no longer depends on
  WirePlumber.
- Delete an unused file.  It was meant to indicate that PipeWire depends
  on dbus, but it actually doesn't, and the file was not included in the
  VM image anyway.
- Do not create any additional directories beyond "$XDG_RUNTIME_DIR" in
  early boot.  This should be done in a separate patch series.
- Avoid mentioning old stuff in a commit message.

Changes since v8:
- Add longer explanation for the priority.driver and priority.session
  values.
- Give credit to George Kiagiadakis.
- Fix spelling errors in comments.

Changes since v7:
- Give the capture node a higher priority.session than the playback
  node, so WirePlumber links recording applications to the capture node
  instead of the monitor of the playback node.
- Give the capture node a higher priority.driver than the playback node,
  so PipeWire has the capture node drive the graph.  This is better
  because capture xruns lead to permanently corrupted data, whereas
  playback xruns do not.
- Re-enable monitor node creation in WirePlumber.

Changes since v6:
- Add missing S-o-b to directory creation patch.
- Add comments explaining why each directory needs to be created.
- Fix spelling errors in commit messages.
- Sort lines in Makefile.
- Don't disable support.settings as a comment in wireplumber.conf says
  to not do that.  Instead, tell WirePlumber to not create monitor
  nodes.  This is a workaround for WirePlumber bug 829.
- Don't remove "-cpu host" from make run-qemu's QEMU command line.  This
  was needed for local testing with KVM disabled but should not have
  been submitted upstream.  Hardware with KVM support should be used
  instead.

Changes since v5:

- Move changes to startup scripts into a single patch.
- Remove "directories" service in favor of creating the directories from
  rc.init.
- Use VM_DIRS to create /run/user and /run/wait.
- Create /run/user and /run/wait on the host as well, using the same
  mechanism as for the VM (though with a different variable name in the
  makefile).
- Use a drop-in configuration file for WirePlumber instead of overriding
  wireplumber.conf.  This should be more robust to future WirePlumber
  changes.
---
 img/app/Makefile                                   |  16 +-
 img/app/default.nix                                |   3 +
 img/app/etc/mdev.conf                              |   1 +
 img/app/etc/pipewire/pipewire.conf                 | 227 +++++++++++++++++++++
 img/app/etc/s6-linux-init/scripts/rc.init          |   4 +
 img/app/etc/s6-rc/app/dependencies.d/pipewire      |   0
 img/app/etc/s6-rc/ok-all/contents                  |   1 +
 img/app/etc/s6-rc/pipewire/notification-fd         |   1 +
 img/app/etc/s6-rc/pipewire/notification-fd.license |   2 +
 img/app/etc/s6-rc/pipewire/run                     |  23 +++
 img/app/etc/s6-rc/pipewire/type                    |   1 +
 img/app/etc/s6-rc/pipewire/type.license            |   2 +
 img/app/etc/s6-rc/wayland-proxy-virtwl/run         |   4 -
 img/app/etc/s6-rc/wireplumber/dependencies.d/dbus  |   0
 .../etc/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 +
 .../wireplumber.conf.d/99_spectrum.conf            |  42 ++++
 19 files changed, 328 insertions(+), 6 deletions(-)

diff --git a/img/app/Makefile b/img/app/Makefile
index 4b4d64f81d99a01eebe777f3737fef813ebb6d3f..c347300a326c1429a731e1173fe7599534c43014 100644
--- a/img/app/Makefile
+++ b/img/app/Makefile
@@ -40,6 +40,7 @@ VM_FILES = \
 	etc/mdev/virtiofs \
 	etc/mdev/wait \
 	etc/passwd \
+	etc/pipewire/pipewire.conf \
 	etc/resolv.conf \
 	etc/s6-linux-init/env/DBUS_SESSION_BUS_ADDRESS \
 	etc/s6-linux-init/env/DISPLAY \
@@ -47,13 +48,15 @@ VM_FILES = \
 	etc/s6-linux-init/env/NIX_XDG_DESKTOP_PORTAL_DIR \
 	etc/s6-linux-init/env/WAYLAND_DISPLAY \
 	etc/s6-linux-init/env/XDG_RUNTIME_DIR \
+	etc/s6-linux-init/run-image/service/getty-hvc0/run \
 	etc/s6-linux-init/run-image/service/s6-linux-init-shutdownd/notification-fd \
 	etc/s6-linux-init/run-image/service/s6-linux-init-shutdownd/run \
-	etc/s6-linux-init/run-image/service/getty-hvc0/run \
 	etc/s6-linux-init/scripts/rc.init \
 	etc/s6-linux-init/scripts/rc.shutdown \
 	etc/s6-linux-init/scripts/rc.shutdown.final \
+	etc/wireplumber/wireplumber.conf.d/99_spectrum.conf \
 	etc/xdg/xdg-desktop-portal/portals.conf
+
 VM_DIRS = dev run proc sys tmp \
 	etc/s6-linux-init/run-image/service \
 	etc/s6-linux-init/run-image/user \
@@ -84,6 +87,7 @@ build/rootfs.erofs: ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(VM_FILES) $(V
 
 VM_S6_RC_FILES = \
 	etc/s6-rc/app/dependencies.d/dbus \
+	etc/s6-rc/app/dependencies.d/pipewire \
 	etc/s6-rc/app/dependencies.d/wayland-proxy-virtwl \
 	etc/s6-rc/app/run \
 	etc/s6-rc/app/type \
@@ -98,9 +102,16 @@ VM_S6_RC_FILES = \
 	etc/s6-rc/mdevd/type \
 	etc/s6-rc/ok-all/contents \
 	etc/s6-rc/ok-all/type \
+	etc/s6-rc/pipewire/notification-fd \
+	etc/s6-rc/pipewire/run \
+	etc/s6-rc/pipewire/type \
 	etc/s6-rc/wayland-proxy-virtwl/notification-fd \
 	etc/s6-rc/wayland-proxy-virtwl/run \
-	etc/s6-rc/wayland-proxy-virtwl/type
+	etc/s6-rc/wayland-proxy-virtwl/type \
+	etc/s6-rc/wireplumber/dependencies.d/dbus \
+	etc/s6-rc/wireplumber/dependencies.d/pipewire \
+	etc/s6-rc/wireplumber/run \
+	etc/s6-rc/wireplumber/type
 
 build/etc/s6-rc: $(VM_S6_RC_FILES)
 	mkdir -p $$(dirname $@)
@@ -147,6 +158,7 @@ run-qemu: $(imgdir)/appvm/blk/root.img start-vhost-user-net start-virtiofsd
 	    -chardev socket,id=virtiofsd,path=build/virtiofsd.sock \
 	    -device vhost-user-fs-pci,chardev=virtiofsd,tag=virtiofs0 \
 	    -device virtio-gpu-rutabaga-pci,cross-domain=on,hostmem=8G \
+	    -audio driver=pipewire,model=virtio \
 	    -object memory-backend-memfd,id=mem,size=256M,share=on \
 	    -numa node,memdev=mem \
 	    -device vhost-vsock-pci,guest-cid=3 \
diff --git a/img/app/default.nix b/img/app/default.nix
index 740643ac41f6473cdb6f6b0fd1f5f47f4493240d..d3eed1f0accdc8968d1ba5bdec74ab597789082f 100644
--- a/img/app/default.nix
+++ b/img/app/default.nix
@@ -48,6 +48,9 @@ let
       pkgs.xwayland
       pkgs.xdg-desktop-portal
       pkgs.xdg-desktop-portal-gtk
+      # Depends on pulseaudio libs
+      pkgs.pipewire
+      pkgs.wireplumber
     ];
   })).fhsenv;
 in
diff --git a/img/app/etc/mdev.conf b/img/app/etc/mdev.conf
index f2101e1f683c49808358b25520080c59ed2afa8e..0e4a1a088522c05da9e0ce15fe135c40d6cf3064 100644
--- a/img/app/etc/mdev.conf
+++ b/img/app/etc/mdev.conf
@@ -5,3 +5,4 @@
 $INTERFACE=.* 0:0 660 ! +/etc/mdev/iface
 $MODALIAS=virtio:d0000001Av.* 0:0 660 ! +/etc/mdev/virtiofs
 dri/card0 0:0 660 +background { /etc/mdev/listen card0 }
+snd/controlC0 0:0 660 +background { /etc/mdev/listen controlC0 }
diff --git a/img/app/etc/pipewire/pipewire.conf b/img/app/etc/pipewire/pipewire.conf
new file mode 100644
index 0000000000000000000000000000000000000000..5f1e34145e9dcb1497f7aa7bb0461f0f13931b1a
--- /dev/null
+++ b/img/app/etc/pipewire/pipewire.conf
@@ -0,0 +1,227 @@
+# SPDX-License-Identifier: MIT
+
+# Copyright © 2018 Wim Taymans
+# Copyright © 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 "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# 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 next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# 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 PipeWire.
+# 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 = {
+    # Upstream defaults.
+    link.max-buffers = 16
+    core.daemon = true
+    core.name   = pipewire-0
+    # Account for running in a VM
+    default.clock.min-quantum = 1024
+}
+
+# Upstream defaults, with support for AVB, V4L2, libcamera
+# bluez, Vulkan, JACK, and video conversion omitted.
+context.spa-libs = {
+    audio.convert.* = audioconvert/libspa-audioconvert
+    api.alsa.*      = alsa/libspa-alsa
+    support.*       = support/libspa-support
+}
+
+context.modules = [
+    # Upstream defaults
+    { name = libpipewire-module-rt
+        args = { nice.level = -11, rt.prio = 88 }
+    }
+    { name = libpipewire-module-protocol-native  }
+    { name = libpipewire-module-metadata }
+    { name = libpipewire-module-spa-device-factory }
+    { name = libpipewire-module-spa-node-factory }
+    { name = libpipewire-module-client-node }
+    { name = libpipewire-module-access }
+    { name = libpipewire-module-client-device }
+    { name = libpipewire-module-portal }
+    { name = libpipewire-module-adapter }
+    { name = libpipewire-module-link-factory }
+    { name = 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 = libpipewire-module-protocol-pulse
+        args = {
+            server.address = [ "unix:native" ]
+            pulse.min.quantum = 1024/48000
+        }
+    }
+]
+
+context.objects = [
+    # Upstream defaults
+    { factory = spa-node-factory
+        args = {
+            factory.name    = support.node.driver
+            node.name       = Dummy-Driver
+            node.group      = pipewire.dummy
+            node.sync-group = sync.dummy
+            priority.driver = 200000
+        }
+    }
+    { factory = spa-node-factory
+        args = {
+            factory.name    = support.node.driver
+            node.name       = Freewheel-Driver
+            priority.driver = 190000
+            node.group      = pipewire.freewheel
+            node.sync-group = sync.dummy
+            node.freewheel  = true
+        }
+    }
+
+    # Spectrum doesn't use udev, so device nodes must be created statically.
+    # Creating them with pw-cli works as long as pw-cli is running, but
+    # the nodes are destroyed when pw-cli exits.
+    #
+    # PipeWire chooses the node with the highest priority.driver value as
+    # graph driver, which is the node that decides when the processing graph
+    # is going to run.  If both the capture node and playback node are in
+    # the same graph, the capture node should be chosen as the driver.  This
+    # is because the driver gets to choose the rate of the graph and so is
+    # much less likely to xrun.  Since capture xruns result in corrupted
+    # audio recordings, while playback xruns just result in a glitch, it
+    # is more important to avoid capture xruns.
+    #
+    # When there are multiple sources or sinks that could be used,
+    # WirePlumber links application nodes to the one with the highest
+    # priority.session value.  In the configuration created here,
+    # there are two valid audio sources: the virtio sound card's
+    # capture stream and the monitor of its playback stream.  The
+    # capture stream is the correct choice, so its priority.session
+    # should be higher.
+    #
+    # The recommendation to give the capture device higher values
+    # for priority.driver and priority.session comes from George
+    # Kiagiadakis of Collabora, who also provided the values
+    # used (2000 and 1000) and why they must be different.
+    # See <https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues/829#note_3027666>.
+    { factory = adapter
+        args = {
+            alsa.card              = 0,
+            alsa.card_name         = "VirtIO SoundCard"
+            alsa.device            = 0
+            alsa.driver_name       = "virtio_snd"
+            alsa.id                = "SoundCard"
+            alsa.long_card_name    = "VirtIO SoundCard at pci/0000:00:01.0/virtio0"
+            alsa.name              = "VirtIO SoundCard"
+            alsa.subdevice         = 0
+            alsa.subdevice_name    = "subdevice #0"
+            api.alsa.card.longname = "VirtIO SoundCard at pci/0000:00:01.0/virtio0"
+            api.alsa.card.name     = "VirtIO SoundCard"
+            api.alsa.headroom      = 0
+            api.alsa.path          = "hw:0,0,0"
+            api.alsa.pcm.card      = 0,
+            api.alsa.pcm.stream    = "playback"
+            audio.allowed-rates    = [ ]
+            audio.channels         = 2
+            audio.format           = "S32"
+            audio.position         = "FL,FR"
+            audio.rate             = 48000
+            factory.name           = "api.alsa.pcm.sink"
+            media.class            = "Audio/Sink"
+            node.name              = "alsa_output.pci-0000_00_01.0.analog-stereo"
+            node.suspend-on-idle   = true
+            priority.driver        = 1000
+            priority.session       = 1000
+        }
+    }
+
+    { factory = adapter
+        args = {
+            alsa.card              = 0,
+            alsa.card_name         = "VirtIO SoundCard"
+            alsa.device            = 0
+            alsa.driver_name       = "virtio_snd"
+            alsa.id                = "SoundCard"
+            alsa.long_card_name    = "VirtIO SoundCard at pci/0000:00:01.0/virtio0"
+            alsa.name              = "VirtIO SoundCard"
+            alsa.subdevice         = 0
+            alsa.subdevice_name    = "subdevice #0"
+            api.alsa.card.longname = "VirtIO SoundCard at pci/0000:00:01.0/virtio0"
+            api.alsa.card.name     = "VirtIO SoundCard"
+            api.alsa.headroom      = 0
+            api.alsa.path          = "hw:0,0,0"
+            api.alsa.pcm.card      = 0,
+            api.alsa.pcm.stream    = "capture"
+            audio.allowed-rates    = [ ]
+            audio.channels         = 2
+            audio.format           = "S32"
+            audio.position         = "FL,FR"
+            audio.rate             = 48000
+            factory.name           = "api.alsa.pcm.source"
+            media.class            = "Audio/Source"
+            node.name              = "alsa_input.pci-0000_00_01.0.analog-stereo"
+            node.suspend-on-idle   = true
+            priority.driver        = 2000
+            priority.session       = 2000
+        }
+    }
+]
+
+# Load the modules that are in the default config *except*
+# for ones whose job is to maintain state.
+pulse.cmd = [
+    { cmd = "load-module" args = "module-always-sink" flags = [ ] }
+    { cmd = "load-module" args = "module-device-manager" flags = [ ] }
+]
+
+# More default stuff.
+pulse.rules = [
+    {
+        matches = [
+             { application.process.binary = "teams" }
+             { application.process.binary = "teams-insiders" }
+             { application.process.binary = "teams-for-linux" }
+             { application.process.binary = "skypeforlinux" }
+        ]
+        actions = { quirks = [ force-s16-info ] }
+    }
+    {
+        matches = [ { application.process.binary = "firefox" } ]
+        actions = { quirks = [ remove-capture-dont-move ] }
+    }
+    {
+        matches = [ { application.name = "~speech-dispatcher.*" } ]
+        actions = {
+            update-props = {
+                pulse.min.req          = 512/48000
+                pulse.min.quantum      = 512/48000
+                pulse.idle.timeout     = 5
+            }
+        }
+    }
+]
+
+context.exec = []
diff --git a/img/app/etc/s6-linux-init/scripts/rc.init b/img/app/etc/s6-linux-init/scripts/rc.init
index c5a59245ff3761e94acb974edde967806fb3b234..049603696ab94dee38251bf472814e02cc268ec0 100755
--- a/img/app/etc/s6-linux-init/scripts/rc.init
+++ b/img/app/etc/s6-linux-init/scripts/rc.init
@@ -1,10 +1,14 @@
 #!/bin/execlineb -P
 # SPDX-License-Identifier: EUPL-1.2+
 # SPDX-FileCopyrightText: 2020-2022 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
 
 if { s6-rc-init -c /etc/s6-rc /run/service }
 
 if { modprobe overlay }
 if { mount -a --mkdir }
 
+# /run/user/0: "$XDG_RUNTIME_DIR"
+if { mkdir -m 0700 /run/user/0 }
+
 s6-rc change ok-all
diff --git a/img/app/etc/s6-rc/app/dependencies.d/pipewire b/img/app/etc/s6-rc/app/dependencies.d/pipewire
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/img/app/etc/s6-rc/ok-all/contents b/img/app/etc/s6-rc/ok-all/contents
index 92f3ef1632fee9d5909c95d031f9646c8aafb7de..6788e54384f065890d00d77378ea5c45ec89f61c 100644
--- a/img/app/etc/s6-rc/ok-all/contents
+++ b/img/app/etc/s6-rc/ok-all/contents
@@ -2,4 +2,5 @@
 # SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is>
 #
 mdevd-coldplug
+wireplumber
 app
diff --git a/img/app/etc/s6-rc/pipewire/notification-fd b/img/app/etc/s6-rc/pipewire/notification-fd
new file mode 100644
index 0000000000000000000000000000000000000000..7ed6ff82de6bcc2a78243fc9c54d3ef5ac14da69
--- /dev/null
+++ b/img/app/etc/s6-rc/pipewire/notification-fd
@@ -0,0 +1 @@
+5
diff --git a/img/app/etc/s6-rc/pipewire/notification-fd.license b/img/app/etc/s6-rc/pipewire/notification-fd.license
new file mode 100644
index 0000000000000000000000000000000000000000..c4a0586a407fe14c3e0855749a7524ac3871dda4
--- /dev/null
+++ b/img/app/etc/s6-rc/pipewire/notification-fd.license
@@ -0,0 +1,2 @@
+SPDX-License-Identifier: CC0-1.0
+SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
diff --git a/img/app/etc/s6-rc/pipewire/run b/img/app/etc/s6-rc/pipewire/run
new file mode 100644
index 0000000000000000000000000000000000000000..ab469019ab447e977fd5924d6d12024a11dfe5a6
--- /dev/null
+++ b/img/app/etc/s6-rc/pipewire/run
@@ -0,0 +1,23 @@
+#!/bin/execlineb -P
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2023-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+
+s6-ipcserver-socketbinder -B /run/user/0/pipewire-0
+fdmove -c 3 0
+
+s6-ipcserver-socketbinder -B /run/user/0/pipewire-0-manager
+fdmove -c 4 0
+
+redirfd -r 0 /dev/null
+
+# Notify readiness.
+if { fdmove 1 5 echo }
+fdclose 5
+
+# Wait for sound devices to be available
+if { /etc/mdev/wait controlC0 }
+
+export LISTEN_FDS 2
+getpid LISTEN_PID
+pipewire
diff --git a/img/app/etc/s6-rc/pipewire/type b/img/app/etc/s6-rc/pipewire/type
new file mode 100644
index 0000000000000000000000000000000000000000..5883cff0cd1514b2836f4ffa39fdac769a5213cb
--- /dev/null
+++ b/img/app/etc/s6-rc/pipewire/type
@@ -0,0 +1 @@
+longrun
diff --git a/img/app/etc/s6-rc/pipewire/type.license b/img/app/etc/s6-rc/pipewire/type.license
new file mode 100644
index 0000000000000000000000000000000000000000..c4a0586a407fe14c3e0855749a7524ac3871dda4
--- /dev/null
+++ b/img/app/etc/s6-rc/pipewire/type.license
@@ -0,0 +1,2 @@
+SPDX-License-Identifier: CC0-1.0
+SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
diff --git a/img/app/etc/s6-rc/wayland-proxy-virtwl/run b/img/app/etc/s6-rc/wayland-proxy-virtwl/run
index 0715d912953c8a1d326059dfd37c29799fcbb053..df9173a1de36b92648f88947b63e32b71b85118a 100755
--- a/img/app/etc/s6-rc/wayland-proxy-virtwl/run
+++ b/img/app/etc/s6-rc/wayland-proxy-virtwl/run
@@ -7,10 +7,6 @@
 # SPDX-FileCopyrightText: 2022 Unikie
 
 foreground { mkdir /tmp/.X11-unix }
-foreground {
-  umask 077
-  mkdir /run/user/0
-}
 
 s6-ipcserver-socketbinder -B /run/user/0/wayland-0
 fdmove -c 3 0
diff --git a/img/app/etc/s6-rc/wireplumber/dependencies.d/dbus b/img/app/etc/s6-rc/wireplumber/dependencies.d/dbus
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/img/app/etc/s6-rc/wireplumber/dependencies.d/pipewire b/img/app/etc/s6-rc/wireplumber/dependencies.d/pipewire
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/img/app/etc/s6-rc/wireplumber/run b/img/app/etc/s6-rc/wireplumber/run
new file mode 100644
index 0000000000000000000000000000000000000000..d58f1971c7387c896256a91ad0c92386a02fd9e2
--- /dev/null
+++ b/img/app/etc/s6-rc/wireplumber/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+wireplumber --profile spectrum
diff --git a/img/app/etc/s6-rc/wireplumber/type b/img/app/etc/s6-rc/wireplumber/type
new file mode 100644
index 0000000000000000000000000000000000000000..5883cff0cd1514b2836f4ffa39fdac769a5213cb
--- /dev/null
+++ b/img/app/etc/s6-rc/wireplumber/type
@@ -0,0 +1 @@
+longrun
diff --git a/img/app/etc/s6-rc/wireplumber/type.license b/img/app/etc/s6-rc/wireplumber/type.license
new file mode 100644
index 0000000000000000000000000000000000000000..c4a0586a407fe14c3e0855749a7524ac3871dda4
--- /dev/null
+++ b/img/app/etc/s6-rc/wireplumber/type.license
@@ -0,0 +1,2 @@
+SPDX-License-Identifier: CC0-1.0
+SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
diff --git a/img/app/etc/wireplumber/wireplumber.conf.d/99_spectrum.conf b/img/app/etc/wireplumber/wireplumber.conf.d/99_spectrum.conf
new file mode 100644
index 0000000000000000000000000000000000000000..277e6019c46582afba12af9b1a27bb16ddd9e804
--- /dev/null
+++ b/img/app/etc/wireplumber/wireplumber.conf.d/99_spectrum.conf
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2019-2021 Collabora Ltd.
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour
+
+# Copyright © 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 "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# 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 next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# 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.
+
+wireplumber.profiles = {
+  spectrum = {
+    # Spectrum VMs are essentially embedded systems, in that they are
+    # not at all general-purpose.
+    inherits = [ main-embedded ]
+    # Disable video and Bluetooth
+    hardware.video-capture = disabled
+    hardware.bluetooth = disabled
+    # Media Session is definitely not running
+    check.no-media-session = disabled
+  }
+}
+
+wireplumber.settings = {
+  # Default to 100% sink volume.  The host will adjust this as needed.
+  device.routes.default-sink-volume = 1.0
+}

---
base-commit: 560fd878ba1bbd8df0fe28488e72948f28940948
change-id: 20250729-pipewire-v10-bb873ebb3560
-- 
Sincerely,
Demi Marie Obenour (she/her/hers)


  parent reply	other threads:[~2025-07-31  0:59 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-11  2:44 [PATCH v3] Run PipeWire and WirePlumber in the VMs Demi Marie Obenour
2025-07-14 14:54 ` Alyssa Ross
2025-07-15 20:22   ` Demi Marie Obenour
2025-07-16 10:26     ` Alyssa Ross
2025-07-16 21:16   ` Demi Marie Obenour
2025-07-16 21:27     ` Demi Marie Obenour
2025-07-18 12:16       ` Alyssa Ross
2025-07-17  5:53   ` Demi Marie Obenour
2025-07-18 10:02     ` Alyssa Ross
2025-07-18 10:19       ` Alyssa Ross
2025-07-18  2:07 ` [PATCH v4 0/3] Sound support in Spectrum VMs Demi Marie Obenour
2025-07-18  2:13   ` [PATCH v4 1/3] Rebuild the root filesystem when the makefile changes Demi Marie Obenour
2025-07-18 11:14     ` Alyssa Ross
2025-07-18  2:13   ` [PATCH v4 2/3] Fix permissions on /tmp Demi Marie Obenour
2025-07-18 11:51     ` Alyssa Ross
2025-07-18 11:51     ` Alyssa Ross
2025-07-18 11:53     ` Alyssa Ross
2025-07-18  2:14   ` [PATCH v4 3/3] Run PipeWire and WirePlumber in the VMs Demi Marie Obenour
2025-07-18 11:27     ` Alyssa Ross
2025-07-18 17:59       ` Demi Marie Obenour
2025-07-19  9:22         ` Alyssa Ross
2025-07-19 20:05           ` Demi Marie Obenour
2025-07-19  8:06     ` Alyssa Ross
2025-07-19 20:03       ` Demi Marie Obenour
2025-07-19 20:07         ` Demi Marie Obenour
2025-07-20  7:50           ` Alyssa Ross
2025-07-20 17:58   ` [PATCH v5 0/8] Sound support in Spectrum VMs Demi Marie Obenour
2025-07-20 18:02     ` [PATCH v5 1/8] Revert "img/app: fix permissions on /tmp" Demi Marie Obenour
2025-07-21  9:34       ` Alyssa Ross
2025-07-20 18:03     ` [PATCH v5 2/8] img/app: Use separate service to create directories Demi Marie Obenour
2025-07-21  9:21       ` Alyssa Ross
2025-07-22 23:48         ` Demi Marie Obenour
2025-07-20 18:04     ` [PATCH v5 3/8] img/app: Fix permissions of /tmp/.X11-unix Demi Marie Obenour
2025-07-20 18:05     ` [PATCH v5 4/8] img/app: Create other X11 directories Demi Marie Obenour
2025-07-21  9:23       ` Alyssa Ross
2025-07-21 19:03         ` Demi Marie Obenour
2025-07-20 18:06     ` [PATCH v5 5/8] img/app: Be explicit about directory modes Demi Marie Obenour
2025-07-20 18:08     ` [PATCH v5 6/8] img/app: create /run/user and /run/wait very early in boot Demi Marie Obenour
2025-07-21  9:23       ` Alyssa Ross
2025-07-20 18:10     ` [PATCH v5 7/8] host/rootfs: " Demi Marie Obenour
2025-07-20 18:11     ` [PATCH v5 8/8] img/app: Run PipeWire and WirePlumber in the VMs Demi Marie Obenour
2025-07-21  9:42       ` Alyssa Ross
2025-07-21 19:09         ` Demi Marie Obenour
2025-07-26 10:11           ` Alyssa Ross
2025-07-21 19:10         ` Demi Marie Obenour
2025-07-24 22:15     ` [PATCH v6 0/5] Sound support in Spectrum VMs Demi Marie Obenour
2025-07-24 22:30       ` [PATCH v6 1/5] host/rootfs: Create /run/user and /run/wait via run-image Demi Marie Obenour
2025-07-26 10:46         ` Alyssa Ross
2025-07-24 22:32       ` [PATCH v6 2/5] img/app: " Demi Marie Obenour
2025-07-24 22:33       ` [PATCH v6 3/5] img/app: tell mount(8) to create directories Demi Marie Obenour
2025-07-26 11:20         ` Alyssa Ross
2025-07-26 11:26         ` Alyssa Ross
2025-07-24 22:35       ` [PATCH v6 4/5] img/app: Create needed directories in early boot Demi Marie Obenour
2025-07-26 10:24         ` Alyssa Ross
2025-07-27 20:13           ` Demi Marie Obenour
2025-07-24 22:36       ` [PATCH v6 5/5] img/app: Run PipeWire and WirePlumber in the VMs Demi Marie Obenour
2025-07-26 11:29         ` Alyssa Ross
2025-07-26 10:57       ` [PATCH v6 0/5] Sound support in Spectrum VMs Alyssa Ross
2025-07-28  5:57       ` [PATCH v7 0/2] " Demi Marie Obenour
2025-07-28  6:01         ` [PATCH v7 1/2] img/app: Create needed directories in early boot Demi Marie Obenour
2025-07-28  6:03         ` [PATCH v7 2/2] img/app: Run PipeWire and WirePlumber in the VMs Demi Marie Obenour
2025-07-28  6:18           ` Demi Marie Obenour
2025-07-28 23:13         ` [PATCH v8 0/2] Sound support in Spectrum VMs Demi Marie Obenour
2025-07-29  0:32           ` [PATCH v9 " Demi Marie Obenour
2025-07-29  0:33             ` [PATCH v9 1/2] img/app: Create needed directories in early boot Demi Marie Obenour
2025-07-29 12:44               ` Alyssa Ross
2025-07-29  0:33             ` [PATCH v9 2/2] img/app: Run PipeWire and WirePlumber in the VMs Demi Marie Obenour
2025-07-29 13:08               ` Alyssa Ross
2025-07-29 21:17                 ` Demi Marie Obenour
2025-07-30  8:10                   ` Alyssa Ross
2025-07-30  9:59             ` Demi Marie Obenour [this message]
2025-07-31  9:12               ` [PATCH v10] " Alyssa Ross
2025-07-31  9:40               ` Alyssa Ross
2025-07-31 17:06               ` [PATCH v11] " Demi Marie Obenour
2025-08-01 17:53                 ` Alyssa Ross
2025-08-02  7:54                 ` Alyssa Ross
2025-07-28 23:13         ` [PATCH v8 1/2] img/app: Create needed directories in early boot Demi Marie Obenour
2025-07-28 23:19           ` Demi Marie Obenour
2025-07-28 23:13         ` [PATCH v8 2/2] img/app: Run PipeWire and WirePlumber in the VMs Demi Marie Obenour
2025-07-29 12:41         ` [PATCH v7 0/2] Sound support in Spectrum VMs Alyssa Ross
2025-07-24 22:23     ` [PATCH v6 1/5] host/rootfs: Create /run/user and /run/wait via run-image Demi Marie Obenour

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250730-pipewire-v10-v10-1-0f7a7ee80943@gmail.com \
    --to=demiobenour@gmail.com \
    --cc=devel@spectrum-os.org \
    --cc=hi@alyssa.is \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://spectrum-os.org/git/crosvm
	https://spectrum-os.org/git/doc
	https://spectrum-os.org/git/mktuntap
	https://spectrum-os.org/git/nixpkgs
	https://spectrum-os.org/git/spectrum
	https://spectrum-os.org/git/ucspi-vsock
	https://spectrum-os.org/git/www

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).