.TH "libpipewire-module-protocol-pulse" 7 "1.6.8" "PipeWire" \" -*- nroff -*- .ad l .nh .SH NAME libpipewire-module-protocol-pulse \- Protocol Pulse .SH DESCRIPTION .PP This module implements a complete PulseAudio server on top of PipeWire\&. .PP This is only the server implementation, client are expected to use the original PulseAudio client library\&. This provides a high level of compatibility with existing applications; in fact, all usual PulseAudio tools such as pavucontrol, pactl, pamon, paplay should continue to work as they did before\&. .PP This module is usually loaded as part of a standalone pipewire process, called pipewire-pulse, with the pipewire-pulse\&.conf config file\&. .PP The pulse server implements a sample cache that is otherwise not available in PipeWire\&. .PP .SH "MODULE NAME" .PP .PP \fRlibpipewire-module-protocol-pulse\fP .PP .SH "MODULE OPTIONS" .PP .PP The module arguments can be the contents of the pulse\&.properties but it is recommended to make a separate pulse\&.properties section in the config file so that overrides can be done\&. .PP .SH "PULSE\&.PROPERTIES" .PP .PP A config section with server properties can be given\&. .PP .PP .nf # ~/\&.config/pipewire/pipewire\-pulse\&.conf\&.d/custom\&.conf pulse\&.properties = { # 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 = 64 # maximum number of clients # listen\-backlog = 32 # backlog in the server listen queue # client\&.access = "restricted" # permissions for clients #} ] #server\&.dbus\-name = "org\&.pulseaudio\&.Server" #pulse\&.allow\-module\-loading = true #pulse\&.min\&.req = 256/48000 # 5\&.3ms #pulse\&.default\&.req = 960/48000 # 20 milliseconds #pulse\&.min\&.frag = 256/48000 # 5\&.3ms #pulse\&.default\&.frag = 96000/48000 # 2 seconds #pulse\&.default\&.tlength = 96000/48000 # 2 seconds #pulse\&.min\&.quantum = 256/48000 # 5\&.3ms #pulse\&.default\&.format = F32 #pulse\&.default\&.position = [ FL FR ] #pulse\&.idle\&.timeout = 0 } pulse\&.properties\&.rules = [ { matches = [ { cpu\&.vm\&.name = !null } ] actions = { update\-props = { # These overrides are only applied when running in a vm\&. pulse\&.min\&.quantum = 1024/48000 # 22ms } } } ] .fi .PP .PP .SS "Connection options" .PP .PP .nf \&.\&.\&. server\&.address = [ "unix:native" # "tcp:4713" ] \&.\&.\&. .fi .PP .PP The addresses the server listens on when starting\&. Uncomment the \fRtcp:4713\fP entry to also make the server listen on a tcp socket\&. This is equivalent to loading \fRlibpipewire-module-native-protocol-tcp\fP\&. .PP There is also a slightly more verbose syntax with more options: .PP .PP .nf \&.\&.\&.\&. server\&.address = [ { address = "tcp:4713" # address max\-clients = 64 # maximum number of clients listen\-backlog = 32 # backlog in the server listen queue client\&.access = "restricted" # permissions for clients } \&.\&.\&.\&. .fi .PP .PP Use \fRclient\&.access\fP to use one of the access methods to restrict the permissions given to clients connected via this address\&. .PP By default network access is given the "restricted" permissions\&. The session manager is responsible for assigning permission to clients with restricted permissions (usually read-only permissions)\&. .PP .PP .nf server\&.dbus\-name = "org\&.pulseaudio\&.Server" .fi .PP .PP The DBus name to reserve for the server\&. If you have multiple servers, you might want to change the name\&. .PP .PP .nf pulse\&.allow\-module\-loading = true .fi .PP .PP By default, clients are allowed to load and unload modules\&. You can disable this feature with this option\&. .PP .SS "Playback buffering options" .PP .PP .nf pulse\&.min\&.req = 256/48000 # 5\&.3ms .fi .PP .PP The minimum amount of data to request for clients\&. The client requested values will be clamped to this value\&. Lowering this value together with tlength can decrease latency if the client wants this, but increase CPU overhead\&. .PP .PP .nf pulse\&.default\&.req = 960/48000 # 20 milliseconds .fi .PP .PP The default amount of data to request for clients\&. If the client does not specify any particular value, this default will be used\&. Lowering this value together with tlength can decrease latency but increase CPU overhead\&. .PP .PP .nf pulse\&.default\&.tlength = 96000/48000 # 2 seconds .fi .PP .PP The target amount of data to buffer on the server side\&. If the client did not specify a value, this default will be used\&. Lower values can decrease the latency\&. .PP .SS "Record buffering options" .PP .PP .nf pulse\&.min\&.frag = 256/48000 # 5\&.3ms .fi .PP .PP The minimum allowed size of the capture buffer before it is sent to a client\&. The requested value of the client will be clamped to this\&. Lowering this value can reduce latency at the expense of more CPU usage\&. .PP .PP .nf pulse\&.default\&.frag = 96000/48000 # 2 seconds .fi .PP .PP The default size of the capture buffer before it is sent to a client\&. If the client did not specify any value, this default will be used\&. Lowering this value can reduce latency at the expense of more CPU usage\&. .PP .SS "Scheduling options" .PP .PP .nf pulse\&.min\&.quantum = 256/48000 # 5\&.3ms .fi .PP .PP The minimum quantum (buffer size in samples) to use for pulseaudio clients\&. This value is calculated based on the frag and req/tlength for record and playback streams respectively and then clamped to this value to ensure no pulseaudio client asks for too small quantums\&. Lowering this value might decrease latency at the expense of more CPU usage\&. .PP .SS "Format options" .PP .PP .nf pulse\&.default\&.format = F32 .fi .PP .PP Some modules will default to this format when no other format was given\&. This is equivalent to the PulseAudio \fRdefault-sample-format\fP option in \fR/etc/pulse/daemon\&.conf\fP\&. .PP .PP .nf pulse\&.default\&.position = [ FL FR ] .fi .PP .PP Some modules will default to this channelmap (with its number of channels)\&. This is equivalent to the PulseAudio \fRdefault-sample-channels\fP and \fRdefault-channel-map\fP options in \fR/etc/pulse/daemon\&.conf\fP\&. .PP .SS "Quirk options" .PP .PP .nf pulse\&.fix\&.format = "S16LE" .fi .PP .PP When a stream uses the FIX_FORMAT flag, fixate the format to this value\&. Normally the format would be fixed to the sink/source that the stream connects to\&. When an invalid format (null or "") is set, the FIX_FORMAT flag is ignored\&. .PP .PP .nf pulse\&.fix\&.rate = 48000 .fi .PP .PP When a stream uses the FIX_RATE flag, fixate the sample rate to this value\&. Normally the rate would be fixed to the sink/source that the stream connects to\&. When a 0 rate is set, the FIX_RATE flag is ignored\&. .PP .PP .nf pulse\&.fix\&.position = "[ FL FR ]" .fi .PP .PP When a stream uses the FIX_CHANNELS flag, fixate the channels to this value\&. Normally the channels would be fixed to the sink/source that the stream connects to\&. When an invalid position (null or "") is set, the FIX_CHANNELS flag is ignored\&. .PP .PP .nf pulse\&.idle\&.timeout = 0 .fi .PP .PP Some clients are not sending data when they should and cause underruns\&. When setting this option such clients will be set to paused if they underrun for the given amount of seconds\&. This makes sure that sinks can suspend and save battery power\&. When the client resumes, it will unpause again\&. A value of 0 disables this feature\&. .PP .SH "COMMAND EXECUTION" .PP .PP As part of the server startup sequence, a set of commands can be executed\&. Currently, this can be used to load additional modules into the server\&. .PP .PP .nf # Extra commands can be executed here\&. # load\-module : loads a module with args and flags # args = " " # ( flags = [ "no\-fail" ] ) # ( condition = [ { = , \&.\&.\&. } \&.\&.\&. ] ) # conditions will check the pulse\&.properties key/values\&. pulse\&.cmd = [ { cmd = "load\-module" args = "module\-always\-sink" flags = [ ] } #{ cmd = "load\-module" args = "module\-switch\-on\-connect" condition = [ { pulse\&.cmd\&.switch\-on\-connect = true } ] #{ cmd = "load\-module" args = "module\-gsettings" flags = [ "nofail" ] } ] .fi .PP .PP .SH "DYNAMIC PROPERTIES" .PP .PP The pulse\&.properties can be dynamically updated with rules\&. It supports an \fRupdate-props\fP action\&. The matches will be performed on the values in context\&.properties\&. .PP .PP .nf pulse\&.properties\&.rules = [ { matches = [ { cpu\&.vm\&.name = !null } ] actions = { update\-props = { # These overrides are only applied when running in a vm\&. pulse\&.min\&.quantum = 1024/48000 # 22ms } } } ] .fi .PP .PP In the above example, when running in a VM, the rule will override the properties in pulse\&.properties with the given values\&. This might be interesting because VMs usually can't support the low latency settings that are possible on real hardware\&. .PP .SH "STREAM SETTINGS AND RULES" .PP .PP Streams created by module-protocol-pulse will use the stream\&.properties section and stream\&.rules sections as usual\&. .PP .SH "APPLICATION SETTINGS (RULES)" .PP .PP The pulse protocol module supports generic config rules\&. It supports a pulse\&.rules section with a \fRquirks\fP and an \fRupdate-props\fP action\&. These rules operate on the client properties (not the stream properties, see above)\&. .PP .PP .nf # ~/\&.config/pipewire/pipewire\-pulse\&.conf\&.d/custom\&.conf pulse\&.rules = [ { # skype does not want to use devices that don't have an S16 sample format\&. matches = [ { application\&.process\&.binary = "teams" } { application\&.process\&.binary = "teams\-insiders" } { application\&.process\&.binary = "skypeforlinux" } ] actions = { quirks = [ force\-s16\-info ] } } { # speech dispatcher asks for too small latency and then underruns\&. matches = [ { application\&.name = "~speech\-dispatcher*" } ] actions = { update\-props = { pulse\&.min\&.req = 1024/48000 # 21ms pulse\&.min\&.quantum = 1024/48000 # 21ms pulse\&.idle\&.timeout = 5 # pause after 5 seconds of underrun } } } ] .fi .PP .PP .SS "Quirks" .PP The quirks action takes an array of quirks to apply for the client\&. .PP .IP "\(bu" 2 \fRforce-s16-info\fP makes the sink and source introspect code pretend that the sample format is S16 (16 bits) samples\&. Some application refuse the sink/source if this is not the case\&. .IP "\(bu" 2 \fRremove-capture-dont-move\fP Removes the DONT_MOVE flag on capture streams\&. Some applications set this flag so that the stream can't be moved anymore with tools such as pavucontrol\&. .IP "\(bu" 2 \fRblock-source-volume\fP blocks the client from updating any source volumes\&. This can be used to disable things like automatic gain control\&. .IP "\(bu" 2 \fRblock-sink-volume\fP blocks the client from updating any sink volumes\&. .IP "\(bu" 2 \fRblock-record-stream\fP blocks the client from creating any record stream\&. .IP "\(bu" 2 \fRblock-playback-stream\fP blocks the client from creating any playback stream\&. .PP .PP .SS "update-props" .PP Takes an object with the properties to update on the client\&. Common actions are to tweak the quantum values\&. You can use the stream specific keys in pulse\&.properties\&. .PP .SS "startup notification" .PP A newline will be written into the notification file descriptor when the server has started if the following environment variable is set: .PP .IP "\(bu" 2 PIPEWIRE_PULSE_NOTIFICATION_FD .PP .PP .SH "EXAMPLE CONFIGURATION" .PP .PP .PP .nf # ~/\&.config/pipewire/pipewire\-pulse\&.conf\&.d/custom\&.conf context\&.modules = [ { name = libpipewire\-module\-protocol\-pulse args = { } } ] pulse\&.properties = { server\&.address = [ "unix:native" ] } pulse\&.rules = [ { # skype does not want to use devices that don't have an S16 sample format\&. matches = [ { application\&.process\&.binary = "teams" } { application\&.process\&.binary = "teams\-insiders" } { application\&.process\&.binary = "skypeforlinux" } ] actions = { quirks = [ force\-s16\-info ] } } { # speech dispatcher asks for too small latency and then underruns\&. matches = [ { application\&.name = "~speech\-dispatcher*" } ] actions = { update\-props = { pulse\&.min\&.req = 1024/48000 # 21ms pulse\&.min\&.quantum = 1024/48000 # 21ms pulse\&.idle\&.timeout = 5 # pause after 5 seconds of underrun } } } ] .fi .PP