All pulse clients get stuck for ~1s on all seeking
My node configuration is shown at pipewire#698 (closed) except that now both, built-in and USB, devices get connected to processing pipeline (for some reason, USB one is on top of the graph with pipewire-media-session but with WP it's the other way around).
If I use WP instead of PMS all pulse apps (and only them, it seems) "wait" for about a second on each seek back, forward or start after a long pause. This is likely connected to #67 (closed)
pipewire.conf
context.properties = {
## Configure properties in the system.
#library.name.system = support/libspa-support
#context.data-loop.library.name.system = support/libspa-support
support.dbus = true
link.max-buffers = 64
#link.max-buffers = 16 # version < 3 clients can't handle more
mem.warn-mlock = true
mem.allow-mlock = true
#mem.mlock-all = true
clock.power-of-two-quantum = false
#log.level = 3
cpu.zero.denormals = true
core.daemon = true # listening for socket connections
core.name = pipewire-0 # core name and socket name
## Properties for the DSP configuration.
default.clock.allowed-rates = [ 192000 48000 384000 768000 44100 32000 16000 8000 ]
#default.clock.rate = 48000
#default.clock.quantum = 768
#default.clock.min-quantum = 96
#default.clock.max-quantum = 1536
default.clock.rate = 192000
default.clock.quantum = 3072
default.clock.min-quantum = 384
default.clock.max-quantum = 6144
#
# These overrides are only applied when running in a vm.
vm.overrides = {
default.clock.min-quantum = 1536
}
default.video.width = 1920
default.video.height = 1080
default.video.rate.num = 60
#default.video.rate.denom = 1
}
context.spa-libs = {
#<factory-name regex> = <library-name>
#
# Used to find spa factory names. It maps an spa factory name
# regular expression to a library name that should contain
# that factory.
#
audio.convert.* = audioconvert/libspa-audioconvert
api.alsa.* = alsa/libspa-alsa
api.v4l2.* = v4l2/libspa-v4l2
api.libcamera.* = libcamera/libspa-libcamera
api.bluez5.* = bluez5/libspa-bluez5
api.vulkan.* = vulkan/libspa-vulkan
api.jack.* = jack/libspa-jack
support.* = support/libspa-support
#videotestsrc = videotestsrc/libspa-videotestsrc
#audiotestsrc = audiotestsrc/libspa-audiotestsrc
}
context.modules = [
#{ name = <module-name>
# [ args = { <key> = <value> ... } ]
# [ flags = [ [ ifexists ] [ nofail ] ]
#}
#
# Loads a module with the given parameters.
# If ifexists is given, the module is ignored when it is not found.
# If nofail is given, module initialization failures are ignored.
#
# Use RTKit or native RT to boost the data thread priority.
{ name = libpipewire-module-rt
args = {
nice.level = -14
rt.prio = 44
rt.time.soft = 900000
rt.time.hard = 1900000
}
flags = [ ifexists nofail ]
}
# The native communication protocol.
{ name = libpipewire-module-protocol-native }
# The profile module. Allows application to access profiler
# and performance data. It provides an interface that is used
# by pw-top and pw-profiler.
{ name = libpipewire-module-profiler }
# Allows applications to create metadata objects. It creates
# a factory for Metadata objects.
{ name = libpipewire-module-metadata }
# Creates a factory for making devices that run in the
# context of the PipeWire server.
{ name = libpipewire-module-spa-device-factory }
# Creates a factory for making nodes that run in the
# context of the PipeWire server.
{ name = libpipewire-module-spa-node-factory }
# Allows creating nodes that run in the context of the
# client. Is used by all clients that want to provide
# data to PipeWire.
{ name = libpipewire-module-client-node }
# Allows creating devices that run in the context of the
# client. Is used by the session manager.
{ name = libpipewire-module-client-device }
# The portal module monitors the PID of the portal process
# and tags connections with the same PID as portal
# connections.
{ name = libpipewire-module-portal
flags = [ ifexists nofail ]
}
# The access module can perform access checks and block
# new clients.
{ name = libpipewire-module-access
args = {
# access.allowed to list an array of paths of allowed
# apps.
#access.allowed = [
# /usr/bin/pipewire-media-session
#]
# An array of rejected paths.
#access.rejected = [ ]
# An array of paths with restricted access.
#access.restricted = [ ]
# Anything not in the above lists gets assigned the
# access.force permission.
#access.force = flatpak
}
}
# Makes a factory for wrapping nodes in an adapter with a
# converter and resampler.
{ name = libpipewire-module-adapter }
# Makes a factory for creating links between ports.
{ name = libpipewire-module-link-factory }
# Provides factories to make session manager objects.
{ name = libpipewire-module-session-manager }
]
context.objects = [
#{ factory = <factory-name>
# [ args = { <key> = <value> ... } ]
# [ flags = [ [ nofail ] ]
#}
#
# Creates an object from a PipeWire factory with the given parameters.
# If nofail is given, errors are ignored (and no object is created).
#
#{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
#{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] }
#{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
#{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
#{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test } }
#{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
# A default dummy driver. This handles nodes marked with the "node.always-driver"
# property when no other driver is currently active. JACK clients need this.
{ factory = spa-node-factory
args = {
factory.name = support.node.driver
node.name = "[DUMMY-DRIVER]"
node.group = pipewire.dummy
priority.driver = 20000
node.pause-on-idle = true
#link.passive = true
#device.description = "Dummy shim-device"
}
}
{ factory = spa-node-factory
args = {
factory.name = support.node.driver
node.name = "[FREEWHEEL]"
priority.driver = 19000
node.group = pipewire.freewheel
node.freewheel = true
node.pause-on-idle = true
#link.passive = true
#device.description = "FreeWheel shim for JACK"
}
}
# This creates a new Source node. It will have input ports
# that you can link, to provide audio for this source.
#{ factory = adapter
# args = {
# factory.name = support.null-audio-sink
# node.name = "my-mic"
# node.description = "Microphone"
# media.class = "Audio/Source/Virtual"
# audio.position = "FL,FR"
# }
#}
# This creates a single PCM source device for the given
# alsa device path hw:0. You can change source to sink
# to make a sink in the same way.
#{ factory = adapter
# args = {
# factory.name = api.alsa.pcm.source
# node.name = "alsa-source"
# node.description = "PCM Source"
# media.class = "Audio/Source"
# api.alsa.path = "hw:0"
# api.alsa.period-size = 1024
# api.alsa.headroom = 0
# api.alsa.disable-mmap = false
# api.alsa.disable-batch = false
# audio.format = "S16LE"
# audio.rate = 48000
# audio.channels = 2
# audio.position = "FL,FR"
# }
#}
{ factory = adapter
args = {
factory.name = support.null-audio-sink
node.name = [NULL-DEVICE-AUDIO]
#node.group = pipewire.dummy
priority.driver = 10000
media.class = Audio/Sink
audio.position = [ FL FR ]
#audio.format = F32
#audio.rate = 48000
#resample.quality = 9
volume = 1.0
#node.latency = 384/48000
node.max-latency = 1536/48000
node.pause-on-idle = true
session.suspend-timeout-seconds = 10
#link.passive = true
device.description = "Dummy shim to prevent hanging"
}
}
{ factory = adapter
args = {
factory.name = support.null-audio-sink
node.name = PipeLine-IN
media.class = Audio/Sink
audio.position = [ FL FR ]
#audio.format = S24_32P
#audio.rate = 192000
resample.quality = 9
volume = 1.0
#node.latency = "4608/192000"
#node.max-latency = "24576/192000"
#node.pause-on-idle = true
#link.passive = true
}
}
# the format, rate and buffer/latency-size for node pipelines are defined by
# capabilities and preferences of nodes in sequence from hardware node to software source node
# meaning that settings for all in-between nodes from IN to OUT will be defined by this OUT node
{ factory = adapter
args = {
factory.name = support.null-audio-sink
node.name = PipeLine-OUT
media.class = Audio/Sink
audio.position = [ FL FR ]
#audio.format = F32
#audio.rate = 192000
resample.quality = 9
volume = 1.0
# give enough time for heavy pipeline to calculate
#node.latency = "384/48000"
#node.max-latency = "768/48000"
#node.latency = "1536/192000"
node.max-latency = "3072/192000"
node.pause-on-idle = true
session.suspend-timeout-seconds = 10
#link.passive = true
device.description = "system"
}
}
]
context.exec = [
#{ path = <program-name> [ args = "<arguments>" ] }
#
# Execute the given program with arguments.
#
# You can optionally start the session manager here,
# but it is better to start it as a systemd service.
# Run the session manager with -h for options.
#
#{ path = "/usr/bin/pipewire-media-session" args = "" }
#
# You can optionally start the pulseaudio-server here as well
# but it is better to start it as a systemd service.
# It can be interesting to start another daemon here that listens
# on another address with the -a option (eg. -a tcp:4713).
#
#{ path = "/usr/bin/pipewire" args = "-c pipewire-pulse.conf" }
]
pipewire-pulse.conf
context.properties = {
## Configure properties in the system.
mem.warn-mlock = true
mem.allow-mlock = true
#mem.mlock-all = true
#log.level = 3
## Properties for the DSP configuration.
clock.power-of-two-quantum = false
default.clock.allowed-rates = [ 192000 48000 384000 768000 ]
default.clock.rate = 48000
default.clock.quantum = 768
default.clock.min-quantum = 96
default.clock.max-quantum = 1536
#default.clock.rate = 192000
#default.clock.quantum = 3072
#default.clock.min-quantum = 384
#default.clock.max-quantum = 6144
}
context.spa-libs = {
audio.convert.* = audioconvert/libspa-audioconvert
support.* = support/libspa-support
}
context.modules = [
{ name = libpipewire-module-rt
args = {
nice.level = -11
rt.prio = 29
rt.time.soft = 900000
rt.time.hard = 1900000
}
flags = [ ifexists nofail ]
}
{ name = libpipewire-module-protocol-native }
{ name = libpipewire-module-client-node }
{ name = libpipewire-module-adapter }
{ name = libpipewire-module-metadata }
{ name = libpipewire-module-protocol-pulse
args = {
# the addresses this server listens on
server.address = [
"unix:native"
#"unix:/tmp/something" # absolute paths may be used
#"tcp:4713" # IPv4 and IPv6 on all addresses
#"tcp:[::]:9999" # IPv6 on all addresses
#"tcp:127.0.0.1:8888" # IPv4 on a single address
#
#{ address = "tcp:4713" # address
# max-clients = 1024 # maximume number of clients
# listen-backlog = 256 # backlog in the server listen queue
# client.access = "restricted" # permissions for clients
#}
]
pulse.min.req = 96/48000
pulse.default.req = 384/48000
pulse.min.frag = 384/48000
pulse.default.frag = 768/48000
pulse.default.tlength = 1536/48000
pulse.min.quantum = 96/48000
# it's F32 stereo by default
#pulse.default.format = S24_32P
#pulse.default.position = [ FL FR ]
}
}
]
stream.properties = {
#node.latency = 3072/192000
#node.max-latency = 24576/192000
#node.autoconnect = true
#audio.rate = 192000
#audio.format = F32
resample.quality = 9
#channelmix.normalize = true
#channelmix.mix-lfe = true
#channelmix.upmix = false
#channelmix.lfe-cutoff = 115
}
wireplumber.conf
# WirePlumber daemon context configuration #
context.properties = {
## Properties to configure the PipeWire context and some modules
#application.name = WirePlumber
#log.level = 3
wireplumber.script-engine = lua-scripting
#wireplumber.export-core = true
mem.warn-mlock = true
mem.allow-mlock = true
#mem.mlock-all = true
support.dbus = true
## Properties for the DSP configuration.
clock.power-of-two-quantum = false
default.clock.allowed-rates = [ 192000 48000 384000 768000 44100 32000 16000 8000 ]
default.clock.rate = 48000
default.clock.quantum = 768
default.clock.min-quantum = 96
default.clock.max-quantum = 1536
#default.clock.rate = 192000
#default.clock.quantum = 3072
#default.clock.min-quantum = 384
#default.clock.max-quantum = 6144
default.video.width = 1920
default.video.height = 1080
default.video.rate.num = 60
default.video.rate.denom = 1
}
context.spa-libs = {
#<factory-name regex> = <library-name>
#
# Used to find spa factory names. It maps an spa factory name
# regular expression to a library name that should contain
# that factory.
#
api.alsa.* = alsa/libspa-alsa
api.bluez5.* = bluez5/libspa-bluez5
api.jack.* = jack/libspa-jack
api.v4l2.* = v4l2/libspa-v4l2
api.libcamera.* = libcamera/libspa-libcamera
api.vulkan.* = vulkan/libspa-vulkan
audio.convert.* = audioconvert/libspa-audioconvert
support.* = support/libspa-support
}
context.modules = [
#{ name = <module-name>
# [ args = { <key> = <value> ... } ]
# [ flags = [ [ ifexists ] [ nofail ] ]
#}
#
# PipeWire modules to load.
# If ifexists is given, the module is ignored when it is not found.
# If nofail is given, module initialization failures are ignored.
#
# Uses RTKit/RT to boost the data thread priority.
{ name = libpipewire-module-rt
args = {
nice.level = -13
rt.prio = 39
rt.time.soft = 900000
rt.time.hard = 1900000
}
flags = [ ifexists nofail ]
}
# The native communication protocol.
{ name = libpipewire-module-protocol-native }
# Allows creating nodes that run in the context of the
# client. Is used by all clients that want to provide
# data to PipeWire.
{ name = libpipewire-module-client-node }
# Allows creating devices that run in the context of the
# client. Is used by the session manager.
{ name = libpipewire-module-client-device }
# Makes a factory for wrapping nodes in an adapter with a
# converter and resampler.
{ name = libpipewire-module-adapter }
# Allows applications to create metadata objects. It creates
# a factory for Metadata objects.
{ name = libpipewire-module-metadata }
# Provides factories to make session manager objects.
{ name = libpipewire-module-session-manager }
]
wireplumber.components = [
#{ name = <component-name>, type = <component-type> }
#
# WirePlumber components to load
#
# The lua scripting engine
{ name = libwireplumber-module-lua-scripting, type = module }
# The lua configuration file(s)
# Other components are loaded from there
{ name = main.lua, type = config/lua }
{ name = policy.lua, type = config/lua }
{ name = bluetooth.lua, type = config/lua }
]
50-alsa-config.lua
alsa_monitor.properties = {
-- Create a JACK device. This is not enabled by default because
-- it requires that the PipeWire JACK replacement libraries are
-- not used by the session manager, in order to be able to
-- connect to the real JACK server.
--["alsa.jack-device"] = false,
-- Reserve devices via org.freedesktop.ReserveDevice1 on D-Bus
["alsa.reserve"] = true,
--["alsa.reserve.priority"] = -20,
--["alsa.reserve.application-name"] = "WirePlumber",
-- Enables monitoring of alsa MIDI devices
["alsa.midi.monitoring"] = true,
["alsa.seq.name"] = "[MIDI-BRIDGE]",
}
alsa_monitor.rules = {
-- An array of matches/actions to evaluate.
{
-- Rules for matching a device or node. It is an array of
-- properties that all need to match the regexp. If any of the
-- matches work, the actions are executed for the object.
matches = {
{
-- This matches all cards.
{ "device.name", "matches", "alsa_card.*" },
},
},
-- Apply properties on the matched object.
apply_properties = {
-- Use ALSA-Card-Profile devices. They use UCM or the profile
-- configuration to configure the device and mixer settings.
["api.alsa.use-acp"] = true,
-- Use UCM instead of profile when available. Can be
-- disabled to skip trying to use the UCM profile.
["api.alsa.use-ucm"] = true,
-- Don't use the hardware mixer for volume control. It
-- will only use software volume. The mixer is still used
-- to mute unused paths based on the selected port.
--["api.alsa.soft-mixer"] = false,
-- Ignore decibel settings of the driver. Can be used to
-- work around buggy drivers that report wrong values.
["api.alsa.ignore-dB"] = false,
-- The profile set to use for the device. Usually this is
-- "default.conf" but can be changed with a udev rule or here.
--["device.profile-set"] = "profileset-name",
-- The default active profile. Is by default set to "Off".
--["device.profile"] = "default profile name",
-- Automatically select the best profile. This is the
-- highest priority available profile. This is disabled
-- here and instead implemented in the session manager
-- where it can save and load previous preferences.
["api.acp.auto-profile"] = false,
-- Automatically switch to the highest priority available port.
-- This is disabled here and implemented in the session manager instead.
["api.acp.auto-port"] = false,
-- Other properties can be set here.
--["device.nick"] = "My Device",
},
},
{
matches = {
{
-- Matches all sources.
{ "node.name", "matches", "alsa_input.*" },
},
{
-- Matches all sinks.
{ "node.name", "matches", "alsa_output.*" },
},
},
apply_properties = {
--["node.nick"] = "My Node",
--["priority.driver"] = 100,
--["priority.session"] = 100,
["node.pause-on-idle"] = true,
["session.suspend-timeout-seconds"] = 61, -- 0 disables suspend
-- default resample.quality is 6, 9 is good, goes up to 15
["resample.quality"] = 9,
["channelmix.normalize"] = true,
["channelmix.mix-lfe"] = true,
["channelmix.upmix"] = false,
["#channelmix.lfe-cutoff"] = 115,
--["audio.channels"] = 2,
--["audio.format"] = "S32LE",
--["audio.rate"] = 192000,
--["audio.allowed-rates"] = "32000,44100,48000,192000,384000,768000"
--["audio.position"] = "FL,FR",
--["node.latency"] = "3072/192000",
-- some USB devices are limited to 8192 buffer regardless of frequency
["node.max-latency"] = "6144/192000",
-- max USB packet is 288/392 at 192/384khz and period size is halved in "batch-mode"
--["api.alsa.period-num"] = 3,
["api.alsa.period-size"] = 256,
["api.alsa.headroom"] = 384,
--["api.alsa.start-delay"] = 0,
--["api.alsa.disable-mmap"] = true,
--["api.alsa.disable-batch"] = true,
--["api.alsa.use-chmap"] = true,
--["iec958.codecs"] = [ PCM DTS AC3 MPEG MPEG2-AAC EAC3 TrueHD DTS-HD ],
},
},
}