Skip to content
Snippets Groups Projects
Commit 1f57ee1d authored by Apertis CI robot's avatar Apertis CI robot
Browse files

Merge updates from debian/bookworm

parents 259cb5b5 6588ac13
No related branches found
No related tags found
4 merge requests!19Backport update from apertis/v2023dev1 → apertis/v2022,!18Draft: Backport update from apertis/v2023dev1 → apertis/v2022,!16Draft: Backport update from apertis/v2023dev1 → apertis/v2022,!15Update from debian/bookworm for apertis/v2023dev1
This commit is part of merge request !16. Comments created here will be created in the context of that merge request.
Showing
with 1389 additions and 464 deletions
......@@ -103,6 +103,11 @@ include:
- export BUILD_ID="$CI_JOB_ID"
- export PREFIX="$PWD/prefix-$BUILD_ID"
- export PW_BUILD_DIR="$PWD/build-pipewire-$BUILD_ID"
- |
if [ -n "$FDO_CI_CONCURRENT" ]; then
NINJA_ARGS="-j$FDO_CI_CONCURRENT $NINJA_ARGS"
export NINJA_ARGS
fi
# Build pipewire
# Fedora also ships that, but without the test plugins that we need...
- git clone --depth=1 --branch="$PIPEWIRE_HEAD"
......@@ -115,7 +120,7 @@ include:
-Dsdl2=disabled -Dsndfile=disabled -Dlibpulse=disabled -Davahi=disabled
-Decho-cancel-webrtc=disabled -Dsession-managers=[]
-Dvideotestsrc=enabled -Daudiotestsrc=enabled -Dtest=enabled
- ninja -C "$PW_BUILD_DIR" install
- ninja $NINJA_ARGS -C "$PW_BUILD_DIR" install
# misc environment only for wireplumber
- export WP_BUILD_DIR="$PWD/build-wireplumber-$BUILD_ID"
- export PKG_CONFIG_PATH="$(dirname $(find "$PREFIX" -name 'libpipewire-*.pc')):$PKG_CONFIG_PATH"
......@@ -123,9 +128,9 @@ include:
# Build wireplumber
- meson "$WP_BUILD_DIR" . --prefix="$PREFIX" $BUILD_OPTIONS
- cd "$WP_BUILD_DIR"
- ninja
- ninja test
- ninja install
- ninja $NINJA_ARGS
- ninja $NINJA_ARGS test
- ninja $NINJA_ARGS install
artifacts:
name: wireplumber-$CI_COMMIT_SHA
when: always
......@@ -213,7 +218,7 @@ build_with_coverity:
--comptype gcc --compiler cc --template
--xml-option=append_arg@C:--ppp_translator
--xml-option=append_arg@C:"replace/GLIB_(DEPRECATED|AVAILABLE)_ENUMERATOR_IN_\d_\d\d(_FOR\(\w+\)|)\s+=/ ="
- cov-build --dir cov-int --config coverity_conf.xml ninja -C "$WP_BUILD_DIR"
- cov-build --dir cov-int --config coverity_conf.xml ninja $NINJA_ARGS -C "$WP_BUILD_DIR"
- tar caf wireplumber.tar.gz cov-int
- curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
--form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL
......
WirePlumber 0.4.5
WirePlumber 0.4.7
~~~~~~~~~~~~~~~~~
Fixes:
- Fixed a regression in 0.4.6 that caused the selection of the default audio
sources and sinks to be delayed until some event, which effectively caused
losing audio output in many circumstances (#148, #150, #151, #153)
- Fixed a regression in 0.4.6 that caused the echo-cancellation pipewire
module (and possibly others) to not work
- A default sink or source is now not selected if there is no available route
for it (#145)
- Fixed an issue where some clients would wait for a bit while seeking (#146)
- Fixed audio capture in the endpoints-based policy
- Fixed an issue that would cause certain lua scripts to error out with older
configuration files (#158)
Past releases
~~~~~~~~~~~~~
WirePlumber 0.4.6
.................
Changes:
- Fixed a lot of race condition bugs that would cause strange crashes or
many log messages being printed when streaming clients would connect and
disconnect very fast (#128, #78, ...)
- Improved the logic for selecting a default target device (#74)
- Fixed switching to headphones when the wired headphones are plugged in (#98)
- Fixed an issue where ``udevadm trigger`` would break wireplumber (#93)
- Fixed an issue where switching profiles of a device could kill client nodes
- Fixed briefly switching output to a secondary device when switching device
profiles (#85)
- Fixed ``wpctl status`` showing default device selections when dealing with
module-loopback virtual sinks and sources (#130)
- WirePlumber now ignores hidden files from the config directory (#104)
- Fixed an interoperability issue with jackdbus (pipewire#1846)
- Fixed an issue where pulseaudio tcp clients would not have permissions to
connect to PipeWire (pipewire#1863)
- Fixed a crash in the journald logger with NULL debug messages (#124)
- Enabled real-time priority for the bluetooth nodes to run in RT (#132)
- Made the default stream volume configurable
- Scripts are now also looked up in $XDG_CONFIG_HOME/wireplumber/scripts
- Updated documentation on configuring WirePlumber and fixed some more
documentation issues (#68)
- Added support for using strings as log level selectors in WIREPLUMBER_DEBUG
WirePlumber 0.4.5
.................
Fixes:
- Fixed a crash that could happen after a node linking error (#76)
......@@ -34,9 +102,6 @@ API:
- The file-monitor-api plugin can now watch files for changes in addition
to directories
Past releases
~~~~~~~~~~~~~
WirePlumber 0.4.4
.................
......
wireplumber (0.4.7-1) unstable; urgency=medium
* Team upload.
* New upstream version 0.4.7
-- Dylan Aïssi <daissi@debian.org> Thu, 13 Jan 2022 11:06:07 +0100
wireplumber (0.4.6-1) unstable; urgency=medium
* Team upload.
* New upstream version 0.4.6
* Simplify debian/watch file
* Bump minimum pipewire to 0.3.43
* Update symbols file
-- Dylan Aïssi <daissi@debian.org> Mon, 10 Jan 2022 17:08:47 +0100
wireplumber (0.4.5-1+apertis1) apertis; urgency=medium
* Sync updates from Debian bookworm
......
......@@ -9,7 +9,7 @@ Build-Depends: debhelper-compat (= 13),
libgirepository1.0-dev,
libglib2.0-dev (>= 2.62),
liblua5.3-dev,
libpipewire-0.3-dev (>= 0.3.32),
libpipewire-0.3-dev (>= 0.3.43),
libspa-0.2-dev,
libsystemd-dev,
meson (>= 0.56.0),
......@@ -18,7 +18,7 @@ Build-Depends: debhelper-compat (= 13),
systemd,
# Only used for automated tests
dbus <!nocheck>,
pipewire (>= 0.3.32) <!nocheck>,
pipewire (>= 0.3.43) <!nocheck>,
Standards-Version: 4.6.0
Homepage: https://gitlab.freedesktop.org/pipewire/wireplumber
Vcs-Browser: https://salsa.debian.org/utopia-team/wireplumber
......@@ -57,7 +57,7 @@ Package: wireplumber
Architecture: linux-any
Depends: ${shlibs:Depends},
${misc:Depends},
pipewire (>= 0.3.32),
pipewire (>= 0.3.43),
Recommends: pipewire-pulse
Section: video
Description: modular session / policy manager for PipeWire
......
......@@ -28,6 +28,7 @@ libwireplumber-0.4.so.0 libwireplumber-0.4-0 #MINVER#
wp_core_load_component@Base 0.3.95
wp_core_new@Base 0.3.95
wp_core_sync@Base 0.3.95
wp_core_sync_closure@Base 0.4.6
wp_core_sync_finish@Base 0.3.95
wp_core_timeout_add@Base 0.3.95
wp_core_timeout_add_closure@Base 0.3.95
......@@ -107,6 +108,7 @@ libwireplumber-0.4.so.0 libwireplumber-0.4-0 #MINVER#
wp_node_new_ports_iterator@Base 0.3.95
wp_node_send_command@Base 0.3.95
wp_node_state_get_type@Base 0.3.95
wp_object_abort_activation@Base 0.4.6
wp_object_activate@Base 0.3.95
wp_object_activate_closure@Base 0.3.95
wp_object_activate_finish@Base 0.3.95
......@@ -202,7 +204,7 @@ libwireplumber-0.4.so.0 libwireplumber-0.4-0 #MINVER#
wp_proxy_get_pw_proxy@Base 0.3.95
wp_proxy_get_type@Base 0.3.95
wp_proxy_set_pw_proxy@Base 0.3.95
wp_proxy_watch_bind_error@Base 0.3.96
#MISSING: 0.4.6-1# wp_proxy_watch_bind_error@Base 0.3.96
wp_session_item_configure@Base 0.3.95
wp_session_item_features_get_type@Base 0.3.95
wp_session_item_get_associated_proxy@Base 0.3.95
......
version=4
opts=filenamemangle=s/.*\/archive\/(\d\S+)\/wireplumber.*\.tar\.gz/wireplumber-$1\.tar\.gz/g \
https://gitlab.freedesktop.org/pipewire/wireplumber/tags?sort=updated_desc .*/archive/(\d\S+)/.*\.tar\.gz.*
https://gitlab.freedesktop.org/pipewire/wireplumber/tags?sort=updated_desc \
archive/@ANY_VERSION@/wireplumber-\d\S*@ARCHIVE_EXT@
.. _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
.. _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.
.. _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.
.. _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``.
.. _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
.. _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.
.. _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.
# 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',
)
.. _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.
.. _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.
.. _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. Its purpose is to list all the modules
that need to be loaded by WirePlumber.
The format of this file is custom and resembles a script with commands::
*comment*
command parameter1 parameter2 ...
Lines are executed in the order they appear and each of them executes an
action defined by the command. Lines starting with *#* are treated as comments
and ignored. Possible commands are
* *add-spa-lib*
Associates SPA plugin names with the names of the SPA modules that they
can be loaded from. This takes 2 parameters - a name pattern and a library name.
This actually does not load the SPA plugin, it only calls *pw_core_add_spa_lib*
with the 2 paramteres given as arguments. As a consequence, it is safe to
call this even if the SPA module is not actually installed on the system.
Example:
::
add-spa-lib api.alsa.* alsa/libspa-alsa
In this example, we let *libpipewire* know that any SPA plugin whose name
starts with *api.alsa.* can be loaded from the SPA module
*alsa/libspa-alsa.so* (relative to the standard SPA modules directory).
* *load-pipewire-module*
Loads a *libpipewire* module. This is similar to the *load-module* commands
that would appear on *pipewire.conf*, the configuration file of the PipeWire
daemon.
This takes at least 1 parameter, the module name, and optionally any module
arguments, in the format that they would be given in *pipewire.conf*
Format:
::
load-pipewire-module module-name some-argument some-property=value
Example:
::
load-pipewire-module libpipewire-module-client-device
This command 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.
* *load-module*
Loads a WirePlumber module. This takes 2 arguments and an optional parameter
block.
Format:
::
load-module ABI module-name {
"parameter" : <"value">
}
The *ABI* parameter specifies the binary interface that WirePlumber shall use
to load this module. Currently, the only supported ABI is *C*. It exists to
allow future expansion, writing modules in other languages.
The *module-name* should be the name of the *.so* file without the *.so*
extension.
Optionally, if the `load-module` line ends with a `{`, the next lines up to
and including the next matching `}` are treated as a parameter block.
This block essentially is a
`GVariant <https://developer.gnome.org/glib/stable/glib-GVariant.html>`_
of type
`GVariant format strings <https://developer.gnome.org/glib/stable/gvariant-format-strings.html>`_
in the
`GVariant Text Format <https://developer.gnome.org/glib/stable/gvariant-text.html>`_.
As a rule of thumb, parameter names in this block must always be strings
enclosed in double quotes, the separation between names and values is done
with the `:` character and values, regardless of their inner type, must always
be enclosed in `<` `>`.
Note that starting the parameter block on the next line is an error. The
starting brace (`{`) must always be on the `load-module` line.
Example:
::
load-module C libwireplumber-module-monitor {
"alsa": <{"factory": <"api.alsa.enum.udev">, "flags": <["use-adapter"]>}>
}
Parameters are module-dependent. They are passed as a GVariant in the
module's initialization function and it is up to the module to interpret
their meaning. WirePlumber does not have any reserved parameters.
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.
module-monitor
""""""""""""""
This module internally loads a SPA "device" object which enumerates all the
devices of a certain subsystem. Then it listens for "node" objects that are
being created by this device and exports them to PipeWire, after adjusting
their properties to provide enough context.
`module-monitor` does not read any configuration files, however, it supports
configuration through parameters defined in the main `wireplumber.conf`.
At the top level, each parameter is creating a monitor instance. The paramter
key is considered to be a friendly name for this instance and can be any string.
The value of each such parameter is meant to be a dictionary with parameters
for this instance. Possible instance parameters are
* `factory`
A string that specifies the name of the SPA factory that loads the intial
"device" object.
Well-known factories are
* "api.alsa.enum.udev" - Discovers ALSA devices via udev
* "api.v4l2.enum.udev" - Discovers V4L2 devices via udev
* "api.bluez5.enum.dbus" - Discovers bluetooth devices by calling bluez5 API via D-Bus
* `flags`
An array of strings that enable specific functionality in the monitor.
Possible flags include
* "use-adapter"
Instructs the monitor to wrap all the created nodes in an "adapter"
SPA node, which provides automatic port splitting/merging and format/rate
conversion. This should be always enabled for audio device nodes.
* "local-nodes"
Instructs the monitor to run all the created nodes locally in in the
WirePlumber process, instead of the default behavior which is to create
the nodes in the PipeWire process. This is useful for bluetooth nodes,
which should run outside of the main PipeWire process for performance
reasons.
* "activate-devices"
Instructs the monitor to automatically set the device profile to "On",
so that the nodes are created. If not specified, the profile must be
set externally by the user before any nodes appear.
module-config-endpoint
""""""""""""""""""""""
This module creates endpoints when WirePlumber detects new nodes in the
pipewire graph. Nodes themselves can be created in two ways.
Device modes are being created by "monitors" that watch a specific subsystem
(udev, bluez, etc...) for devices. Client nodes are being created by client
applications that try to stream to/from pipewire. As soon as a node is created,
the `module-config-endpoint` iterates through all the `.endpoint` configuration
files, in the order that is determined by the filename, and tries to match the
node to the node description in the `[match-node]` table. Upon a successful
match, a new endpoint that follows the description in the `[endpoint]` table is
created.
`*.endpoint` configuration files
""""""""""""""""""""""""""""""""
These files are TOML v0.5 files. At the top-level, they must contain exactly
2 tables: `[match-node]` and `[endpoint]`
The `[match-node]` table contains properties that match a pipewire node that
exists on the graph. Possible fields of this table are
* `properties`
This is a TOML array of tables, where each table must contain two fields:
`name` and `value`, both being strings. Each table describes a match against
one of the pipewire properties of the node. For a successful node match, all
the described properties must match with the node.
The value of the `name` field must match exactly the name of the pipewire
property, while the value of the `value` field can contain '*' (wildcard)
and '?' (joker), adhering to the rules of the
[GLib g_pattern_match() function](https://developer.gnome.org/glib/stable/glib-Glob-style-pattern-matching.html).
When writing `.endpoint` files, a useful utility that you can use to list
device node properties is::
$ wireplumber-cli device-node-props
Another way to figure out some of these properties *for ALSA nodes* is
by parsing the aplay/arecord output. For example, this line from `aplay -l`
is interpreted as follows::
card 0: PCH [HDA Intel PCH], device 2: ALC3246 [ALC3246 Analog]
{ name = "api.alsa.path", value = "hw:0,2" },
{ name = "api.alsa.card", value = "0" },
{ name = "api.alsa.card.id", value = "PCH" },
{ name = "api.alsa.card.name", value = "HDA Intel PCH" },
{ name = "api.alsa.pcm.device", value = "2" },
{ name = "api.alsa.pcm.id", value = "ALC3246" },
{ name = "api.alsa.pcm.name", value = "ALC3246 Analog" }
The `[endpoint]` table contains a description of the endpoint to be created.
Possible fields of this table are
* `session`
Required. A String representing the session name to be used when exporting the
endpoint.
* `type`
Required. Specifies the factory to be used for construction.
The only well-known factories at the moment of writing is `si-adapter` and
`si-simple-node-edpoint`.
* `streams`
Optional. Specifies the name of a `.streams` file that contains the
descriptions of the streams to create for this endpoint. This currently
specific to the implementation of the `pw-audio-softdsp-endpoint` and might
change in the future.
* `config`
Optional. Specifies the configuration table used to configure the endpoint.
This table can have the following entries
* `name`
Optional. The name of the newly created endpoint. If not specified, the
endpoint is named after the node (from the `node.name` property of the
node).
* `media_class`
Optional. A string that specifies an override for the `media.class`
property of the node. It can be used in special circumstances to declare
that an endpoint is dealing with a different type of data. This is only
useful in combination with a policy implementation that is aware of this
media class.
* `role`
Optional. A string representing the role of the endpoint.
* `priority`
Optional. An unsigned integer that specifies the order in which endpoints
are chosen by the policy.
If not specified, the default priority of an endpoint is equal to zero
(i.e. the lowest priority).
* `enable-control-port`
Optional. A boolean representing whether the control port should be
enabled on the endpoint or not.
* `enable-monitor`
Optional. A boolean representing whether the monitor ports should be
enabled on the endpoint or not.
* `preferred-n-channels`
Optional. An unsigned integer that specifies a preference in the number
of audio channels that an audio node should be configured with. Note that
if the node does not support this many channels, it will be configured
with the closest possible number of channels. This is only available
with the `si-adapter` factory.
`*.streams` configuration file
""""""""""""""""""""""""""""""
These files contain lists of streams with their names and priorities.
They are TOML v0.5 files.
Each `.streams` file must contain exactly one top-level array of tables,
called `streams`. Every table must contain a mandatory `name` field, and 2
optional fields: `priority` and `enable_control_port`.
The `name` of each stream is used to create the streams on new endpoints.
The `priority` of each stream is being interpreted by the policy module to
apply restrictions on which app can use the stream at a given time.
The `enable_control_port` is used to enable the control port of the stream.
module-config-policy
""""""""""""""""""""
This module implements demo-quality policy management that is partly driven
by configuration files. The configuration files that this module reads are
described below:
`*.endpoint-link`
"""""""""""""""""
These files contain rules to link endpoints with each other.
They are TOML v0.5 files.
Endpoints are normally created by another module, such
as `module-config-endpoint` which is described above.
As soon as an endpoint is created, the `module-config-policy` uses the
information gathered from the `.endpoint-link` files in order to create a
link to another endpoint.
`.endpoint-link` files can contain 3 top-level tables
* `[match-endpoint]`, required
* `[target-endpoint]`, optional
The `[match-endpoint]` table contains properties that match an endpoint that
exists on the graph. Possible fields of this table are
* `name`
Optional. The name of the endpoint. It is possible to use wildcards here to
match only parts of the name.
* `media_class`
Optional. A string that specifies the `media.class` that the endpoint
must have in order to match.
* `properties`
This is a TOML array of tables, where each table must contain two fields:
`name` and `value`, both being strings. Each table describes a match against
one of the pipewire properties of the endpoint. For a successful endpoint
match, all the described properties must match with the endpoint.
The `[target-endpoint]` table contains properties that match an endpoint that
exists on the graph. The purpose of this table is to match a second endpoint
that the original matching endpoint from `[match-endpoint]` will be linked to.
If not specified, `module-config-policy` will look for the session "default"
endpoint for the type of media that the matching endpoint produces or consumes
and will use that as a target. Possible fields of this table are
* `name`, `media_class`, `properties`
All these fields are permitted and behave exactly as described above for the
`[match-endpoint]` table.
* `stream`
This field specifies a stream name that the link will use on the target
endpoint. If it is not specified, the stream name is acquired from the
`media.role` property of the matching endpoint. If specified, the value of
this field overrides the `media.role`.
......@@ -10,7 +10,8 @@ Getting debug messages on the command line is a matter of setting the
WIREPLUMBER_DEBUG=level:category1,category2,...
``level`` can be a number from 1 to 5 and defines the minimum debug level to show:
``level`` can be one of ``CEWMIDT`` or a numerical log level as listed below.
In either case it defines the minimum debug level to show:
0. critical warnings and fatal errors (``C`` & ``E`` in the log)
1. warnings (``W``)
......@@ -50,13 +51,13 @@ Show all messages:
.. code::
WIREPLUMBER_DEBUG=5
WIREPLUMBER_DEBUG=D
Show all messages up to the *debug* level (E, C, W, M, I & D), excluding *trace*:
.. code::
WIREPLUMBER_DEBUG=4
WIREPLUMBER_DEBUG=M
Show all messages up to the *message* level (E, C, W & M),
excluding *info*, *debug* & *trace*
......@@ -70,13 +71,13 @@ Show all messages from the wireplumber library:
.. code::
WIREPLUMBER_DEBUG=5:wp-*
WIREPLUMBER_DEBUG=D:wp-*
Show all messages from ``wp-registry``, libpipewire and all modules:
.. code::
WIREPLUMBER_DEBUG=5:wp-registry,pw,m-*
WIREPLUMBER_DEBUG=D:wp-registry,pw,m-*
Relationship with the GLib log handler & G_MESSAGES_DEBUG
---------------------------------------------------------
......
......@@ -9,7 +9,7 @@ Table of Contents
installing-wireplumber.rst
running-wireplumber-daemon.rst
daemon-configuration.rst
configuration.rst
daemon-logging.rst
.. toctree::
......
......@@ -8,9 +8,9 @@ Dependencies
In order to compile WirePlumber you will need:
* GLib >= 2.58
* PipeWire 0.3 (>= 0.3.26)
* Lua 5.3
* GLib >= 2.62
* PipeWire 0.3 (>= 0.3.43)
* Lua 5.3 or 5.4
Lua is optional in the sense that if it is not found in the system, a bundled
version will be built and linked statically with WirePlumber. This is controlled
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment