mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-14 13:28:10 +02:00
docs: Replace hotdoc with Doxygen & Sphinx to generate documentation
This commit is contained in:
parent
3e6edcb02e
commit
89549247f8
20 changed files with 3313 additions and 550 deletions
|
|
@ -1 +0,0 @@
|
|||
# API reference
|
||||
78
docs/conf.py.in
Normal file
78
docs/conf.py.in
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'WirePlumber'
|
||||
copyright = '2020, Collabora'
|
||||
author = 'Collabora'
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '2020'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'breathe',
|
||||
]
|
||||
|
||||
breathe_projects = { "WirePlumber": "@BUILD_ROOT@/xml" }
|
||||
breathe_default_members = ('members', 'undoc-members')
|
||||
|
||||
breathe_default_project = "WirePlumber"
|
||||
|
||||
# Exclude '.c' extension from breathe_implementation_filename_extensions so that the documented code in C files is parsed and the ReStructured Text files are built from xml files
|
||||
breathe_implementation_filename_extensions = ['.cc', '.cpp']
|
||||
|
||||
# Let breathe know that our domain is 'C'
|
||||
breathe_domain_by_extension = {
|
||||
"h" : "c",
|
||||
"c" : "c",
|
||||
}
|
||||
|
||||
# See, https://breathe.readthedocs.io/en/latest/directives.html#config-values for more information
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Tell sphinx what the primary language being documented is.
|
||||
primary_domain = 'cpp'
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
# Testing
|
||||
|
||||
## Automated unit tests
|
||||
|
||||
WirePlumber has automated tests that you can easily run with:
|
||||
|
||||
```
|
||||
$ meson test -C build
|
||||
```
|
||||
|
||||
This will automatically compile all test dependencies, so you can be sure
|
||||
that this always tests your latest changes.
|
||||
|
||||
If you wish to run a specific test instead of all of them, you can run:
|
||||
```
|
||||
$ meson test -C build test-name
|
||||
```
|
||||
|
||||
When debugging a single test, you can additionally enable verbose test output
|
||||
by appending `-v` and you can also run the test in gdb by appending `--gdb`.
|
||||
|
||||
For more information on how to use `meson test`, please refer to
|
||||
[meson's manual](https://mesonbuild.com/Unit-tests.html)
|
||||
|
||||
> When submitting changes for review, always ensure that all tests pass
|
||||
|
||||
Please note that many WirePlumber tests require specific SPA test plugins
|
||||
to be available in your PipeWire installation. More specifically, PipeWire
|
||||
needs to be configured with the following options enabled:
|
||||
```
|
||||
-Dvideotestsrc=true -Daudiotestsrc=true -Dtest=true
|
||||
```
|
||||
If these SPA plugins are not found in the system, some tests will fail.
|
||||
This is expected.
|
||||
|
||||
## WirePlumber examples
|
||||
|
||||
WirePlumber ships examples in `test/examples`.
|
||||
Execute them from the top-level directory like this:
|
||||
|
||||
```
|
||||
$ WIREPLUMBER_MODULE_DIR=build/modules ./build/tests/examples/audiotestsrc-play
|
||||
```
|
||||
|
||||
Assuming there is no other process actively using `hw:0,0` from alsa, the above
|
||||
example should play a test tone on `hw:0,0` without errors.
|
||||
|
||||
## Native API clients
|
||||
|
||||
### pw-cat
|
||||
|
||||
Using the default endpoint:
|
||||
```
|
||||
$ wpctl status # verify the default endpoints
|
||||
$ pw-record test.wav
|
||||
$ pw-play test.wav
|
||||
```
|
||||
|
||||
Using a non-default endpoint:
|
||||
```
|
||||
$ pw-record --list-targets # find the node id
|
||||
$ pw-record --target <node_id> test.wav
|
||||
$ pw-play --list-targets # find the node id
|
||||
$ pw-play --target <node_id> test.wav
|
||||
```
|
||||
or
|
||||
```
|
||||
$ wpctl status # find the capture & playback endpoint ids
|
||||
$ pw-record --target <endpoint_id> test.wav
|
||||
$ pw-play --target <endpoint_id> test.wav
|
||||
```
|
||||
|
||||
> Note: node ids and endpoint ids can be used interchangeably when specifying
|
||||
targets in all use cases.
|
||||
|
||||
### video-play
|
||||
|
||||
Using the default endpoint:
|
||||
```
|
||||
$ cd path/to/pipewire-source-dir
|
||||
$ ./build/src/examples/video-play
|
||||
```
|
||||
|
||||
Using a non-default endpoint:
|
||||
```
|
||||
$ wpctl status # find the endpoint id from the list
|
||||
$ cd path/to/pipewire-source-dir
|
||||
$ ./build/src/examples/video-play <endpoint_id>
|
||||
```
|
||||
|
||||
> Tip: enable videotestsrc in wireplumber's configuration to have more video
|
||||
sources available (see `videotestsrc.node.disabled` in the configuration directory)
|
||||
|
||||
## PulseAudio compat API clients
|
||||
|
||||
### pacat
|
||||
|
||||
Using the default endpoint:
|
||||
```
|
||||
$ wpctl status # verify the default endpoints
|
||||
$ pw-pulse parecord test.wav
|
||||
$ pw-pulse paplay test.wav
|
||||
```
|
||||
|
||||
Using a non-default endpoint:
|
||||
```
|
||||
$ wpctl status # find the capture & playback endpoint ids
|
||||
$ PIPEWIRE_NODE=<endpoint_id> pw-pulse parecord test.wav
|
||||
$ PIPEWIRE_NODE=<endpoint_id> pw-pulse paplay test.wav
|
||||
```
|
||||
|
||||
### pavucontrol
|
||||
|
||||
```
|
||||
$ pw-pulse pavucontrol
|
||||
```
|
||||
* Volume level meters should work
|
||||
* Changing the volume should work
|
||||
|
||||
## ALSA compat API clients
|
||||
|
||||
### aplay / arecord
|
||||
|
||||
> Note: unless you have installed PipeWire in the default system prefix
|
||||
(`/usr`), the ALSA compat API will not work, unless you copy
|
||||
`libasound_module_pcm_pipewire.so` in the alsa plugins directory
|
||||
(usually `/usr/<libdir>/alsa-lib/`) and that you add the contents of
|
||||
`pipewire-alsa/conf/50-pipewire.conf` in your `~/.asoundrc`
|
||||
(or anywhere else, system-wide, where libasound can read it)
|
||||
|
||||
Using the default endpoint:
|
||||
```
|
||||
$ wpctl status # verify the default endpoints
|
||||
$ arecord -D pipewire -f S16_LE -r 48000 test.wav
|
||||
$ aplay -D pipewire test.wav
|
||||
```
|
||||
|
||||
Using a non-default endpoint:
|
||||
```
|
||||
$ wpctl status # find the capture & playback endpoint ids
|
||||
$ PIPEWIRE_NODE=<endpoint_id> arecord -D pipewire -f S16_LE -r 48000 test.wav
|
||||
$ PIPEWIRE_NODE=<endpoint_id> aplay -D pipewire test.wav
|
||||
```
|
||||
or
|
||||
```
|
||||
$ wpctl status # find the capture & playback endpoint ids
|
||||
$ arecord -D pipewire:NODE=<endpoint_id> -f S16_LE -r 48000 test.wav
|
||||
$ aplay -D pipewire:NODE=<endpoint_id> test.wav
|
||||
```
|
||||
|
||||
## JACK compat API clients
|
||||
|
||||
### qjackctl
|
||||
|
||||
```
|
||||
pw-jack qjackctl
|
||||
```
|
||||
* This should correctly connect.
|
||||
* The "Graph" window should show the PipeWire graph.
|
||||
|
||||
### jack_simple_client
|
||||
|
||||
```
|
||||
$ wpctl status # find the target endpoint id
|
||||
$ wpctl inspect <endpoint_id> # find the node.id
|
||||
$ PIPEWIRE_NODE=<node_id> pw-jack jack_simple_client
|
||||
```
|
||||
|
||||
> The JACK layer is not controlled by the session manager, it creates its own
|
||||
links; which is why it is required to specify a node id (endpoint id will not
|
||||
work)
|
||||
|
||||
## Device Reservation
|
||||
|
||||
### with PulseAudio
|
||||
|
||||
1. With PulseAudio running, start a pulseaudio client:
|
||||
```
|
||||
gst-launch-1.0 audiotestsrc ! pulsesink
|
||||
```
|
||||
2. Start PipeWire & WirePlumber
|
||||
- The device in use by PA will not be available in PW
|
||||
3. Stop the PA client
|
||||
- A few seconds later, WirePlumber should assume control of the device
|
||||
4. `wpctl status` should be able to confirm that the device is available
|
||||
5. Start a PA client again
|
||||
- It should not be able to play; it will just freeze
|
||||
6. Stop WirePlumber
|
||||
- The PA client should immediately start playing
|
||||
|
||||
### with JACK
|
||||
|
||||
1. Start PipeWire & WirePlumber
|
||||
- All devices should be available
|
||||
2. Start `jackdbus`
|
||||
- through `qjackctl`:
|
||||
- Enable `Setup` -> `Misc` -> `Enable JACK D-Bus interface`
|
||||
- Click `Start` on the main window
|
||||
- or manually:
|
||||
- Run `jackdbus auto`
|
||||
- Run `qdbus org.jackaudio.service /org/jackaudio/Controller org.jackaudio.JackControl.StartServer`
|
||||
3. Wait a few seconds and run `wpctl status` to inspect
|
||||
- The devices taken by JACK should no longer be available
|
||||
- There should be two `JACK System` endpoints (sink & source)
|
||||
4. Run an audio client on PipeWire (ex `pw-play test.wav`)
|
||||
- Notice how audio now goes through JACK
|
||||
5. Stop JACK
|
||||
- through `qjackctl`, click `Stop`
|
||||
- or manually: `qdbus org.jackaudio.service /org/jackaudio/Controller org.jackaudio.JackControl.StopServer`
|
||||
6. Wait a few seconds and run `wpctl status` to inspect
|
||||
- The devices that were release by JACK should again be available
|
||||
- There should be no `JACK System` endpoint
|
||||
|
||||
> You may also start WirePlumber *after* starting JACK. It should immediately
|
||||
go to the state described in step 3
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
# Running the WirePlumber Daemon
|
||||
|
||||
## Configure PipeWire
|
||||
|
||||
PipeWire 0.3 comes with an example session manager that you will need
|
||||
to disable and replace with WirePlumber. This can be achieved by editing
|
||||
`src/daemon/pipewire.conf.in` in the PipeWire git tree or
|
||||
`/etc/pipewire/pipewire.conf` in an existing installation:
|
||||
|
||||
```
|
||||
diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in
|
||||
index cebded96..dee1743b 100644
|
||||
--- a/src/daemon/pipewire.conf.in
|
||||
+++ b/src/daemon/pipewire.conf.in
|
||||
@@ -99,7 +99,8 @@ exec = {
|
||||
# Start the session manager. Run the session manager with -h for
|
||||
# options.
|
||||
#
|
||||
- "@media_session_path@" = { args = ""}
|
||||
+ #"@media_session_path@" = { args = ""}
|
||||
+ "wireplumber" = {}
|
||||
#
|
||||
# You can optionally start the pulseaudio-server here as well
|
||||
# but it better to start it as a systemd service.
|
||||
```
|
||||
|
||||
This setup assumes that WirePlumber is *installed* on the target system.
|
||||
|
||||
## Run independently or without installing
|
||||
|
||||
If you wish to debug WirePlumber, it may be useful to run it separately from
|
||||
PipeWire or run it directly from the source tree without installing.
|
||||
To do so:
|
||||
|
||||
1. Comment out with `#` the `"wireplumber" = {}` line from `pipewire.conf`
|
||||
2. Run pipewire:
|
||||
- if it is installed, execute `pipewire`
|
||||
- if it is **not** installed, execute `make run` in the **pipewire** source tree
|
||||
3. Without stopping pipewire, run wireplumber:
|
||||
- if it is installed, execute `wireplumber`
|
||||
- if it is **not** installed, execute `make run` in the **wireplumber** source tree
|
||||
2511
docs/doxyfile.in
Normal file
2511
docs/doxyfile.in
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,32 +0,0 @@
|
|||
# WirePlumber
|
||||
|
||||
WirePlumber is a modular session / policy manager for
|
||||
[PipeWire](https://pipewire.org) and a GObject-based high-level library
|
||||
that wraps PipeWire's API, providing convenience for writing the daemon's
|
||||
modules as well as external tools for managing PipeWire.
|
||||
|
||||
* [Installing WirePlumber](installation/from-source.md)
|
||||
|
||||
## The WirePlumber Daemon
|
||||
|
||||
The WirePlumber daemon implements the session & policy management service.
|
||||
It follows a modular design, having plugins that implement the actual
|
||||
management functionality.
|
||||
|
||||
* [Running the WirePlumber Daemon](daemon/running.md)
|
||||
* [Daemon Configuration](daemon/configuration.md)
|
||||
* [Debug Logging](daemon/log.md)
|
||||
|
||||
## The WirePlumber Library
|
||||
|
||||
The WirePlumber Library provides API that allows you
|
||||
to extend the WirePlumber daemon, to write management or status tools
|
||||
for PipeWire (apps that don't do actual media streaming)
|
||||
and to write custom session managers for embedded devices.
|
||||
|
||||
* [API Reference](gi-index)
|
||||
|
||||
## Resources
|
||||
|
||||
* [Contribute to WirePlumber](contributing/contributing.md)
|
||||
* [Reach out to the community](community.md)
|
||||
54
docs/index.rst
Normal file
54
docs/index.rst
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
Wireplumber
|
||||
===========
|
||||
|
||||
WirePlumber is a modular session / policy manager for `PipeWire <https://pipewire.org>`_ and a GObject-based high-level library that wraps PipeWire's API, providing convenience for writing the daemon's modules as well as external tools for managing PipeWire.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Contents:
|
||||
|
||||
toc/installing-wireplumber.rst
|
||||
toc/running-wireplumber-daemon.rst
|
||||
toc/daemon-configuration.rst
|
||||
toc/daemon-logging.rst
|
||||
toc/contributing.rst
|
||||
toc/community.rst
|
||||
toc/testing.rst
|
||||
api/library_root.rst
|
||||
|
||||
The WirePlumber Daemon
|
||||
----------------------
|
||||
|
||||
The WirePlumber daemon implements the session & policy management service. It follows a modular design, having plugins that implement the actual management functionality.
|
||||
|
||||
* :ref:`running-wireplumber-daemon`
|
||||
* :ref:`daemon-configuration`
|
||||
* :ref:`logging`
|
||||
|
||||
The WirePlumber library
|
||||
-----------------------
|
||||
|
||||
The WirePlumber Library provides API that allows you to extend the WirePlumber daemon, to write management or status tools for PipeWire (apps that don't do actual media streaming) and to write custom session managers for embedded devices.
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* :ref:`contributing`
|
||||
* :ref:`testing`
|
||||
* :ref:`community`
|
||||
|
||||
Subpages
|
||||
--------
|
||||
|
||||
* :ref:`installing-wireplumber`
|
||||
* :ref:`running-wireplumber-daemon`
|
||||
* :ref:`daemon-configuration`
|
||||
* :ref:`contributing`
|
||||
* :ref:`testing`
|
||||
* :ref:`community`
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
# Installing WirePlumber
|
||||
|
||||
## Dependencies
|
||||
|
||||
In order to compile WirePlumber you will need:
|
||||
|
||||
* GLib >= 2.58
|
||||
* PipeWire 0.3 (>= 0.3.5 highly recommended)
|
||||
|
||||
For building gobject-introspection data, you will also need `g-ir-scanner`,
|
||||
which is usually shipped together with the gobject-introspection development
|
||||
files.
|
||||
|
||||
For building documentation, you will also need [hotdoc](https://hotdoc.github.io/).
|
||||
Most distributions do not ship this, but you can install it easily using python's
|
||||
`pip` package manager.
|
||||
|
||||
## Compilation
|
||||
|
||||
WirePlumber uses the [meson build system](https://mesonbuild.com/).
|
||||
|
||||
To configure the project, you need to first run `meson`.
|
||||
The basic syntax is shown below:
|
||||
```
|
||||
meson [build directory] [source directory] [--prefix=/path] [...options...]
|
||||
```
|
||||
|
||||
Assuming you want to build in a directory called `build` inside the source
|
||||
tree, you can run:
|
||||
```
|
||||
$ meson build . --prefix=/usr
|
||||
$ ninja -C build
|
||||
```
|
||||
|
||||
### Additional options
|
||||
|
||||
- `-Dintrospection=[enabled|disabled|auto]`: Force enable or force disable
|
||||
building gobject-introspection data. The default value is `auto`, which means
|
||||
that g-i will be built if `g-ir-scanner` is found and skipped otherwise.
|
||||
- `-Ddocs=[enabled|disabled|auto]`: Force enable or force disable building
|
||||
documentation. The default value is `auto`, which means that documentation
|
||||
will be built if `hotdoc` is found and skipped otherwise. Note that building
|
||||
the documentation also requires gobject-introspection data to be built.
|
||||
|
||||
## Installation
|
||||
|
||||
To install, simply run the `install` target with ninja:
|
||||
```
|
||||
$ ninja -C build install
|
||||
```
|
||||
|
||||
To revert the installation, there is also an `uninstall` target:
|
||||
```
|
||||
$ ninja -C build uninstall
|
||||
```
|
||||
136
docs/meson.build
136
docs/meson.build
|
|
@ -1,42 +1,120 @@
|
|||
hotdoc_p = find_program('hotdoc', required: get_option('doc'))
|
||||
if not hotdoc_p.found()
|
||||
message('Hotdoc not found, not building the documentation')
|
||||
sphinx_p = find_program('sphinx-build', required: get_option('doc'))
|
||||
if not sphinx_p.found()
|
||||
message('Sphinx not found, not building the documentation')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
hotdoc = import('hotdoc')
|
||||
required_hotdoc_extensions = ['gi-extension']
|
||||
foreach extension: required_hotdoc_extensions
|
||||
if not hotdoc.has_extensions(extension)
|
||||
if get_option('doc').enabled()
|
||||
error('Documentation enabled but @0@ missing'.format(extension))
|
||||
endif
|
||||
doxygen_p = find_program('doxygen', required: get_option('doc'))
|
||||
if not doxygen_p.found()
|
||||
message('Doxygen not found, not building the documentation')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
message('@0@ extension not found, not building documentation'.format(extension))
|
||||
subdir_done()
|
||||
endif
|
||||
endforeach
|
||||
breathe_p = find_program('breathe-apidoc', required: get_option('doc'))
|
||||
if not breathe_p.found()
|
||||
message('Breathe not found, not building the documentation')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
sphinx_c = run_command(sphinx_p, '--version')
|
||||
breathe_c = run_command(breathe_p, '--version')
|
||||
doxygen_c = run_command(doxygen_p, '--version')
|
||||
|
||||
sphinx_v = sphinx_c.stdout().split(' ')[1].strip()
|
||||
breathe_v = breathe_c.stdout().split(' ')[2].strip()
|
||||
doxygen_v = doxygen_c.stdout().strip()
|
||||
|
||||
if sphinx_v.version_compare('< 2.1.0')
|
||||
error('Use at least sphinx version 2.1.0, found ' + sphinx_v)
|
||||
endif
|
||||
|
||||
if breathe_v.version_compare('< 4.11')
|
||||
error('Use at least breathe version 4.11, found ' + breathe_v)
|
||||
endif
|
||||
|
||||
if doxygen_v.version_compare('< 1.8')
|
||||
error('Use at least doxygen version 1.8, found ' + doxygen_v)
|
||||
endif
|
||||
|
||||
if not build_gir
|
||||
if get_option('doc').enabled()
|
||||
error('Documentation enabled but introspection not built.')
|
||||
endif
|
||||
|
||||
message('Introspection not built, can\'t build the documentation')
|
||||
subdir_done()
|
||||
# message('Introspection not built, can\'t build the documentation')
|
||||
# subdir_done()
|
||||
endif
|
||||
|
||||
wp_doc = hotdoc.generate_doc('wireplumber',
|
||||
project_version: wireplumber_api_version,
|
||||
sitemap: 'sitemap.txt',
|
||||
index: 'index.md',
|
||||
gi_index: 'api-reference.md',
|
||||
gi_smart_index: true,
|
||||
gi_sources: [wp_gir[0].full_path()],
|
||||
gi_c_sources: [wp_lib_sources, wp_lib_headers, wpenums_c, wpenums_h],
|
||||
gi_c_source_roots: [join_paths(meson.current_source_dir(), '../lib/wp/'), ],
|
||||
languages: ['c'],
|
||||
dependencies: [wp_dep],
|
||||
build_by_default: true,
|
||||
install: true,
|
||||
doxygen_database = meson.current_build_dir() + '/doxygen_doc'
|
||||
|
||||
# modify the sphinx configuration and the breathe doxygen XML database
|
||||
# to point where its being generated by doxygen
|
||||
sphinx_conf_data = configuration_data()
|
||||
sphinx_conf_data.set('BUILD_ROOT', doxygen_database)
|
||||
sphinx_conf_data.set('VERSION', meson.project_version())
|
||||
sphinx_conf = configure_file(
|
||||
input: 'conf.py.in',
|
||||
output: 'conf.py',
|
||||
configuration: sphinx_conf_data
|
||||
)
|
||||
|
||||
doxy_conf_data = configuration_data()
|
||||
doxy_conf_data.set('SRC_ROOT', meson.source_root())
|
||||
doxy_conf_data.set('OUTPUT_DIR', doxygen_database)
|
||||
doxygen_conf_wireplumber = configure_file(
|
||||
input: 'doxyfile.in',
|
||||
output: 'doxyfile',
|
||||
configuration: doxy_conf_data
|
||||
)
|
||||
|
||||
dir_prefix = get_option('prefix')
|
||||
dir_data = join_paths(dir_prefix, get_option('datadir'))
|
||||
|
||||
script_data = configuration_data()
|
||||
script_data.set('SRCDIR', meson.current_build_dir())
|
||||
script_data.set('OUTDIR', meson.current_build_dir() + '/docs')
|
||||
script_data.set('DOXYGEN_CONF', meson.current_build_dir() + '/doxyfile')
|
||||
|
||||
# Set a different directory for doctrees to avoid installing them
|
||||
script_data.set('DOCTREES_DIR', meson.current_build_dir() + '/doctrees')
|
||||
|
||||
script_data.set('DOXYGEN_CMD', doxygen_p.path())
|
||||
script_data.set('SPHINX_CMD', sphinx_p.path())
|
||||
script_doxy_sphinx = configure_file(
|
||||
input: 'run_doxygen_sphinx.sh.in',
|
||||
output: 'run_doxygen_sphinx.sh',
|
||||
configuration: script_data
|
||||
)
|
||||
|
||||
# copy everything to build_dir, if you plan on adding other files in the top
|
||||
# rootdir of sourcedir, please add them here as well, otherwise use 'toc/'s
|
||||
# meson.build file
|
||||
|
||||
sphinx_files = ['index.rst']
|
||||
foreach file : sphinx_files
|
||||
configure_file(input: file, output: file, copy: true)
|
||||
endforeach
|
||||
|
||||
# and those in toc
|
||||
subdir('toc')
|
||||
|
||||
sphinx_doc = custom_target(
|
||||
'breathe',
|
||||
command: script_doxy_sphinx,
|
||||
output: 'docs',
|
||||
build_by_default: true,
|
||||
)
|
||||
|
||||
# we need this because we will have a stale 'docs' directory
|
||||
# and this forces it to be rebuilt
|
||||
docs = run_target(
|
||||
'docs',
|
||||
command: script_doxy_sphinx,
|
||||
)
|
||||
|
||||
install_subdir(
|
||||
sphinx_doc.full_path(),
|
||||
install_dir: join_paths(dir_data, 'doc', 'wireplumber', 'html'),
|
||||
exclude_files: '.buildinfo',
|
||||
strip_directory: true,
|
||||
)
|
||||
|
|
|
|||
5
docs/requirements.txt
Normal file
5
docs/requirements.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
bs4 # BeautifulSoup!
|
||||
lxml # We need the lxml backend for BeautifulSoup.
|
||||
sphinx>=1.6.1 # 1.6 introduces logging API.
|
||||
breathe # The directives used for documentation come from the excellent Breathe.
|
||||
six # Primarily for Unicode string types
|
||||
2
docs/run_doxygen_sphinx.sh.in
Executable file
2
docs/run_doxygen_sphinx.sh.in
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
@DOXYGEN_CMD@ @DOXYGEN_CONF@ && @SPHINX_CMD@ -E -Q -j auto -d @DOCTREES_DIR@ @SRCDIR@ @OUTDIR@
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
index.md
|
||||
installation/from-source.md
|
||||
daemon/running.md
|
||||
daemon/configuration.md
|
||||
daemon/log.md
|
||||
gi-index
|
||||
contributing/contributing.md
|
||||
contributing/testing.md
|
||||
community.md
|
||||
|
|
@ -1,20 +1,26 @@
|
|||
# Community Resources
|
||||
.. _community:
|
||||
|
||||
## Discussion chat channel
|
||||
Community Resources
|
||||
===================
|
||||
|
||||
Discussion chat channel
|
||||
-----------------------
|
||||
|
||||
WirePlumber does not have its own discussion channel, but you can ask questions
|
||||
in the generic `#pipewire` IRC channel (on irc.freenode.org or
|
||||
`#freenode_#pipewire:matrix.org` if you are joining via matrix)
|
||||
|
||||
## Mailing list
|
||||
Mailing list
|
||||
------------
|
||||
|
||||
For discussions related to PipeWire **development**, there is
|
||||
[the pipewire-devel mailing list](https://lists.freedesktop.org/mailman/listinfo/pipewire-devel)
|
||||
`the pipewire devel mailing list <https://lists.freedesktop.org/mailman/listinfo/pipewire-devel>`_
|
||||
|
||||
## Reporting issues
|
||||
Reporting issues
|
||||
----------------
|
||||
|
||||
If you have found an issue with WirePlumber and wish to report it,
|
||||
please create a ticket on gitlab,
|
||||
[here](https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues)
|
||||
`here <https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues>`_
|
||||
|
||||
Please always check that your issue is not already reported before reporting it.
|
||||
|
|
@ -1,37 +1,43 @@
|
|||
# Contributing to WirePlumber
|
||||
.. _contributing:
|
||||
|
||||
## Coding style
|
||||
Contributing to WirePlumber
|
||||
===========================
|
||||
|
||||
Coding style
|
||||
------------
|
||||
|
||||
WirePlumber uses the
|
||||
[GNOME C Coding Style](https://developer.gnome.org/programming-guidelines/unstable/c-coding-style.html.en)
|
||||
`GNOME C Coding Style <https://developer.gnome.org/programming-guidelines/unstable/c-coding-style.html.en>`_
|
||||
with K&R brace placement and 2-space indentation, similar to
|
||||
[GStreamer](https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/developing.html#what-is-the-coding-style-for-gstreamer-code).
|
||||
`GStreamer <https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/developing.html#what-is-the-coding-style-for-gstreamer-code>`_.
|
||||
When in doubt, just follow the example of the existing code.
|
||||
|
||||
WirePlumber ships with a [.editorconfig](https://editorconfig.org/) file.
|
||||
WirePlumber ships with a `editorconfig <https://editorconfig.org/>`_ file.
|
||||
If your code editor / IDE supports this, it should automatically set up
|
||||
the indentation settings.
|
||||
|
||||
> When submitting changes for review, please ensure that the coding style
|
||||
of the changes respects the coding style of the project
|
||||
* When submitting changes for review, please ensure that the coding style of the changes respects the coding style of the project.
|
||||
|
||||
## Tests
|
||||
Tests
|
||||
^^^^^
|
||||
|
||||
See [Testing](contributing/testing.md)
|
||||
See
|
||||
:ref:`testing`
|
||||
|
||||
## Running in gdb / valgrind / etc...
|
||||
Running in gdb / valgrind / etc...
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The Makefile included with WirePlumber supports the `gdb` and `valgrind`
|
||||
targets. So, instead of `make run` you can do `make gdb` or `make valgrind`
|
||||
to do some debugging.
|
||||
|
||||
You can also run in any other wrapper by setting the `DBG` variable
|
||||
on `make run`. For example:
|
||||
```
|
||||
$ make run DBG="strace"
|
||||
```
|
||||
on `make run`. For example::
|
||||
|
||||
## Merge requests
|
||||
$ make run DBG="strace"
|
||||
|
||||
Merge requests
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
In order to submit changes to the project, you should create a merge request.
|
||||
To do this,
|
||||
|
|
@ -49,4 +55,4 @@ so that maintainers are able to rebase your branch, since WirePlumber uses
|
|||
a fast-forward merge policy.
|
||||
|
||||
For more detailed information, check out
|
||||
[gitlab's manual on merge requests](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
||||
`gitlabs manual on merge requests <https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html>`_
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
# Configuration
|
||||
.. _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
|
||||
|
|
@ -9,92 +12,92 @@ 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`
|
||||
*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:
|
||||
The format of this file is custom and resembles a script with commands::
|
||||
|
||||
```
|
||||
# comment
|
||||
command parameter1 parameter2 ...
|
||||
```
|
||||
*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:
|
||||
action defined by the command. Lines starting with *#* are treated as comments
|
||||
and ignored. Possible commands are
|
||||
|
||||
* `add-spa-lib`
|
||||
* *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.
|
||||
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`
|
||||
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).
|
||||
add-spa-lib api.alsa.* alsa/libspa-alsa
|
||||
|
||||
* `load-pipewire-module`
|
||||
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).
|
||||
|
||||
Loads a `libpipewire` module. This is similar to the `load-module` commands
|
||||
that would appear on `pipewire.conf`, the configuration file of the PipeWire
|
||||
* *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`
|
||||
arguments, in the format that they would be given in *pipewire.conf*
|
||||
|
||||
Format:
|
||||
```
|
||||
load-pipewire-module module-name some-argument some-property=value
|
||||
```
|
||||
::
|
||||
|
||||
load-pipewire-module module-name some-argument some-property=value
|
||||
|
||||
Example:
|
||||
```
|
||||
load-pipewire-module libpipewire-module-client-device
|
||||
```
|
||||
::
|
||||
|
||||
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
|
||||
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`
|
||||
* *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
|
||||
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`
|
||||
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)
|
||||
`GVariant <https://developer.gnome.org/glib/stable/glib-GVariant.html>`_
|
||||
of type
|
||||
[`a{sv}`](https://developer.gnome.org/glib/stable/gvariant-format-strings.html)
|
||||
`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).
|
||||
`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
|
||||
|
|
@ -104,17 +107,18 @@ and ignored. Possible commands are:
|
|||
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"]>}>
|
||||
}
|
||||
```
|
||||
::
|
||||
|
||||
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
|
||||
Location of configuration files
|
||||
-------------------------------
|
||||
|
||||
WirePlumber's default location of its configuration files is determined at
|
||||
compile time by the build system. Typically, it ends up being `/etc/wireplumber`.
|
||||
|
|
@ -127,22 +131,21 @@ is prepended to the path: `$prefix/$sysconfdir/wireplumber`
|
|||
|
||||
WirePlumber expects its `wireplumber.conf` to reside in that directory.
|
||||
It is possible to override that at runtime by setting the
|
||||
`WIREPLUMBER_CONFIG_FILE` environment variable:
|
||||
`WIREPLUMBER_CONFIG_FILE` environment variable::
|
||||
|
||||
```
|
||||
WIREPLUMBER_CONFIG_FILE=src/config/wireplumber.conf wireplumber
|
||||
```
|
||||
WIREPLUMBER_CONFIG_FILE=src/config/wireplumber.conf wireplumber
|
||||
|
||||
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
|
||||
```
|
||||
by setting the `WIREPLUMBER_CONFIG_DIR` environment variable::
|
||||
|
||||
## Location of modules
|
||||
WIREPLUMBER_CONFIG_DIR=src/config wireplumber
|
||||
|
||||
### WirePlumber modules
|
||||
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
|
||||
|
|
@ -153,15 +156,15 @@ 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`.
|
||||
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
|
||||
```
|
||||
`WIREPLUMBER_MODULE_DIR` environment variable::
|
||||
|
||||
### PipeWire and SPA modules
|
||||
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.
|
||||
|
|
@ -170,7 +173,8 @@ 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
|
||||
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
|
||||
|
|
@ -183,14 +187,14 @@ 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:
|
||||
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:
|
||||
Well-known factories are
|
||||
|
||||
* "api.alsa.enum.udev" - Discovers ALSA devices via udev
|
||||
* "api.v4l2.enum.udev" - Discovers V4L2 devices via udev
|
||||
|
|
@ -199,7 +203,7 @@ for this instance. Possible instance parameters are:
|
|||
* `flags`
|
||||
|
||||
An array of strings that enable specific functionality in the monitor.
|
||||
Possible flags include:
|
||||
Possible flags include
|
||||
|
||||
* "use-adapter"
|
||||
|
||||
|
|
@ -221,10 +225,11 @@ for this instance. Possible instance parameters are:
|
|||
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
|
||||
module-config-endpoint
|
||||
""""""""""""""""""""""
|
||||
|
||||
This module creates endpoints when WirePlumber detects new nodes in the
|
||||
pipewire graph. Nodes themselves can be created in two ways:
|
||||
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,
|
||||
|
|
@ -234,13 +239,14 @@ 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
|
||||
`*.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:
|
||||
exists on the graph. Possible fields of this table are
|
||||
|
||||
* `properties`
|
||||
|
||||
|
|
@ -255,32 +261,26 @@ exists on the graph. Possible fields of this table are:
|
|||
[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:
|
||||
device node properties is::
|
||||
|
||||
```
|
||||
$ wireplumber-cli device-node-props
|
||||
```
|
||||
$ 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:
|
||||
is interpreted as follows::
|
||||
|
||||
```
|
||||
card 0: PCH [HDA Intel PCH], device 2: ALC3246 [ALC3246 Analog]
|
||||
```
|
||||
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" },
|
||||
```
|
||||
{ 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:
|
||||
The `[endpoint]` table contains a description of the endpoint to be created.
|
||||
Possible fields of this table are
|
||||
|
||||
* `session`
|
||||
|
||||
|
|
@ -290,8 +290,8 @@ Possible fields of this table are:
|
|||
* `type`
|
||||
|
||||
Required. Specifies the factory to be used for construction.
|
||||
The only well-known factories at the moment of writing is: `si-audio-adapter`
|
||||
and `si-simple-node-edpoint`.
|
||||
The only well-known factories at the moment of writing is `si-adapter` and
|
||||
`si-simple-node-edpoint`.
|
||||
|
||||
* `streams`
|
||||
|
||||
|
|
@ -303,7 +303,7 @@ Possible fields of this table are:
|
|||
* `config`
|
||||
|
||||
Optional. Specifies the configuration table used to configure the endpoint.
|
||||
This table can have the following entries:
|
||||
This table can have the following entries
|
||||
|
||||
* `name`
|
||||
|
||||
|
|
@ -347,9 +347,10 @@ Possible fields of this table are:
|
|||
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-audio-adapter` factory.
|
||||
with the `si-adapter` factory.
|
||||
|
||||
## `*.streams` configuration files
|
||||
`*.streams` configuration file
|
||||
""""""""""""""""""""""""""""""
|
||||
|
||||
These files contain lists of streams with their names and priorities.
|
||||
They are TOML v0.5 files.
|
||||
|
|
@ -365,13 +366,15 @@ 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
|
||||
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`
|
||||
`*.endpoint-link`
|
||||
"""""""""""""""""
|
||||
|
||||
These files contain rules to link endpoints with each other.
|
||||
They are TOML v0.5 files.
|
||||
|
|
@ -382,12 +385,12 @@ 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:
|
||||
`.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:
|
||||
exists on the graph. Possible fields of this table are
|
||||
|
||||
* `name`
|
||||
|
||||
|
|
@ -411,7 +414,7 @@ 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:
|
||||
and will use that as a target. Possible fields of this table are
|
||||
|
||||
* `name`, `media_class`, `properties`
|
||||
|
||||
|
|
@ -1,66 +1,64 @@
|
|||
# Debug Logging
|
||||
.. _logging:
|
||||
|
||||
Debug Logging
|
||||
=============
|
||||
|
||||
Getting debug messages on the command line is a matter of setting the
|
||||
`WIREPLUMBER_DEBUG` environment variable. The generic syntax is:
|
||||
```
|
||||
WIREPLUMBER_DEBUG=level:category1,category2,...
|
||||
```
|
||||
`WIREPLUMBER_DEBUG` environment variable. The generic syntax is::
|
||||
|
||||
`level` can be a number from 1 to 5 and defines the minimum debug level to show:
|
||||
- 1 - warnings, critical warnings and fatal errors (`W`, `C` & `E` in the log)
|
||||
- 2 - normal messages (`M`)
|
||||
- 3 - informational messages (`I`)
|
||||
- 4 - debug messages (`D`)
|
||||
- 5 - trace messages (`T`)
|
||||
WIREPLUMBER_DEBUG=level:category1,category2,...
|
||||
|
||||
`level` can be a number from 1 to 5 and defines the minimum debug level to show::
|
||||
1 - warnings, critical warnings and fatal errors (`W`, `C` & `E` in the log)
|
||||
2 - normal messages (`M`)
|
||||
3 - informational messages (`I`)
|
||||
4 - debug messages (`D`)
|
||||
5 - trace messages (`T`)
|
||||
|
||||
`category1,category2,...` is an *optional* comma-separated list of debug
|
||||
categories to show. Any categories not listed here will not appear in the log.
|
||||
If no categories are specified, then all messages are printed.
|
||||
Categories support [glob-style patterns](https://developer.gnome.org/glib/stable/glib-Glob-style-pattern-matching.html)
|
||||
Categories support `glob style patterns <https://developer.gnome.org/glib/stable/glib-Glob-style-pattern-matching.html>`_
|
||||
containing '*' and '?', for convenience.
|
||||
|
||||
Well known categories include:
|
||||
- `wireplumber`: messages from the wireplumber daemon
|
||||
- `pw`: messages from libpipewire & spa plugins
|
||||
- `wp-*`: messages from libwireplumber
|
||||
- `wp-core`: messages from `WpCore`
|
||||
- `wp-proxy`: messages from `WpProxy`
|
||||
- ... and so on ...
|
||||
- `m-*`: messages from wireplumber modules
|
||||
- `m-monitor`: messages from `libwireplumber-module-monitor`
|
||||
- `m-session-settings`: messages from `libwireplumber-module-session-settings`
|
||||
- ... and so on ...
|
||||
|
||||
## Examples
|
||||
* **wireplumber**: messages from the wireplumber daemon
|
||||
* **pw**: messages from libpipewire & spa plugins
|
||||
* **wp-***: messages from libwireplumber
|
||||
* **wp-core**: messages from `WpCore`
|
||||
* **wp-proxy**: messages from `WpProxy` ... and so on ...
|
||||
* **m-***: messages from wireplumber modules
|
||||
* **m-monitor**: messages from `libwireplumber-module-monitor`
|
||||
* **m-session-settings**: messages from `libwireplumber-module-session-settings` ... and so on ...
|
||||
|
||||
Show all messages
|
||||
```
|
||||
WIREPLUMBER_DEBUG=5
|
||||
```
|
||||
Examples
|
||||
--------
|
||||
|
||||
Show all messages up to the `debug` level (E, C, W, M, I & D), excluding `trace`
|
||||
```
|
||||
WIREPLUMBER_DEBUG=4
|
||||
```
|
||||
Show all messages::
|
||||
|
||||
WIREPLUMBER_DEBUG=5
|
||||
|
||||
Show all messages up to the `debug` level (E, C, W, M, I & D), excluding `trace` ::
|
||||
|
||||
WIREPLUMBER_DEBUG=4
|
||||
|
||||
Show all messages up to the `message` level (E, C, W & M),
|
||||
excluding `info`, `debug` & `trace`
|
||||
(this is also the default when `WIREPLUMBER_DEBUG` is omitted)
|
||||
```
|
||||
WIREPLUMBER_DEBUG=2
|
||||
```
|
||||
(this is also the default when `WIREPLUMBER_DEBUG` is omitted) ::
|
||||
|
||||
Show all messages from the wireplumber library
|
||||
```
|
||||
WIREPLUMBER_DEBUG=5:wp-*
|
||||
```
|
||||
WIREPLUMBER_DEBUG=2
|
||||
|
||||
Show all messages from `wp-registry`, libpipewire and all modules
|
||||
```
|
||||
WIREPLUMBER_DEBUG=5:wp-registry,pw,m-*
|
||||
```
|
||||
Show all messages from the wireplumber library ::
|
||||
|
||||
## Relationship with the GLib log handler & G_MESSAGES_DEBUG
|
||||
WIREPLUMBER_DEBUG=5:wp-*
|
||||
|
||||
Show all messages from `wp-registry`, libpipewire and all modules ::
|
||||
|
||||
WIREPLUMBER_DEBUG=5:wp-registry,pw,m-*
|
||||
|
||||
Relationship with the GLib log handler & G_MESSAGES_DEBUG
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Older versions of WirePlumber used to use `G_MESSAGES_DEBUG` to control their
|
||||
log output, which is the environment variable that affects GLib's default
|
||||
|
|
@ -73,7 +71,8 @@ If you are writing your own application based on libwireplumber, you can choose
|
|||
if you want to replace this log handler using the flags passed to
|
||||
[wp_init()](wp_init).
|
||||
|
||||
## Relationship with the PipeWire log handler & PIPEWIRE_DEBUG
|
||||
Relationship with the PipeWire log handler & PIPEWIRE_DEBUG
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
libpipewire uses the `PIPEWIRE_DEBUG` environment variable, with a similar syntax.
|
||||
WirePlumber replaces the log handler of libpipewire with its own, rendering
|
||||
|
|
@ -82,4 +81,4 @@ WirePlumber replaces the log handler of libpipewire with its own, rendering
|
|||
|
||||
If you are writing your own application based on libwireplumber, you can choose
|
||||
if you want to replace this log handler using the flags passed to
|
||||
[wp_init()](wp_init).
|
||||
[wp_init()](wp_init).
|
||||
59
docs/toc/installing-wireplumber.rst
Normal file
59
docs/toc/installing-wireplumber.rst
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
.. _installing-wireplumber:
|
||||
|
||||
Installing WirePlumber
|
||||
======================
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
In order to compile WirePlumber you will need:
|
||||
|
||||
* GLib >= 2.58
|
||||
* PipeWire 0.3 (>= 0.3.5 highly recommended)
|
||||
|
||||
For building gobject-introspection data, you will also need 'g-ir-scanner',
|
||||
which is usually shipped together with the gobject-introspection development
|
||||
files.
|
||||
|
||||
For building documentation, you will also need `doxygen <https://www.doxygen.nl/>`_,
|
||||
`Sphinx <https://pypi.org/project/Sphinx/>`_ and `breathe <https://pypi.org/project/breathe/>`_.
|
||||
Most distributions do not ship these tools, but you can install them easily using python's
|
||||
**pip** package manager.
|
||||
|
||||
Compilation
|
||||
-----------
|
||||
|
||||
WirePlumber uses the `meson build system <https://mesonbuild.com/>`_
|
||||
|
||||
To configure the project, you need to first run `meson`.
|
||||
The basic syntax is shown below:
|
||||
|
||||
*meson [build directory] [source directory] [--prefix=/path] [...options...]*
|
||||
|
||||
Assuming you want to build in a directory called 'build' inside the source
|
||||
tree, you can run:
|
||||
|
||||
*$ meson build . --prefix=/usr*
|
||||
*$ ninja -C build*
|
||||
|
||||
Additional options
|
||||
------------------
|
||||
|
||||
* **-Dintrospection=[enabled|disabled|auto]**: Force enable or force disable
|
||||
building gobject-introspection data. The default value is **auto**, which means
|
||||
that g-i will be built if **g-ir-scanner** is found and skipped otherwise.
|
||||
* **-Ddocs=[enabled|disabled|auto]**: Force enable or force disable building
|
||||
documentation. The default value is **auto**, which means that documentation
|
||||
will be built if **doxygen**, **sphinx** and **breathe** tools are found and skipped otherwise.
|
||||
Note that building the documentation also requires gobject-introspection data to be built.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
To install, simply run the **install** target with ninja:
|
||||
|
||||
*$ ninja -C build install*
|
||||
|
||||
To revert the installation, there is also an **uninstall** target:
|
||||
|
||||
*$ ninja -C build uninstall*
|
||||
14
docs/toc/meson.build
Normal file
14
docs/toc/meson.build
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# you need to add here any files you add to the toc directory as well
|
||||
files = [
|
||||
'installing-wireplumber.rst',
|
||||
'running-wireplumber-daemon.rst',
|
||||
'daemon-configuration.rst',
|
||||
'daemon-logging.rst',
|
||||
'contributing.rst',
|
||||
'community.rst',
|
||||
'testing.rst',
|
||||
]
|
||||
|
||||
foreach file : files
|
||||
configure_file(input: file, output: file, copy: true)
|
||||
endforeach
|
||||
51
docs/toc/running-wireplumber-daemon.rst
Normal file
51
docs/toc/running-wireplumber-daemon.rst
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
.. _running-wireplumber-daemon:
|
||||
|
||||
Running the WirePlumber daemon
|
||||
==============================
|
||||
|
||||
Configure PipeWire
|
||||
------------------
|
||||
|
||||
PipeWire 0.3 comes with an example session manager that you will need
|
||||
to disable and replace with WirePlumber. This can be achieved by editing
|
||||
**src/daemon/pipewire.conf.in** in the PipeWire git tree or
|
||||
**/etc/pipewire/pipewire.conf** in an existing installation:
|
||||
|
||||
Here, is the set of changes required to disable the default session manager and
|
||||
to replace it with WirePlumber::
|
||||
|
||||
diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in
|
||||
index cebded96..dee1743b 100644
|
||||
--- a/src/daemon/pipewire.conf.in
|
||||
+++ b/src/daemon/pipewire.conf.in
|
||||
@@ -99,7 +99,8 @@ exec = {
|
||||
# Start the session manager. Run the session manager with -h for
|
||||
# options.
|
||||
#
|
||||
- "@media_session_path@" = { args = ""}
|
||||
+ #"@media_session_path@" = { args = ""}
|
||||
+ "wireplumber" = {}
|
||||
#
|
||||
# You can optionally start the pulseaudio-server here as well
|
||||
# but it better to start it as a systemd service.
|
||||
|
||||
This setup assumes that WirePlumber is *installed* on the target system.
|
||||
|
||||
Run independently or without installing
|
||||
---------------------------------------
|
||||
|
||||
If you wish to debug WirePlumber, it may be useful to run it separately from
|
||||
PipeWire or run it directly from the source tree without installing.
|
||||
To do so -
|
||||
|
||||
1. Comment out with *#* the *"wireplumber" = {}* line from *pipewire.conf*
|
||||
|
||||
2. Run pipewire.
|
||||
|
||||
* if it is installed, execute *pipewire*
|
||||
* if it is **not** installed, execute *make run* in the **pipewire** source tree
|
||||
|
||||
3. Without stopping pipewire, run wireplumber.
|
||||
|
||||
* if it is installed, execute *wireplumber*
|
||||
* if it is **not** installed, execute *make run* in the **wireplumber** source tree
|
||||
250
docs/toc/testing.rst
Normal file
250
docs/toc/testing.rst
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
.. _testing:
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
Automated unit tests
|
||||
--------------------
|
||||
|
||||
WirePlumber has automated tests that you can easily run with::
|
||||
|
||||
$ meson test -C build
|
||||
|
||||
|
||||
This will automatically compile all test dependencies, so you can be sure
|
||||
that this always tests your latest changes.
|
||||
|
||||
If you wish to run a specific test instead of all of them, you can run::
|
||||
|
||||
$ meson test -C build test-name
|
||||
|
||||
|
||||
When debugging a single test, you can additionally enable verbose test output
|
||||
by appending *-v* and you can also run the test in gdb by appending *--gdb*.
|
||||
|
||||
For more information on how to use *'meson test'*, please refer to
|
||||
`mesons manual <https://mesonbuild.com/Unit-tests.html>`_
|
||||
|
||||
* When submitting changes for review, always ensure that all tests pass
|
||||
|
||||
Please note that many WirePlumber tests require specific SPA test plugins
|
||||
to be available in your PipeWire installation. More specifically, PipeWire
|
||||
needs to be configured with the following options enabled::
|
||||
|
||||
-Dvideotestsrc=true -Daudiotestsrc=true -Dtest=true
|
||||
|
||||
If these SPA plugins are not found in the system, some tests will fail.
|
||||
This is expected.
|
||||
|
||||
WirePlumber examples
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
WirePlumber ships examples in *'test/examples'*.
|
||||
Execute them from the top-level directory like this::
|
||||
|
||||
$ WIREPLUMBER_MODULE_DIR=build/modules ./build/tests/examples/audiotestsrc-play
|
||||
|
||||
|
||||
Assuming there is no other process actively using *'hw:0,0'* from alsa, the above
|
||||
example should play a test tone on *'hw:0,0'* without errors.
|
||||
|
||||
Native API clients
|
||||
------------------
|
||||
|
||||
pw-cat
|
||||
^^^^^^
|
||||
|
||||
Using the default endpoint::
|
||||
|
||||
$ wpctl status # verify the default endpoints
|
||||
$ pw-record test.wav
|
||||
$ pw-play test.wav
|
||||
|
||||
|
||||
Using a non-default endpoint::
|
||||
|
||||
$ pw-record --list-targets # find the node id
|
||||
$ pw-record --target <node_id> test.wav
|
||||
$ pw-play --list-targets # find the node id
|
||||
$ pw-play --target <node_id> test.wav
|
||||
|
||||
or
|
||||
|
||||
Use the commands::
|
||||
|
||||
$ wpctl status # find the capture & playback endpoint ids
|
||||
$ pw-record --target <endpoint_id> test.wav
|
||||
$ pw-play --target <endpoint_id> test.wav
|
||||
|
||||
|
||||
.. note:: node ids and endpoint ids can be used interchangeably when specifying
|
||||
targets in all use cases.
|
||||
|
||||
video-play
|
||||
^^^^^^^^^^
|
||||
|
||||
Using the default endpoint::
|
||||
|
||||
$ cd path/to/pipewire-source-dir
|
||||
$ ./build/src/examples/video-play
|
||||
|
||||
|
||||
Using a non-default endpoint::
|
||||
|
||||
$ wpctl status # find the endpoint id from the list
|
||||
$ cd path/to/pipewire-source-dir
|
||||
$ ./build/src/examples/video-play <endpoint_id>
|
||||
|
||||
|
||||
.. note:: Tip: enable videotestsrc in wireplumber's configuration to have more video
|
||||
sources available (see `videotestsrc.node.disabled` in the configuration directory)
|
||||
|
||||
PulseAudio compat API clients
|
||||
-----------------------------
|
||||
|
||||
pacat
|
||||
^^^^^
|
||||
|
||||
Using the default endpoint::
|
||||
|
||||
$ wpctl status # verify the default endpoints
|
||||
$ pw-pulse parecord test.wav
|
||||
$ pw-pulse paplay test.wav
|
||||
|
||||
|
||||
Using a non-default endpoint::
|
||||
|
||||
$ wpctl status # find the capture & playback endpoint ids
|
||||
$ PIPEWIRE_NODE=<endpoint_id> pw-pulse parecord test.wav
|
||||
$ PIPEWIRE_NODE=<endpoint_id> pw-pulse paplay test.wav
|
||||
|
||||
|
||||
pavucontrol
|
||||
^^^^^^^^^^^
|
||||
|
||||
Use the command::
|
||||
|
||||
$ pw-pulse pavucontrol
|
||||
|
||||
* Volume level meters should work
|
||||
* Changing the volume should work
|
||||
|
||||
ALSA compat API clients
|
||||
-----------------------
|
||||
|
||||
aplay / arecord
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
.. note:: unless you have installed PipeWire in the default system prefix
|
||||
(`/usr`), the ALSA compat API will not work, unless you copy
|
||||
`libasound_module_pcm_pipewire.so` in the alsa plugins directory
|
||||
(usually `/usr/<libdir>/alsa-lib/`) and that you add the contents of
|
||||
`pipewire-alsa/conf/50-pipewire.conf` in your `~/.asoundrc`
|
||||
(or anywhere else, system-wide, where libasound can read it)
|
||||
|
||||
Using the default endpoint::
|
||||
|
||||
$ wpctl status # verify the default endpoints
|
||||
$ arecord -D pipewire -f S16_LE -r 48000 test.wav
|
||||
$ aplay -D pipewire test.wav
|
||||
|
||||
|
||||
Using a non-default endpoint::
|
||||
|
||||
$ wpctl status # find the capture & playback endpoint ids
|
||||
$ PIPEWIRE_NODE=<endpoint_id> arecord -D pipewire -f S16_LE -r 48000 test.wav
|
||||
$ PIPEWIRE_NODE=<endpoint_id> aplay -D pipewire test.wav
|
||||
|
||||
or
|
||||
|
||||
Use the commands::
|
||||
|
||||
$ wpctl status # find the capture & playback endpoint ids
|
||||
$ arecord -D pipewire:NODE=<endpoint_id> -f S16_LE -r 48000 test.wav
|
||||
$ aplay -D pipewire:NODE=<endpoint_id> test.wav
|
||||
|
||||
|
||||
JACK compat API clients
|
||||
-----------------------
|
||||
|
||||
qjackctl
|
||||
^^^^^^^^
|
||||
|
||||
Use the commands::
|
||||
|
||||
pw-jack qjackctl
|
||||
|
||||
* This should correctly connect.
|
||||
* The "Graph" window should show the PipeWire graph.
|
||||
|
||||
jack_simple_client
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Use the commands::
|
||||
|
||||
$ wpctl status # find the target endpoint id
|
||||
$ wpctl inspect <endpoint_id> # find the node.id
|
||||
$ PIPEWIRE_NODE=<node_id> pw-jack jack_simple_client
|
||||
|
||||
|
||||
.. note:: The JACK layer is not controlled by the session manager, it creates its own
|
||||
links; which is why it is required to specify a node id (endpoint id will not
|
||||
work)
|
||||
|
||||
Device Reservation
|
||||
------------------
|
||||
|
||||
with PulseAudio
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
1. With PulseAudio running, start a pulseaudio client.
|
||||
|
||||
Use the command::
|
||||
|
||||
$ gst-launch-1.0 audiotestsrc ! pulsesink
|
||||
|
||||
2. Start PipeWire & WirePlumber
|
||||
- The device in use by PA will not be available in PW
|
||||
3. Stop the PA client
|
||||
- A few seconds later, WirePlumber should assume control of the device
|
||||
4. *'wpctl status'* should be able to confirm that the device is available
|
||||
5. Start a PA client again
|
||||
- It should not be able to play; it will just freeze
|
||||
6. Stop WirePlumber
|
||||
- The PA client should immediately start playing
|
||||
|
||||
with JACK
|
||||
^^^^^^^^^
|
||||
|
||||
1. Start PipeWire & WirePlumber
|
||||
|
||||
* All devices should be available
|
||||
|
||||
2. Start *'jackdbus'*
|
||||
|
||||
1. through *'qjackctl'*:
|
||||
|
||||
* Enable *'Setup'* -> *'Misc'* -> *'Enable JACK D-Bus interface'*
|
||||
|
||||
* Click *'Start'* on the main window
|
||||
|
||||
2. or manually:
|
||||
|
||||
* Run *'jackdbus auto'*
|
||||
|
||||
* Run *'qdbus org.jackaudio.service /org/jackaudio/Controller org.jackaudio.JackControl.StartServer'*
|
||||
|
||||
3. Wait a few seconds and run *'wpctl status'* to inspect
|
||||
- The devices taken by JACK should no longer be available
|
||||
- There should be two *'JACK System'* endpoints (sink & source)
|
||||
4. Run an audio client on PipeWire (ex *'pw-play test.wav'*)
|
||||
- Notice how audio now goes through JACK
|
||||
5. Stop JACK
|
||||
- through *'qjackctl'*, click *'Stop'*
|
||||
- or manually: *'qdbus org.jackaudio.service /org/jackaudio/Controller org.jackaudio.JackControl.StopServer'*
|
||||
6. Wait a few seconds and run *'wpctl status'* to inspect
|
||||
- The devices that were release by JACK should again be available
|
||||
- There should be no *'JACK System'* endpoint
|
||||
|
||||
.. note:: You may also start WirePlumber *after* starting JACK. It should immediately
|
||||
go to the state described in step 3
|
||||
Loading…
Add table
Reference in a new issue