docs: split up and enrich configuration docs

* Add information about multiple instances
* Document better how the lua config files work
* Document how lua config files get merged from different places
* Copy over additional documentation for ALSA from pw-media-session
* Fix rst syntax issues
This commit is contained in:
George Kiagiadakis 2022-01-04 18:32:49 +02:00
parent 4896ad0680
commit 1da5d11317
14 changed files with 1279 additions and 636 deletions

View file

@ -0,0 +1,34 @@
.. _configuration:
Configuration
=============
WirePlumber is a heavily modular daemon. By itself, it doesn't do anything
except load the configured modules. All the rest of the logic is implemented
inside those modules.
Modular design ensures that it is possible to swap the implementation of
specific functionality without having to re-implement the rest of it, allowing
flexibility on target-sensitive parts, such as policy management and
making use of non-standard hardware.
At startup, WirePlumber first reads its **main** configuration file.
This file configures the operation context (properties of the daemon,
modules to be loaded, etc). This file may also specify additional, secondary
configuration files which will be loaded as well at the time of parsing the
main file.
All files and modules are specified relative to their standard search locations,
which are documented later in this chapter.
.. toctree::
:maxdepth: 1
configuration/locations.rst
configuration/main.rst
configuration/config_lua.rst
configuration/multi_instance.rst
configuration/alsa.rst
configuration/bluetooth.rst
configuration/policy.rst
configuration/access.rst

View file

@ -0,0 +1,63 @@
.. _config_access:
Access configuration
====================
main.lua.d/50-default-access-config.lua
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Using a similar format as the :ref:`ALSA monitor <config_alsa>`, this
configuration file is charged to configure the client objects created by
PipeWire.
* *default_access.properties*
A Lua object that contains generic client configuration properties in the
for of key pairs.
Example:
.. code-block:: lua
default_access.properties = {
["enable-flatpak-portal"] = true,
}
The above example sets to ``true`` the ``enable-flatpak-portal`` property.
The list of valid properties are:
.. code-block:: lua
["enable-flatpak-portal"] = true,
Whether to enable the flatpak portal or not.
* *default_access.rules*
This is a Lua array that can contain objects with rules for a client object.
Those Lua objects have 2 properties. Similar to the
:ref:`ALSA configuration <config_alsa>`, the first property is ``matches``,
which allow users to define rules to match a client object.
The second property is ``default_permissions``, and it is used to set
permissions on the matched client object.
Example:
.. code-block:: lua
{
matches = {
{
{ "pipewire.access", "=", "flatpak" },
},
},
default_permissions = "rx",
}
This grants read and execute permissions to all clients that have the
``pipewire.access`` property set to ``flatpak``.
Possible permissions are any combination of ``r``, ``w`` and ``x`` for read,
write and execute; or ``all`` for all kind of permissions.

View file

@ -0,0 +1,456 @@
.. _config_alsa:
ALSA configuration
==================
Modifying the default configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ALSA devices are created and managed by the session manager with the *alsa.lua*
monitor script. In the default configuration, this script is loaded by
``main.lua.d/30-alsa-monitor.lua``, which also specifies an ``alsa_monitor``
global table that can be filled in with properties and rules in subsequent
config files. By default, these are filled in ``main.lua.d/50-alsa-config.lua``.
The ``alsa_monitor`` global table has 2 sub-tables:
* *alsa_monitor.properties*
This is a simple Lua table that has key value pairs used as properties.
Example:
.. code-block:: lua
alsa_monitor.properties = {
["alsa.jack-device"] = false,
["alsa.reserve"] = true,
}
The above example will configure the ALSA monitor to not enable the JACK
device, and do ALSA device reservation using the mentioned DBus interface.
A list of valid properties are:
.. code-block:: lua
["alsa.jack-device"] = false
Creates a JACK device if set to ``true``. 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.
.. code-block:: lua
["alsa.reserve"] = true
Reserve ALSA devices via *org.freedesktop.ReserveDevice1* on D-Bus.
.. code-block:: lua
["alsa.reserve.priority"] = -20
The used ALSA device reservation priority.
.. code-block:: lua
["alsa.reserve.application-name"] = "WirePlumber"
The used ALSA device reservation application name.
* *alsa_monitor.rules*
This is a Lua array that can contain objects with rules for a device or node.
Those objects have 2 properties. The first one is ``matches``, which allow
users to define rules to match a device or node. The second property is
``apply_properties``, and it is used to apply properties on the matched object.
Example:
.. code-block:: lua
alsa_monitor.rules = {
matches = {
{
{ "device.name", "matches", "alsa_card.*" },
},
},
apply_properties = {
["api.alsa.use-acp"] = true,
}
}
This sets the API ALSA use ACP property to all devices with a name that
matches the ``alsa_card.*`` pattern.
The ``matches`` section is an array of arrays. On the first level, the rules
are ORed together, so any rule match is going to apply the properties. On
the second level, the rules are merged with AND, so they must all match.
Example:
.. code-block:: lua
matches = {
{
{ "node.name", "matches", "alsa_input.*" },
{ "alsa.driver_name", "equals", "snd_hda_intel" },
},
{
{ "node.name", "matches", "alsa_output.*" },
},
},
This is equivalent to the following logic, in pseudocode:
.. code-block::
if ("node.name" MATCHES "alsa_input.*" AND "alsa.driver_name" EQUALS "snd_hda_intel" )
OR
("node.name" MATCHES "alsa_output.*")
then
... apply the properties ...
end
As you can notice, the individual rules are themselves also lua arrays. The
first element is a property name (ex "node.name"), the second element is a
verb and the third element is an expected value, which depends on the verb.
Internally, this uses the ``Constraint`` API, which is documented in the
:ref:`Object Interet API <lua_object_interest_api>` section. All the verbs
that you can use on ``Constraint`` are also allowed here.
.. note::
When using the "matches" verb, the values are not complete regular expressions.
They are wildcard patterns, which means that '*' matches an arbitrary,
possibly empty, string and '?' matches an arbitrary character.
All the possible properties that you can apply to devices and nodes of the
ALSA monitor are described in the sections below.
Device properties
^^^^^^^^^^^^^^^^^
PipeWire devices correspond to the ALSA cards.
The following properties can be configured on devices created by the monitor:
.. code-block:: lua
["api.alsa.use-acp"] = true
Use the ACP (alsa card profile) code to manage the device. This will probe the
device and configure the available profiles, ports and mixer settings. The
code to do this is taken directly from PulseAudio and provides devices that
look and feel exactly like the PulseAudio devices.
.. code-block:: lua
["api.alsa.use-ucm"] = true
By default, the UCM configuration is used when it is available for your device.
With this option you can disable this and use the ACP profiles instead.
.. code-block:: lua
["api.alsa.soft-mixer"] = false
Setting this option to true will disable the hardware mixer for volume control
and mute. All volume handling will then use software volume and mute, leaving
the hardware mixer untouched. The hardware mixer will still be used to mute
unused audio paths in the device.
.. code-block:: lua
["api.alsa.ignore-dB"] = false
Setting this option to true will ignore the decibel setting configured by the
driver. Use this when the driver reports wrong settings.
.. code-block:: lua
["device.profile-set"] = "profileset-name"
This option can be used to select a custom profile set name for the device.
Usually this is configured in Udev rules but it can also be specified here.
.. code-block:: lua
["device.profile"] = "default profile name"
The default active profile name.
.. code-block:: lua
["api.acp.auto-profile"] = false
Automatically select the best profile for the device. Normally this option is
disabled because the session manager will manage the profile of the device.
The session manager can save and load previously selected profiles. Enable
this if your session manager does not handle this feature.
.. code-block:: lua
["api.acp.auto-port"] = false
Automatically select the highest priority port that is available. This is by
default disabled because the session manager handles the task of selecting and
restoring ports. It can, for example, restore previously saved volumes. Enable
this here when the session manager does not handle port restore.
Some of the other properties that might be configured on devices:
.. code-block:: lua
["device.nick"] = "My Device",
["device.description"] = "My Device"
``device.description`` will show up in most apps when a device name is shown.
Node Properties
^^^^^^^^^^^^^^^
Nodes are sinks or sources in the PipeWire graph. They correspond to the ALSA
devices. In addition to the generic stream node configuration options, there are
some alsa specific options as well:
.. code-block:: lua
["priority.driver"] = 2000
This configures the node driver priority. Nodes with higher priority will be
used as a driver in the graph. Other nodes with lower priority will have to
resample to the driver node when they are joined in the same graph. The default
value is set based on some heuristics.
.. code-block:: lua
["priority.session"] = 100
This configures the priority of the device when selecting a default device.
Higher priority devices will be more likely candidates as a default device.
.. code-block:: lua
["node.pause-on-idle"] = false
Pause-on-idle will stop the node when nothing is linked to it anymore.
This is by default false because some devices cause a pop when they are
opened/closed. The node will, normally, pause and suspend after a timeout
(see suspend-node.lua).
.. code-block:: lua
["session.suspend-timeout-seconds"] = 5 -- 0 disables suspend
This option configures a different suspend timeout on the node.
By default this is 5 seconds. For some devices (HiFi amplifiers, for example)
it might make sense to set a higher timeout because they might require some
time to restart after being idle.
A value of 0 disables suspend for a node and will leave the ALSA device busy.
The device can then manually be suspended with ``pactl suspend-sink|source``.
**The following properties can be used to configure the format used by the
ALSA device:**
.. code-block:: lua
["audio.format"] = "S16LE"
By default, PipeWire will use a 32 bits sample format but a different format
can be set here.
The Audio rate of a device can be set here:
.. code-block:: lua
["audio.rate"] = 44100
By default, the ALSA device will be configured with the same samplerate as the
global graph. If this is not supported, or a custom values is set here,
resampling will be used to match the graph rate.
.. code-block:: lua
["audio.channels"] = 2
["audio.position"] = "FL,FR"
By default the channels and their position are determined by the selected
Device profile. You can override this setting here and optionally swap or
reconfigure the channel positions.
.. code-block:: lua
["api.alsa.use-chmap"] = false
Use the channel map as reported by the driver. This is disabled by default
because it is often wrong and the ACP code handles this better.
.. code-block:: lua
["api.alsa.disable-mmap"] = true
PipeWire will by default access the memory of the device using mmap.
This can be disabled and force the usage of the slower read and write access
modes in case the mmap support of the device is not working properly.
.. code-block:: lua
["channelmix.normalize"] = true
Makes sure that during such mixing & resampling original 0 dB level is
preserved, so nothing sounds wildly quieter/louder.
.. code-block:: lua
["channelmix.mix-lfe"] = true
Creates "center" channel for X.0 recordings from front stereo on X.1 setups and
pushes some low-frequency/bass from "center" from X.1 recordings into front
stereo on X.0 setups.
.. code-block:: lua
["monitor.channel-volumes"] = false
By default, the volume of the sink/source does not influence the volume on the
monitor ports. Set this option to true to change this. PulseAudio has
inconsistent behaviour regarding this option, it applies channel-volumes only
when the sink/source is using software volumes.
ALSA buffer properties
^^^^^^^^^^^^^^^^^^^^^^
PipeWire uses a timer to consume and produce samples to/from ALSA devices.
After every timeout, it queries the device hardware pointers of the device and
uses this information to set a new timeout. See also this example program.
By default, PipeWire handles ALSA batch devices differently from non-batch
devices. Batch devices only get their hardware pointers updated after each
hardware interrupt. Non-batch devices get updates independent of the interrupt.
This means that for batch devices we need to set the interrupt at a sufficiently
high frequency (at the cost of CPU usage) while for non-batch devices we want to
set the interrupt frequency as low as possible (to save CPU).
For batch devices we also need to take the extra buffering into account caused
by the delayed updates of the hardware pointers.
Most USB devices are batch devices and will be handled as such by PipeWire by
default.
There are 2 tunable parameters to control the buffering and timeouts in a
device
.. code-block:: lua
["api.alsa.period-size"] = 1024
This sets the device interrupt to every period-size samples for non-batch
devices and to half of this for batch devices. For batch devices, the other
half of the period-size is used as extra buffering to compensate for the delayed
update. So, for batch devices, there is an additional period-size/2 delay.
It makes sense to lower the period-size for batch devices to reduce this delay.
.. code-block:: lua
["api.alsa.headroom"] = 0
This adds extra delay between the hardware pointers and software pointers.
In most cases this can be set to 0. For very bad devices or emulated devices
(like in a VM) it might be necessary to increase the headroom value.
In summary, this is the overview of buffering and timings:
============== ========================================== =========
Property Batch Non-Batch
============== ========================================== =========
IRQ Frequency api.alsa.period-size/2 api.alsa.period-size
Extra Delay api.alsa.headroom + api.alsa.period-size/2 api.alsa.headroom
============== ========================================== =========
It is possible to disable the batch device tweaks with:
.. code-block:: lua
["api.alsa.disable-batch"] = true
It removes the extra delay added of period-size/2 if the device can support this.
For batch devices it is also a good idea to lower the period-size
(and increase the IRQ frequency) to get smaller batch updates and lower latency.
ALSA extra latency properties
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Extra internal delay in the DAC and ADC converters of the device itself can be
set with the ``latency.internal.*`` properties:
.. code-block:: lua
["latency.internal.rate"] = 256
["latency.internal.ns"] = 0
You can configure a latency in samples (relative to rate with
``latency.internal.rate``) or in nanoseconds (``latency.internal.ns``).
This value will be added to the total reported latency by the node of the device.
You can use a tool like ``jack_iodelay`` to get the number of samples of
internal latency of your device.
This property is also adjustable at runtime with the ``ProcessLatency`` param.
You will need to find the id of the Node you want to change. For example:
Query the current internal latency of an ALSA node with id 58:
.. code-block:: console
$ pw-cli e 58 ProcessLatency
Object: size 80, type Spa:Pod:Object:Param:ProcessLatency (262156), id Spa:Enum:ParamId:ProcessLatency (16)
Prop: key Spa:Pod:Object:Param:ProcessLatency:quantum (1), flags 00000000
Float 0.000000
Prop: key Spa:Pod:Object:Param:ProcessLatency:rate (2), flags 00000000
Int 0
Prop: key Spa:Pod:Object:Param:ProcessLatency:ns (3), flags 00000000
Long 0
Set the internal latency to 256 samples:
.. code-block:: console
$ pw-cli s 58 ProcessLatency '{ rate = 256 }'
Object: size 32, type Spa:Pod:Object:Param:ProcessLatency (262156), id Spa:Enum:ParamId:ProcessLatency (16)
Prop: key Spa:Pod:Object:Param:ProcessLatency:rate (2), flags 00000000
Int 256
remote 0 node 58 changed
remote 0 port 70 changed
remote 0 port 72 changed
remote 0 port 74 changed
remote 0 port 76 changed
Startup tweaks
^^^^^^^^^^^^^^
Some devices need some time before they can report accurate hardware pointer
positions. In those cases, an extra start delay can be added that is used to
compensate for this startup delay:
.. code-block:: lua
["api.alsa.start-delay"] = 0
It is unsure when this tunable should be used.
IEC958 (S/PDIF) passthrough
^^^^^^^^^^^^^^^^^^^^^^^^^^^
S/PDIF passthrough will only be enabled when the accepted codecs are configured
on the ALSA device.
This can be done in 3 different ways:
1. Use pavucontrol and toggle the codecs in the output advanced section
2. Modify the ``["iec958.codecs"] = "[ PCM DTS AC3 MPEG MPEG2-AAC EAC3 TrueHD DTS-HD ]"``
node property to something.
3. Use ``pw-cli s <node-id> Props '{ iec958Codecs : [ PCM ] }'`` to modify
the codecs at runtime.

View file

@ -0,0 +1,160 @@
.. _config_bluetooth:
Bluetooth configuration
=======================
Using the same format as the :ref:`ALSA monitor <config_alsa>`, the
configuration file ``bluetooth.lua.d/50-bluez-config.lua`` is charged
to configure the Bluetooth devices and nodes created by WirePlumber.
* *bluez_monitor.properties*
A Lua object that contains generic client configuration properties in the
for of key pairs.
Example:
.. code-block:: lua
bluez_monitor.properties = {
["bluez5.enable-msbc"] = true,
}
This example will enable the MSBC codec in connected Bluetooth devices that
support it.
The list of valid properties are:
.. code-block:: lua
["bluez5.enable-sbc-xq"] = true
Enables the SBC-XQ codec in connected Blueooth devices that support it
.. code-block:: lua
["bluez5.enable-msbc"] = true
Enables the MSBC codec in connected Blueooth devices that support it
.. code-block:: lua
["bluez5.enable-hw-volume"] = true
Enables hardware volume controls in Bluetooth devices that support it
.. code-block:: lua
["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]"
Enabled headset roles (default: [ hsp_hs hfp_ag ]), this property only applies
to native backend. Currently some headsets (Sony WH-1000XM3) are not working
with both hsp_ag and hfp_ag enabled, disable either hsp_ag or hfp_ag to work
around it.
Supported headset roles: ``hsp_hs`` (HSP Headset), ``hsp_ag`` (HSP Audio Gateway),
``hfp_hf`` (HFP Hands-Free) and ``hfp_ag`` (HFP Audio Gateway)
.. code-block:: lua
["bluez5.codecs"] = "[ sbc sbc_xq aac ]"
Enables ``sbc``, ``sbc_zq`` and ``aac`` A2DP codecs.
Supported codecs: ``sbc``, ``sbc_xq``, ``aac``, ``ldac``, ``aptx``,
``aptx_hd``, ``aptx_ll``, ``aptx_ll_duplex``, ``faststream``, ``faststream_duplex``.
All codecs are supported by default.
.. code-block:: lua
["bluez5.hfphsp-backend"] = "native"
HFP/HSP backend (default: native). Available values: ``any``, ``none``,
``hsphfpd``, ``ofono`` or ``native``.
.. code-block:: lua
["bluez5.default.rate"] = 48000
The bluetooth default audio rate.
.. code-block:: lua
["bluez5.default.channels"] = 2
The bluetooth default number of channels.
* *bluez_monitor.rules*
Like in the :ref:`ALSA configuration <config_alsa>`, this is a Lua array that
can contain objects with rules for a Bluetooth device or node.
Those objects have 2 properties. The first one is ``matches``, which allows
users to define rules to match a Bluetooth device or node.
The second property is ``apply_properties``, and it is used to apply
properties on the matched Bluetooth device or node.
Example:
.. code-block:: lua
{
matches = {
{
{ "device.name", "matches", "bluez_card.*" },
},
},
apply_properties = {
["bluez5.auto-connect"] = "[ hfp_hf hsp_hs a2dp_sink ]"
}
}
This will set the auto-connect property to ``hfp_hf``, ``hsp_hs`` and ``a2dp_sink``
on bluetooth devices whose name matches the ``bluez_card.*`` pattern.
A list of valid properties are:
.. code-block:: lua
["bluez5.auto-connect"] = "[ hfp_hf hsp_hs a2dp_sink ]"
Auto-connect device profiles on start up or when only partial profiles have
connected. Disabled by default if the property is not specified.
Supported values are: ``hfp_hf``, ``hsp_hs``, ``a2dp_sink``, ``hfp_ag``,
``hsp_ag`` and ``a2dp_source``.
.. code-block:: lua
["bluez5.hw-volume"] = "[ hfp_ag hsp_ag a2dp_source ]"
Hardware volume controls (default: ``hfp_ag``, ``hsp_ag``, and ``a2dp_source``)
Supported values are: ``hfp_hf``, ``hsp_hs``, ``a2dp_sink``, ``hfp_ag``,
``hsp_ag`` and ``a2dp_source``.
.. code-block:: lua
["bluez5.a2dp.ldac.quality"] = "auto"
LDAC encoding quality.
Available values: ``auto`` (Adaptive Bitrate, default),
``hq`` (High Quality, 990/909kbps), ``sq`` (Standard Quality, 660/606kbps) and
``mq`` (Mobile use Quality, 330/303kbps).
.. code-block:: lua
["bluez5.a2dp.aac.bitratemode"] = 0
AAC variable bitrate mode.
Available values: 0 (cbr, default), 1-5 (quality level).
.. code-block:: lua
["device.profile"] = "a2dp-sink"
Profile connected first.
Available values: ``a2dp-sink`` (default) or ``headset-head-unit``.

View file

@ -0,0 +1,170 @@
.. _config_lua:
Lua configuration files
=======================
Lua configuration files are similar to the main configuration file, but they
leverage the lua language to enable advanced configuration of module arguments
and allow split-file configuration.
There is only one global section that WirePlumber reads from these files: the
**components** table. This table is equivalent to the **context.components**
object on the main configuration file. Its purpose is to list components that
WirePlumber should load on startup.
Every line on the **components** table should be another table that contains
information about the loaded component::
{
"component-name",
type = "component-type",
args = { additional arguments },
optional = true/false,
}
* **"component-name"** should be the name of the component to load
(ex. *"libwireplumber-module-mixer-api"*)
* **"component-type"** should be the type of the component.
Valid component types include:
* ``module``: A WirePlumber shared object module
* ``script/lua``: A WirePlumber Lua script
* ``pw_module``: A PipeWire shared object module (loaded on WirePlumber,
not on the PipeWire daemon)
* **args** is an optional table that can contain additional arguments to be
passed down to the module or script. Scripts can retrieve these arguments
by declaring a line that reads ``local config = ...`` at the top of the script.
Modules receive these arguments as a GVariant ``a{sv}`` table.
* **optional** is a boolean value that specifies whether loading of this
component is optional. The default value is ``false``. If set to ``true``,
then WirePlumber will not fail loading if the component is not found.
Split-file configuration
------------------------
When a Lua configuration file is loaded, the engine also looks for additional
files in a directory that has the same name as the configuration file and a
``.d`` suffix.
A Lua directory can contain a list of Lua configuration files. Those files are
loaded alphabetically by filename so that user can control the order in which
Lua configuration files are executed.
Lua files in the directory are always loaded *after* the configuration file
that is out of the directory. However, it is perfectly valid to not have any
configuration file out of the directory.
Example hierarchy with files both in and out of the directory
(in the order of loading)::
config.lua
config.lua.d/00-functions.lua
config.lua.d/01-alsa.lua
config.lua.d/10-policy.lua
config.lua.d/99-misc.lua
Example hierarchy with files only in the directory
(in the order of loading)::
config.lua.d/00-functions.lua
config.lua.d/01-alsa.lua
config.lua.d/10-policy.lua
config.lua.d/99-misc.lua
Multi-path merging
------------------
WirePlumber looks for configuration files in 3 different places, as described
in the :ref:`Locations of files <config_locations>` section. When a split-file
configuration scheme is used, files will be merged from these different locations.
For example, consider these files exist on the filesystem::
/usr/share/wireplumber/config.lua.d/00-functions.lua
/usr/share/wireplumber/config.lua.d/01-alsa.lua
/usr/share/wireplumber/config.lua.d/10-policy.lua
/usr/share/wireplumber/config.lua.d/99-misc.lua
...
/etc/wireplumber/config.lua.d/01-alsa.lua
...
/home/user/.config/wireplumber/config.lua.d/11-policy-extras.lua
In this case, loading ``config.lua`` will result in loading these files
(in this order)::
/usr/share/wireplumber/config.lua.d/00-functions.lua
/etc/wireplumber/config.lua.d/01-alsa.lua
/usr/share/wireplumber/config.lua.d/10-policy.lua
/home/user/.config/wireplumber/config.lua.d/11-policy-extras.lua
/usr/share/wireplumber/config.lua.d/99-misc.lua
This is useful to keep the default configuration in /usr and override it
with host-specific and user-specific parts in /etc and /home respectively.
As an exception to this rule, if the configuration path is overridden with
the ``WIREPLUMBER_CONFIG_DIR`` environment variable, then configuration files
will only be loaded from this path and no merging will happen.
Functions
---------
Because of the nature of these files (they are scripts!), it is more convenient
to manage the **components** table through functions. In the default
configuration files shipped with WirePlumber, there is a file called
``00-functions.lua`` that defines some helper functions to load components.
When loading components through these functions, *duplicate calls are ignored*,
so it is possible to call a function to load a specific component multiple times
and it will only be loaded once.
.. function:: load_module(module, args)
Loads a WirePlumber shared object module.
:param string module: the module name, without the "libwireplumber-module-"
prefix (ex specify "mixer-api" to load "libwireplumber-module-mixer-api")
:param table args: optional module arguments table
.. function:: load_optional_module(module, args)
Loads an optional WirePlumber shared object module. Optional in this case
means that if the module is not present on the filesystem, it will be ignored.
:param string module: the module name, without the "libwireplumber-module-"
prefix (ex specify "mixer-api" to load "libwireplumber-module-mixer-api")
:param table args: optional module arguments table
.. function:: load_pw_module(module)
Loads a PipeWire shared object module
:param string module: the module name, without the "libpipewire-module-"
prefix (ex specify "adapter" to load "libpipewire-module-adapter")
.. function:: load_script(script, args)
Loads a Lua script (a functionality script, not a lua configuration file)
:param string script: the script's filename (ex. "policy-node.lua")
:param table args: optional script arguments table
.. function:: load_monitor(monitor, args)
Loads a Lua monitor script. Monitors are scripts found in the ``monitors/``
directory and their purpose is to monitor and load devices.
:param string monitor: the scripts's name without the directory or the .lua
extension (ex. "alsa" will load "monitors/alsa.lua")
:param table args: optional script arguments table
.. function:: load_access(access, args)
Loads a Lua access script. Access scripts are ones found in the ``access/``
directory and their purpose is to manage application permissions.
:param string access: the scripts's name without the directory or the .lua
extension (ex. "flatpak" will load "access/access-flatpak.lua")
:param table args: optional script arguments table

View file

@ -0,0 +1,94 @@
.. _config_locations:
Locations of files
==================
Location of configuration files
-------------------------------
WirePlumber's default locations of its configuration files are determined at
compile time by the build system. Typically, those end up being
``$XDG_CONFIG_DIR/wireplumber``, ``/etc/wireplumber``, and
``/usr/share/wireplumber``, in that order of priority.
In more detail, the latter two are controlled by the ``--sysconfdir`` and ``--datadir``
meson options. When those are set to an absolute path, such as ``/etc``, the
location of the configuration files is set to be ``$sysconfdir/wireplumber``.
When set to a relative path, such as ``etc``, then the installation prefix (``--prefix``)
is prepended to the path: ``$prefix/$sysconfdir/wireplumber``
The three locations are intended for custom user configuration,
host-specific configuration and distribution-provided configuration,
respectively. At runtime, WirePlumber will search the directories
for the highest-priority directory to contain the needed configuration file.
This allows a user or system administrator to easily override the distribution
provided configuration files by placing an equally named file in the respective
directory.
It is also possible to override the configuration directory by setting the
``WIREPLUMBER_CONFIG_DIR`` environment variable::
WIREPLUMBER_CONFIG_DIR=src/config wireplumber
If ``WIREPLUMBER_CONFIG_DIR`` is set, the default locations are ignored and
configuration files are *only* looked up in this directory.
Location of scripts
-------------------
WirePlumber's default locations of its scripts are the same ones as for the
configuration files, but with the ``scripts`` directory appended.
Typically, these end up being ``$XDG_CONFIG_DIR/wireplumber/scripts``,
``/etc/wireplumber/scripts``, and ``/usr/share/wireplumber/scripts``,
in that order of priority.
The three locations are intended for custom user scripts,
host-specific scripts and distribution-provided scripts, respectively.
At runtime, WirePlumber will search the directories for the highest-priority
directory to contain the needed script.
It is also possible to override the scripts directory by setting the
``WIREPLUMBER_DATA_DIR`` environment variable::
WIREPLUMBER_DATA_DIR=src wireplumber
The "data" directory is a somewhat more generic path that may be used for
other kinds of data files in the future. For scripts, WirePlumber still expects
to find a ``scripts`` subdirectory in this "data" directory, so in the above
example the scripts would be in ``src/scripts``.
If ``WIREPLUMBER_DATA_DIR`` is set, the default locations are ignored and
scripts are *only* looked up in this directory.
Location of modules
-------------------
WirePlumber modules
^^^^^^^^^^^^^^^^^^^
Like with configuration files, WirePlumber's default location of its modules is
determined at compile time by the build system. Typically, it ends up being
``/usr/lib/wireplumber-0.4`` (or ``/usr/lib/<arch-triplet>/wireplumber-0.4`` on
multiarch systems)
In more detail, this is controlled by the ``--libdir`` meson option. When
this is set to an absolute path, such as ``/lib``, the location of the
modules is set to be ``$libdir/wireplumber-$abi_version``. When this is set
to a relative path, such as ``lib``, then the installation prefix (``--prefix``)
is prepended to the path: ``$prefix/$libdir/wireplumber-$abi_version``.
It is possible to override this directory at runtime by setting the
``WIREPLUMBER_MODULE_DIR`` environment variable::
WIREPLUMBER_MODULE_DIR=build/modules wireplumber
PipeWire and SPA modules
^^^^^^^^^^^^^^^^^^^^^^^^
PipeWire and SPA modules are not loaded from the same location as WirePlumber's
modules. They are loaded from the location that PipeWire loads them.
It is also possible to override these locations by using environment variables:
``SPA_PLUGIN_DIR`` and ``PIPEWIRE_MODULE_DIR``. For more details, refer to
PipeWire's documentation.

View file

@ -0,0 +1,126 @@
.. _config_main:
Main configuration file
=======================
The main configuration file is by default called ``wireplumber.conf``. This can
be changed on the command line by passing the ``--config-file`` or ``-c`` option::
wireplumber --config-file=bluetooth.conf
The ``--config-file`` option is useful to run multiple instances of wireplumber
that do separate tasks each. For more information on this subject, see the
:ref:`Multiple Instances <config_multi_instance>` section.
The format of this configuration file is the variant of JSON that is also
used in PipeWire configuration files. Note that this is subject to change
in the future.
All sections are essentially JSON objects. Lines starting with *#* are treated
as comments and ignored. The list of all possible section JSON objects are:
* *context.properties*
Used to define properties to configure the PipeWire context and some modules.
Example::
context.properties = {
application.name = WirePlumber
log.level = 2
}
This sets the daemon's name to *WirePlumber* and the log level to *2*, which
only displays errors and warnings. See the
:ref:`Debug Logging <logging>` section for more details.
* *context.spa-libs*
Used to find spa factory names. It maps a spa factory name regular expression
to a library name that should contain that factory. The object property names
are the regular expression, and the object property values are the actual
library name::
<factory-name regex> = <library-name>
Example::
context.spa-libs = {
api.alsa.* = alsa/libspa-alsa
audio.convert.* = audioconvert/libspa-audioconvert
}
In this example, we instruct wireplumber to only any *api.alsa.** factory name
from the *libspa-alsa* library, and also any *audio.convert.** factory name
from the *libspa-audioconvert* library.
* *context.modules*
Used to load PipeWire modules. This does not affect the PipeWire daemon by any
means. It exists simply to allow loading *libpipewire* modules in the PipeWire
core that runs inside WirePlumber. This is usually useful to load PipeWire
protocol extensions, so that you can export custom objects to PipeWire and
other clients.
Users can also pass key-value pairs if the specific module has arguments, and
a combination of 2 flags: ``ifexists`` flag is given, the module is ignored when
not found; if ``nofail`` is given, module initialization failures are ignored::
{
name = <module-name>
[ args = { <key> = <value> ... } ]
[ flags = [ [ ifexists ] [ nofail ] ]
}
Example::
context.modules = [
{ name = libpipewire-module-adapter }
{
name = libpipewire-module-metadata,
flags = [ ifexists ]
}
]
The above example loads both PipeWire adapter and metadata modules. The
metadata module will be ignored if not found because of its ``ifexists`` flag.
* *context.components*
Used to load WirePlumber components. Components can be either WirePlumber
modules written in C, WirePlumber scripts or other configuration
files::
{ name = <component-name>, type = <component-type> }
Valid component types include:
* ``module``: A WirePlumber shared object module
* ``script/lua``: A WirePlumber Lua script
(requires ``libwireplumber-module-lua-scripting``)
* ``config/lua``: A WirePlumber Lua configuration file
(requires ``libwireplumber-module-lua-scripting``)
Example::
context.components = [
{ name = libwireplumber-module-lua-scripting, type = module }
{ name = main.lua, type = config/lua }
]
This will load the WirePlumber lua-scripting module, dynamically, and then
it will also load any components specified in the ``main.lua`` file.
.. note::
When loading lua configuration files, WirePlumber will also look for
additional files in the directory suffixed with ``.d`` and will load
all of them as well. For example, loading ``example.lua`` will also load
any ``.lua`` files under ``example.lua.d/``. In addition, the presence of the
main file is optional, so it is valid to specify ``example.lua`` in the
component name, while ``example.lua`` doesn't exist, but ``example.lua.d/``
exists instead and has ``.lua`` files to load.
For more information about lua configuration files, see the
:ref:`Lua configuration files <config_lua>` section.

View file

@ -0,0 +1,11 @@
# you need to add here any files you add to the toc directory as well
sphinx_files += files(
'locations.rst',
'main.rst',
'config_lua.rst',
'multi_instance.rst',
'alsa.rst',
'bluetooth.rst',
'policy.rst',
'access.rst',
)

View file

@ -0,0 +1,45 @@
.. _config_multi_instance:
Running multiple instances
==========================
WirePlumber has the ability to run either as a single instance daemon or as
multiple instances, meaning that there can be multiple processes, each one
doing a different task.
In the default configuration, both setups are supported. The default is to run
in single-instance mode.
In single-instance mode, WirePlumber reads ``wireplumber.conf``, which is the
default configuration file, and from there it loads ``main.lua``, ``policy.lua``
and ``bluetooth.lua``, which are lua configuration files (deployed as directories)
that enable all the relevant functionality.
In multi-instance mode, WirePlumber is meant to be started with the
``--config-file`` command line option 3 times:
.. code-block:: console
$ wireplumber --config-file=main.conf
$ wireplumber --config-file=policy.conf
$ wireplumber --config-file=bluetooth.conf
That loads one process which reads ``main.conf``, which then loads ``main.lua``
and enables core functionality. Then another process that reads ``policy.conf``,
which then loads ``policy.lua`` and enables policy functionality... and so on.
To make this easier to work with, a template systemd unit is provided, which is
meant to be started with the name of the main configuration file as a
template argument:
.. code-block:: console
$ systemctl --user disable wireplumber # disable the single instance
$ systemctl --user enable wireplumber@main
$ systemctl --user enable wireplumber@policy
$ systemctl --user enable wireplumber@bluetooth
It is obviously possible to start as many instances as desired, with manually
crafted configuration files, as long as it is ensured that these instances
serve a different purpose and they do not conflict with each other.

View file

@ -0,0 +1,116 @@
.. _config_policy:
Policy Configuration
====================
policy.lua.d/10-default-policy.lua
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file contains generic default policy properties that can be configured.
* *default_policy.policy*
This is a Lua object that contains several properties that change the
behavior of the default WirePlumber policy.
Example:
.. code-block:: lua
default_policy.policy = {
["move"] = true,
}
The above example will set the ``move`` policy property to ``true``.
The list of supported properties are:
.. code-block:: lua
["move"] = true
Moves session items when metadata ``target.node`` changes.
.. code-block:: lua
["follow"] = true
Moves session items to the default device when it has changed.
.. code-block:: lua
["audio.no-dsp"] = false
Set to ``true`` to disable channel splitting & merging on nodes and enable
passthrough of audio in the same format as the format of the device. Note that
this breaks JACK support; it is generally not recommended.
.. code-block:: lua
["duck.level"] = 0.3
How much to lower the volume of lower priority streams when ducking. Note that
this is a linear volume modifier (not cubic as in PulseAudio).
policy.lua.d/50-endpoints-config.lua
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Endpoints are objects that can group multiple clients into different groups or
roles. This is useful if a user wants to apply specific actions when a client
is connected to a particular role/endpoint. This configuration file allows
users to configure those endpoints and their actions.
* *default_policy.policy.roles*
This is a Lua array with objects defining the actions of each role.
Example:
.. code-block:: lua
default_policy.policy.roles = {
["Multimedia"] = {
["alias"] = { "Movie", "Music", "Game" },
["priority"] = 10,
["action.default"] = "mix",
}
["Notification"] = {
["priority"] = 20,
["action.default"] = "duck",
["action.Notification"] = "mix",
}
}
The above example defines actions for both ``Multimedia`` and ``Notification``
roles. Since the Notification role has more priority than the Multimedia
role, when a client connects to the Notification endpoint, it will ``duck``
the volume of all Multimedia clients. If Multiple Notification clients want
to play audio, only the Notifications audio will be mixed.
Possible values of actions are: ``mix`` (Mixes audio),
``duck`` (Mixes and lowers the audio volume) or ``cork`` (Pauses audio).
* *default_policy.policy.endpoints*
This is a Lua array with objects defining the endpoints that the user wants
to create.
Example:
.. code-block:: lua
default_policy.endpoints = {
["endpoint.multimedia"] = {
["media.class"] = "Audio/Sink",
["role"] = "Multimedia",
}
},
["endpoint.notifications"] = {
["media.class"] = "Audio/Sink",
["role"] = "Notification",
}
This example creates 2 endpoints, with names ``endpoint.multimedia`` and
``endpoint.notifications``; and assigned roles ``Multimedia`` and ``Notification``
respectively. Both endpoints have ``Audio/Sink`` media class, and so are only
used for playback.

View file

@ -1,633 +0,0 @@
.. _daemon-configuration:
Configuration
=============
WirePlumber is a heavily modular daemon. By itself, it doesn't do anything
except load the configured modules. All the rest of the logic is implemented
inside those modules.
Modular design ensures that it is possible to swap the implementation of
specific functionality without having to re-implement the rest of it, allowing
flexibility on target-sensitive parts, such as policy management and
making use of non-standard hardware.
*wireplumber.conf*
------------------
This is WirePlumber's main configuration file. It is read at startup, before
connecting to the PipeWire daemon, and its purpose is to define the different
sections of the daemon's configuration. Since the format of this configuration
file is in JSON, all sections are essentially JSON objects. Lines starting with
*#* are treated as comments and ignored. The list of all possible section JSON
objects are:
* *context.properties*
Used to define properties to configure the PipeWire context and some modules.
Example::
context.properties = {
application.name = WirePlumber
Log.level = 2
}
This sets the daemon's name to *WirePlumber* and the log level to *2*, which
only displays errors and warnings. See the Debug_ section for more details.
.. _Debug: https://pipewire.pages.freedesktop.org/wireplumber/daemon-logging.html
* *context.spa-libs*
Used to find spa factory names. It maps a spa factory name regular expression
to a library name that should contain that factory. The object property names
are the regular expression, and the object property values are the actual
library name::
<factory-name regex> = <library-name>
Example::
context.spa-libs = {
api.alsa.* = alsa/libspa-alsa
audio.convert.* = audioconvert/libspa-audioconvert
}
In this example, we instruct wireplumber to only any *api.alsa.** factory name
from the *libspa-alsa* library, and also any *audio.convert.** factory name
from the *libspa-audioconvert* library.
* *context.modules*
Used to load PipeWire modules. This does not affect the PipeWire daemon by any
means. It exists simply to allow loading *libpipewire* modules in the PipeWire
core that runs inside WirePlumber. This is usually useful to load PipeWire
protocol extensions, so that you can export custom objects to PipeWire and
other clients.
Users can also pass key-value pairs if the specific module has arguments, and
a combination of 2 flags: `ifexists` flag is given, the module is ignored when
not found; if `nofail` is given, module initialization failures are ignored::
{
name = <module-name>
[ args = { <key> = <value> ... } ]
[ flags = [ [ ifexists ] [ nofail ] ]
}
Example::
context.modules = [
{ name = libpipewire-module-adapter }
{
name = libpipewire-module-metadata,
flags = [ ifexists ]
}
]
The above example loads both PipeWire adapter and metadata modules. The
metadata module will be ignored if not found because of its `ifexists` flag.
* *context.components*
Used to load WirePlumber components. Components can be either a WirePlumber
module written in C that is loaded dynamically, or a directory with Lua
configuration files::
{ name = <component-name>, type = <component-type> }
Example::
context.components = [
{ name = libwireplumber-module-lua-scripting, type = module }
{ name = main.lua, type = config/lua }
]
This will load the WirePlumber Lua scripting module dynamically, and any Lua
file that is placed under the *main.lua.d* directory, which can load other
components from there (See Lua configuration directories below for more
details).
Location of configuration files
-------------------------------
WirePlumber's default locations of its configuration files are determined at
compile time by the build system. Typically, those end up being
`XDG_CONFIG_DIR/wireplumber`, `/etc/wireplumber`, and
`/usr/share/wireplumber`, in that order of priority.
In more detail, the latter two are controlled by the `--sysconfdir` and `--datadir`
meson options. When those are set to an absolute path, such as `/etc`, the
location of the configuration files is set to be `$sysconfdir/wireplumber`.
When set to a relative path, such as `etc`, then the installation prefix (`--prefix`)
is prepended to the path: `$prefix/$sysconfdir/wireplumber`
The three locations are intended for custom user configuration,
host-specific configuration and distribution-provided configuration,
respectively. At runtime, WirePlumber will search the directories
for the highest-priority directory to contain the `wireplumber.conf`
configuration file. This allows a user or system administrator to easily
override the distribution provided configuration files by placing an equally
named file in the respective directory.
It is possible to override the lookup path at runtime by passing the
`--config-file` or `-c` option::
wireplumber --config-file=src/config/wireplumber.conf
It is also possible to override the whole configuration directory, so that
all other configuration files are being read from a different location as well,
by setting the `WIREPLUMBER_CONFIG_DIR` environment variable::
WIREPLUMBER_CONFIG_DIR=src/config wireplumber
If `WIREPLUMBER_CONFIG_DIR` is set, the default locations are ignored.
Location of modules
-------------------
WirePlumber modules
^^^^^^^^^^^^^^^^^^^
Like with configuration files, WirePlumber's default location of its modules is
determined at compile time by the build system. Typically, it ends up being
`/usr/lib/wireplumber-0.1` (or `/usr/lib/<arch-triplet>/wireplumber-0.1` on
multiarch systems)
In more detail, this is controlled by the `--libdir` meson option. When
this is set to an absolute path, such as `/lib`, the location of the
modules is set to be `$libdir/wireplumber-$abi_version`. When this is set
to a relative path, such as `lib`, then the installation prefix (`--prefix`)
is prepended to the path\: `$prefix/$libdir/wireplumber-$abi_version`.
It is possible to override this directory at runtime by setting the
`WIREPLUMBER_MODULE_DIR` environment variable::
WIREPLUMBER_MODULE_DIR=build/modules wireplumber
PipeWire and SPA modules
^^^^^^^^^^^^^^^^^^^^^^^^
PipeWire and SPA modules are not loaded from the same location as WirePlumber's
modules. They are loaded from the location that PipeWire loads them.
It is also possible to override these locations by using environment variables:
`SPA_PLUGIN_DIR` and `PIPEWIRE_MODULE_DIR`. For more details, refer to
PipeWire's documentation.
Lua Configuration Directories
-----------------------------
A Lua directory can contain a list of Lua configuration files. Those files are
loaded alphabetically by filename so that user can control the order in which
Lua configuration files are executed.
The default WirePlumber configuration has the following Lua configuration
directories (note that this can change in future releases):
* *main.lua.d*
This directory contains the main WirePlumber Lua configuration files. Here you
will find the configuration for ALSA, V4L2 and libcamera monitors configuration.
In addition to this, there is also access configuration for the clients.
* *bluetooth.lua.d*
This directory is only used for Bluetooth configuration.
* *policy.lua.d*
This directory is used for both the policy and endpoints configuration.
Lua Configuration Files
-----------------------
Some of the most relevant Lua configuration files from the Lua configuration
directories are:
main.lua.d/\*-alsa-config.lua
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This configuration file is charged to configure the ALSA nodes created by
PipeWire. Users can configure how these ALSA nodes are created by defining a
set of properties and rules:
* *alsa_monitor.properties*
This is a simple Lua object that has key value pairs used as properties.
Example::
alsa_monitor.properties = {
["alsa.jack-device"] = false,
["alsa.reserve"] = true,
}
The above example will configure the ALSA monitor to not enable the JACK
device, and do ALSA device reservation using the mentioned DBus interface.
A list of valid properties are::
["alsa.jack-device"] = false
Creates a JACK device if set to `true`. 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.reserve"] = true
Reserve ALSA devices via org.freedesktop.ReserveDevice1 on D-Bus.::
["alsa.reserve.priority"] = -20
The used ALSA device reservation priority.::
["alsa.reserve.application-name"] = "WirePlumber"
The used ALSA device reservation application name.
* *alsa_monitor.rules*
This is a Lua array that can contain objects with rules for a device or node.
Those objects have 2 properties. The first one is `matches`, which allow users
to define rules to match 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. The second property is `apply_properties`, and it is
used to apply properties on the matched object.
Example::
alsa_monitor.rules = {
matches = {
{
{ "device.name", "matches", "alsa_card.*" },
},
},
apply_properties = {
["api.alsa.use-acp"] = true,
}
}
This sets the API ALSA use ACP property to all devices with a name that
matches the `alsa_card.*` pattern.
A list of valid properties are::
["api.alsa.use-acp"] = true
Use the ACP (alsa card profile) code to manage the device. This will probe the
device and configure the available profiles, ports and mixer settings. The
code to do this is taken directly from PulseAudio and provides devices that
look and feel exactly like the PulseAudio devices.::
["api.alsa.use-ucm"] = true
By default, the UCM configuration is used when it is available for your device.
With this option you can disable this and use the ACP profiles instead.::
["api.alsa.soft-mixer"] = false
Setting this option to true will disable the hardware mixer for volume control
and mute. All volume handling will then use software volume and mute, leaving
the hardware mixer untouched. The hardware mixer will still be used to mute
unused audio paths in the device.::
["api.alsa.ignore-dB"] = false
Setting this option to true will ignore the decibel setting configured by the
driver. Use this when the driver reports wrong settings.::
["device.profile-set"] = "profileset-name"
This option can be used to select a custom profile set name for the device.
Usually this is configured in Udev rules but it can also be specified here.::
["device.profile"] = "default profile name"
The default active profile name.::
["api.acp.auto-profile"] = false
Automatically select the best profile for the device. Normally this option is
disabled because the session manager will manage the profile of the device.
The session manager can save and load previously selected profiles. Enable
this if your session manager does not handle this feature.::
["api.acp.auto-port"] = false
Automatically select the highest priority port that is available. This is by
default disabled because the session manager handles the task of selecting and
restoring ports. It can, for example, restore previously saved volumes. Enable
this here when the session manager does not handle port restore.
Some of the other properties that might be configured on devices::
["device.nick"] = "My Device",
["device.description"] = "My Device"
`device.description` will show up in most apps when a device name is shown.
main.lua.d/\*-v4l2-config.lua
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Using the same format as the the ALSA monitor properties and rules from above.
This configuration file is charged to configure the V4L2 nodes created by
PipeWire.
Example::
v4l2_monitor.rules = {
matches = {
{
{ "device.name", "matches", "v4l2_device.*" },
},
},
apply_properties = {
["node.pause-on-idle"] = false,
},
}
This will set the pause node on idle all V4L2 devices whose device name matches
the `v4l2_device.*` pattern.
main.lua.d/\*-default-access-config.lua
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Using a similar format as the ALSA monitor, this configuration file is charged
to configure the client objects created by PipeWire.
* *default_access.properties*
A Lua object that contains generic client configuration properties in the
for of key pairs.
Example::
default_access.properties = {
["enable-flatpak-portal"] = true,
}
The above example sets to `true` the `enable-flatpak-portal` property.
The list of valid properties are::
["enable-flatpak-portal"] = true,
Whether to enable the flatpak portal or not.
* *default_access.rules*
This is a Lua array that can contain objects with rules for a client object.
Those Lua objects have 2 properties. Similar to the ALSA configuration, the
first property is `matches`, which allow users to define rules to match a
client object. The second property is `default_permissions`, and it is
used to set permissions on the matched client object.
Example::
{
matches = {
{
{ "pipewire.access", "=", "flatpak" },
},
},
default_permissions = "rx",
}
This grants read and execute permissions to all clients that have the
`pipewire.access` property set to `flatpak`.
Possible permissions are any combination of `r`, `w` and `x` for read, write
and execute; or `all` for all kind of permissions.
bluetooth.lua.d/\*-bluez-config.lua
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Using the same format as the ALSA monitor, this configuration file is charged
to configure the Bluetooth device and nodes created by PipeWire.
* *bluez_monitor.properties*
A Lua object that contains generic client configuration properties in the
for of key pairs.
Example::
bluez_monitor.properties = {
["bluez5.enable-msbc"] = true,
}
This example will enable the MSBC codec in connected Bluetooth devices that
support it.
The list of valid properties are::
["bluez5.enable-sbc-xq"] = true
Enables the SBC-XQ codec in connected Blueooth devices that support it::
["bluez5.enable-msbc"] = true
Enables the MSBC codec in connected Blueooth devices that support it::
["bluez5.enable-hw-volume"] = true
Enables hardware volume controls in Bluetooth devices that support it::
["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]"
Enabled headset roles (default: [ hsp_hs hfp_ag ]), this property only applies
to native backend. Currently some headsets (Sony WH-1000XM3) are not working
with both hsp_ag and hfp_ag enabled, disable either hsp_ag or hfp_ag to work
around it.
Supported headset roles: `hsp_hs` (HSP Headset), `hsp_ag` (HSP Audio Gateway),
`hfp_hf` (HFP Hands-Free) and `hfp_ag` (HFP Audio Gateway)::
["bluez5.codecs"] = "[ sbc sbc_xq aac ]"
Enables `sbc`, `sbc_zq` and `aac` A2DP codecs.
Supported codecs: `sbc`, `sbc_xq`, `aac`, `ldac`, `aptx`, `aptx_hd`, `aptx_ll`,
`aptx_ll_duplex`, `faststream`, `faststream_duplex`.
All codecs are supported by default::
["bluez5.hfphsp-backend"] = "native"
HFP/HSP backend (default: native). Available values: `any`, `none`, `hsphfpd`,
`ofono` or `native`.::
["bluez5.default.rate"] = 48000
The bluetooth default audio rate.::
["bluez5.default.channels"] = 2
The bluetooth default number of channels.
* *bluez_monitor.rules*
Like the ALSA configuration, this is a Lua array that can contain objects with
rules for a Bluetooth device or node. Those objects have 2 properties. The
first one is `matches`, which allow users to define rules to match a Bluetooth
device or node. The second property is `apply_properties`, and it is used to
apply properties on the matched Bluetooth device or node.
Example::
{
matches = {
{
{ "device.name", "matches", "bluez_card.*" },
},
},
apply_properties = {
["bluez5.auto-connect"] = "[ hfp_hf hsp_hs a2dp_sink ]"
}
}
This will set the auto-connect property to `hfp_hf`, `hsp_hs` and `a2dp_sink`
on bluetooth devices whose name matches the `bluez_card.*` pattern.
A list of valid properties are::
["bluez5.auto-connect"] = "[ hfp_hf hsp_hs a2dp_sink ]"
Auto-connect device profiles on start up or when only partial profiles have
connected. Disabled by default if the property is not specified.
Supported values are: `hfp_hf`, `hsp_hs`, `a2dp_sink`, `hfp_ag`, `hsp_ag` and
`a2dp_source`.::
["bluez5.hw-volume"] = "[ hfp_ag hsp_ag a2dp_source ]"
Hardware volume controls (default: `hfp_ag`, `hsp_ag`, and `a2dp_source`)
Supported values are: `hfp_hf`, `hsp_hs`, `a2dp_sink`, `hfp_ag`, `hsp_ag` and
`a2dp_source`.::
["bluez5.a2dp.ldac.quality"] = "auto"
LDAC encoding quality.
Available values: `auto` (Adaptive Bitrate, default),
`hq` (High Quality, 990/909kbps), `sq` (Standard Quality, 660/606kbps) and
`mq` (Mobile use Quality, 330/303kbps).::
["bluez5.a2dp.aac.bitratemode"] = 0
AAC variable bitrate mode.
Available values: 0 (cbr, default), 1-5 (quality level).::
["device.profile"] = "a2dp-sink"
Profile connected first.
Available values: `a2dp-sink` (default) or `headset-head-unit`.
policy.lua.d/\*-default-policy.lua
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file contains Generic default policy properties that can be configured.
* *default_policy.policy*
This is a Lua object that contains several properties that change the
behavior of the default WirePlumber policy.
Example::
default_policy.policy = {
["move"] = true,
}
The above example will set the `move` policy property to `true`.
The list of supported properties are::
["move"] = true
Moves session items when metadata `target.node` changes.::
["follow"] = true
Moves session items to the default device when it has changed.::
["audio.no-dsp"] = false
Set to `true` to disable channel splitting & merging on nodes and enable
passthrough of audio in the same format as the format of the device. Note that
this breaks JACK support; it is generally not recommended.::
["duck.level"] = 0.3
How much to lower the volume of lower priority streams when ducking. Note that
this is a linear volume modifier (not cubic as in PulseAudio).
policy.lua.d/\*-endpoints-config.lua
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Endpoints are nodes that can group multiple clients into different groups or
roles. This is useful if a user wants to apply specific actions when a client
is connected to a particular role/endpoint. This configuration file allows
users to configure those endpoints and their actions.
* *default_policy.policy.roles*
This is a Lua array with objects defining the actions of each role.
Example::
default_policy.policy.roles = {
["Multimedia"] = {
["alias"] = { "Movie", "Music", "Game" },
["priority"] = 10,
["action.default"] = "mix",
}
["Notification"] = {
["priority"] = 20,
["action.default"] = "duck",
["action.Notification"] = "mix",
}
}
The above example defines actions for both `Multimedia` and `Notification`
roles. Since the Notification role has more priority than the Multimedia
role, when a client connects to the Notification endpoint, it will `duck`
the volume of all Multimedia clients. If Multiple Notification clients want
to play audio, only the Notifications audio will be mixed.
Possible values of actions are: `mix` (Mixes audio),
`duck` (Mixes and lowers the audio volume) or `cork` (Pauses audio).
* *default_policy.policy.endpoints*
This is a Lua array with objects defining the endpoints that the user wants
to create.
Example::
default_policy.endpoints = {
["endpoint.multimedia"] = {
["media.class"] = "Audio/Sink",
["role"] = "Multimedia",
}
},
["endpoint.notifications"] = {
["media.class"] = "Audio/Sink",
["role"] = "Notification",
}
This example creates 2 endpoints, with names `endpoint.multimedia` and
`endpoint.notifications`; and assigned roles `Multimedia` and `Notification`
respectively. Both endpoints have `Audio/Sink` media class, and so are only
used for playback.

View file

@ -9,7 +9,7 @@ Table of Contents
installing-wireplumber.rst
running-wireplumber-daemon.rst
daemon-configuration.rst
configuration.rst
daemon-logging.rst
.. toctree::

View file

@ -14,7 +14,7 @@ and that will likely also affect WirePlumber's Lua API.
There are currently two uses for Lua in WirePlumber:
- To implement the scripting engine
- To implement lua-based :ref:`config files <daemon-configuration>`
- To implement lua-based :ref:`config files <config_lua>`
This section is only documenting the API of the **scripting engine**

View file

@ -3,7 +3,7 @@ sphinx_files += files(
'index.rst',
'installing-wireplumber.rst',
'running-wireplumber-daemon.rst',
'daemon-configuration.rst',
'configuration.rst',
'daemon-logging.rst',
'contributing.rst',
'community.rst',
@ -15,3 +15,4 @@ sphinx_files += files(
subdir('c_api')
subdir('lua_api')
subdir('configuration')