patches and low-level development discussion
 help / color / mirror / code / Atom feed
blob 6e946b560aa2ff762d42c3e0e3818916500d2883 9468 bytes (raw)
name: img/app/etc/pipewire/pipewire.conf 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
 
# 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>.
    # The explanation for why it is more important to avoid
    # capture xruns than playback xruns comes from past discussions
    # that I (Demi Marie Obenour) had with Wim Taymans.
    { 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 = []

debug log:

solving 6e946b560aa2ff762d42c3e0e3818916500d2883 ...
found 6e946b560aa2ff762d42c3e0e3818916500d2883 in https://inbox.spectrum-os.org/spectrum-devel/20250731-pipewire-v10-v11-1-90ad150e2c00@gmail.com/

applying [1/1] https://inbox.spectrum-os.org/spectrum-devel/20250731-pipewire-v10-v11-1-90ad150e2c00@gmail.com/
diff --git a/img/app/etc/pipewire/pipewire.conf b/img/app/etc/pipewire/pipewire.conf
new file mode 100644
index 0000000000000000000000000000000000000000..6e946b560aa2ff762d42c3e0e3818916500d2883

Checking patch img/app/etc/pipewire/pipewire.conf...
Applied patch img/app/etc/pipewire/pipewire.conf cleanly.

index at:
100644 6e946b560aa2ff762d42c3e0e3818916500d2883	img/app/etc/pipewire/pipewire.conf

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

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).