Merge branch 'feature/user-overview-docs' into 'master'
Draft: docs: Add user overview docs for PipeWire See merge request pipewire/pipewire!2771
|
|
@ -58,6 +58,7 @@ PREDEFINED = PA_C_DECL_BEGIN= \
|
|||
SPA_NORETURN \
|
||||
SPA_RESTRICT
|
||||
HTML_EXTRA_STYLESHEET = @cssfiles@
|
||||
IMAGE_PATH = "@top_srcdir@/doc/dox/media/"
|
||||
|
||||
MAX_INITIALIZER_LINES = 1
|
||||
SORT_MEMBER_DOCS = NO
|
||||
|
|
|
|||
4
doc/dox/media/LinuxSoundStack.drawio.svg
Normal file
|
After Width: | Height: | Size: 54 KiB |
4
doc/dox/media/Routing-Direct.drawio.svg
Normal file
|
After Width: | Height: | Size: 18 KiB |
4
doc/dox/media/Routing-FilterChain.drawio.svg
Normal file
|
After Width: | Height: | Size: 28 KiB |
4
doc/dox/media/Routing-FilterChainDouble.drawio.svg
Normal file
|
After Width: | Height: | Size: 41 KiB |
4
doc/dox/media/Routing-Remap.drawio.svg
Normal file
|
After Width: | Height: | Size: 74 KiB |
4
doc/dox/media/SoundMixing.drawio.svg
Normal file
|
After Width: | Height: | Size: 53 KiB |
65
doc/dox/media/SoundStack.svg
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="56.56242mm"
|
||||
height="25.159874mm"
|
||||
viewBox="0 0 56.56242 25.159874"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="SoundStack.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.3986392"
|
||||
inkscape:cx="64.348262"
|
||||
inkscape:cy="154.07834"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1043"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-19.106369,-77.182167)">
|
||||
<rect
|
||||
style="fill:#000000;stroke-width:0.264583"
|
||||
id="rect61"
|
||||
width="25.727388"
|
||||
height="10.026114"
|
||||
x="19.106369"
|
||||
y="92.315926" />
|
||||
<rect
|
||||
style="fill:#000000;stroke-width:0.264583"
|
||||
id="rect63"
|
||||
width="11.917834"
|
||||
height="5.8643312"
|
||||
x="30.456688"
|
||||
y="81.722298" />
|
||||
<rect
|
||||
style="fill:#000000;stroke-width:0.264583"
|
||||
id="rect65"
|
||||
width="25.538216"
|
||||
height="24.214012"
|
||||
x="50.130573"
|
||||
y="77.182167" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 27 KiB |
216
doc/dox/overview-for-users.md
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
\page page_overview_for_users Overview for Users
|
||||
|
||||
While the \ref page_overview page describes PipeWire on a technical level for programmers,
|
||||
this page is intended for end users working with (and not programming on) PipeWire.
|
||||
|
||||
# PipeWire
|
||||
|
||||
- [docs.pipewire.org: PipeWire docs](https://docs.pipewire.org/) – that’s this page
|
||||
- [pipewire.pages.freedesktop.org: WirePlumber docs](https://pipewire.pages.freedesktop.org/wireplumber/) – WirePlumber reference
|
||||
- [gitlab.freedesktop.org Wiki](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/home) with guides and links to other docs
|
||||
- [wiki.archlinux.org: ArchLinux docs](https://wiki.archlinux.org/title/PipeWire) with tool list and examples
|
||||
|
||||
PipeWire is a multimedia framework for Linux. The Kernel uses ALSA, and applications can either use ALSA directly
|
||||
(but only one application send sound to an ALSA output at the same time), or use a different backend like JACK,
|
||||
PulseAudio, or (the newest) PipeWire. All those backends do not have the single client limitation and provide
|
||||
additional features.
|
||||
|
||||
PipeWire uses a powerful graph based approach for routing application freely between producers and consumers.
|
||||
|
||||
PipeWire provides a PulseAudio API (and others like JACK), so clients relying on PulseAudio still work,
|
||||
they just use the PulseAudio API provided by PipeWire. Therefore, PulseAudio tools like `pavucontrol` still work
|
||||
(see PulseAudio section below).
|
||||
|
||||
|
||||
## PipeWire overview
|
||||
|
||||
Normally, a system with PipeWire also runs **WirePlumber.**
|
||||
|
||||
**PipeWire** only *provides* the functionality for transporting and transforming audio and video. It is *used* by a session manager.
|
||||
|
||||
There is one PipeWire *server* which is used by a number of PipeWire *clients* (the processes that produce/consume multimedia).
|
||||
PipeWire, as well as WirePlumber, run in *userspace,* so interfacing with them with `systemd` (and `journald` etc.)
|
||||
happens in *user context* with the `--user` flag, for example
|
||||
`systemctl --user status pipewire.service` or `journalctl --user -fu wireplumber.service`.
|
||||
|
||||
**WirePlumber** provides [Session Management](https://pipewire.pages.freedesktop.org/wireplumber/design/understanding_session_management.html): It enables new devices when they appear on ALSA, creates and configures nodes,
|
||||
create links between nodes to route sound from an application to a consumer, etc.
|
||||
|
||||
### Terminology
|
||||
|
||||
For a more technical description, see \ref page_overview.
|
||||
|
||||
* **Nodes** produce and/or consume data, for example a stereo output to a headset (consumes), an audio player (produces),
|
||||
a reverb effect filter (consumes, then produces modified audio), etc.
|
||||
* **Ports** are the connectors on nodes where data enters or exits. A stereo output sound card has two input ports
|
||||
typically labeled `FL` and `FR` for front left and front right, which may receive data from `vlc` which has
|
||||
two output ports `FL` and `FR`. (Physically, the sound card can have a stereo jack output, for example, but that is not in the scope of PipeWire.)
|
||||
* **Links** connect two ports. Audio/Video data only flows when there is a link between ports.
|
||||
Ports can have multiple incoming/outgoing links, so PipeWire can e.g. send the same `vlc` audio stream to the stereo headset
|
||||
and a bluetooth headset and an audio recorder.
|
||||
* **Devices** represent e.g. ALSA PCM sound cards. They have *Profiles*, and the active profile defines properties
|
||||
like channel setup. For example, a sound card can have a `stereo` profile where only two ports are exposed,
|
||||
or a `surround7.1` profile with 8 ports available.
|
||||
|
||||
Nodes have various properties like name/description, a vendor (if available), an ID (changes between restart, therefore use `node.name` or `device.name`), etc.
|
||||
Some specific properties:
|
||||
|
||||
* `media.class` describes the type of the node. A sound card (a *device* in PipeWire) has media class `Audio/Device`
|
||||
with corresponding `Audio/Source` input and `Audio/Sink` output nodes. A process producing audio is `Stream/Output/Audio`.
|
||||
|
||||
Relationships between different object types (`type` property):
|
||||
|
||||

|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
C[PipeWire:Interface:Client]
|
||||
D[PipeWire:Interface:Device]
|
||||
N[PipeWire:Interface:Node]
|
||||
P[PipeWire:Interface:Port]
|
||||
L[PipeWire:Interface:Link]
|
||||
CO[PipeWire:Interface:Core]
|
||||
M[PipeWire:Interface:Module]
|
||||
SC[PipeWire:Interface:SecurityContext]
|
||||
PR[PipeWire:Interface:Profiler]
|
||||
PM[PipeWire:Interface:Metadata]
|
||||
N -- target.object --> C
|
||||
N -- target.object --> D
|
||||
L -- input + output port --> P
|
||||
L -- input + output node --> N
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### PipeWire Tools
|
||||
|
||||
* [List of PipeWire programs](https://docs.pipewire.org/page_programs.html)
|
||||
|
||||
This is just a short selection of tools.
|
||||
|
||||
[qpwgraph](https://gitlab.freedesktop.org/rncbc/qpwgraph) gives a quick visual overview over the current system configuration with nodes and links between them.
|
||||
It also allows creating and deleting links on the fly.
|
||||
|
||||
`pw-dump` dumps the whole configuration (json dump all, nodes etc)
|
||||
|
||||
`pw-cli` allows to query and configure PipeWire, for example setting a sound card profile with
|
||||
`pw-cli s Profile CARD_ID '{index: PROFILE_ID, save: true}'`, or in interactive mode.
|
||||
*Important:* In interactive mode, do *not* use quotes around JSON data.
|
||||
|
||||
`wpctl` interfaces with WirePlumber, for example `wpctl status` shows an ASCII representation of the nodes, sources, sinks, and routing.
|
||||
|
||||
### WirePlumber
|
||||
|
||||
WirePlumber creates links based on defaults and priorities as described in [Linking Policy](https://pipewire.pages.freedesktop.org/wireplumber/policies/linking.html).
|
||||
For example, when an application starts audio playback, it links to the default sound output like the Bluetooth headset.
|
||||
If that output disappears, it dynamically chooses the next suitable output device.
|
||||
|
||||
### Configuration files and rules
|
||||
|
||||
* [PipeWire docs: configuration overview](https://docs.pipewire.org/page_config.html)
|
||||
|
||||
Both PipeWire and WirePlumber have a set of config files for configuring different parts. They use the same format.
|
||||
|
||||
Rules in config file can define default outputs for specific nodes (e.g. VLC sound always goes to the 7.1 sound card).
|
||||
[ArchLinux: WirePlumber](https://wiki.archlinux.org/title/WirePlumber) gives a short introduction to using them.
|
||||
|
||||
**PipeWire server configuration** configures the PipeWire instance, defines which modules PipeWire should load, adds device rules, etc.
|
||||
|
||||
* Location: `pipewire/pipewire.conf`
|
||||
* Docs: [pipewire.conf](https://docs.pipewire.org/page_man_pipewire_conf_5.html)
|
||||
* Configures: `context.exec`, `context.modules`, `context.properties`, `context.spa-libs`, `device.rules`, `node.rules`
|
||||
|
||||
**PipeWire client configuration** contains configuration for PipeWire and ALSA clients, e.g. if VLC uses the PipeWire or ALSA backend,
|
||||
its runtime behaviour can be modified with this configuration.
|
||||
Example: A stream rule defines to always route `vlc` sound output to Bluetooth earbuds and `pw-play` to a stereo headset.
|
||||
|
||||
* Location: `pipewire/client.conf`, for example `~/.config/pipewire/client.conf.d/`
|
||||
* Docs: [client.conf](https://docs.pipewire.org/page_man_pipewire-client_conf_5.html) and [PipeWire object property reference](https://docs.pipewire.org/page_man_pipewire-props_7.html) (also contains WirePlumber related options!)
|
||||
* Configures: `alsa.properties`, `alsa.rules`, `stream.properties`, `stream.rules`
|
||||
|
||||
**PulseAudio/JACK configuration** contains configuration for PipeWire’s PulseAudio and JACK servers.
|
||||
|
||||
* Docs: [pipewire-pulse.conf](https://docs.pipewire.org/page_man_pipewire-pulse_conf_5.html), [jack.conf](https://docs.pipewire.org/page_man_pipewire-jack_conf_5.html)
|
||||
|
||||
**WirePlumber configuration** configures general WirePlumber aspects (should it even bring up ALSA devices
|
||||
or save/restore user settings configured with e.g. `pavucontrol`) and also ALSA/Bluetooth monitor aspects
|
||||
(choosing a default profile like Stereo or 7.1, setting device priorities that affect default routing, setting device properties, etc.).
|
||||
|
||||
* Location: `wireplumber.conf`, e.g. `~/.config/wireplumber/wireplumber.conf.d/`
|
||||
|
||||
* Docs: [WirePlumber daemon configuration](https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration.html) and more like [ALSA configuration](https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/alsa.html)
|
||||
* Configures: `context`, `device`, `linking`, `wireplumber`, `monitor` (like `monitor.alsa.properties`, `monitor.alsa.rules`), `node` (like `node.software-dsp`),`support`, `policy`
|
||||
|
||||
|
||||
|
||||
#### Writing Rules and Examples
|
||||
|
||||
Rules can use regular expression when strings start with `~`, as explained in [PipeWire: Working with rules](https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/modifying_configuration.html#working-with-rules).
|
||||
|
||||
```text
|
||||
# Goes to ~/.config/wireplumber/wireplumber.conf.d/wireplumber-default-device.conf
|
||||
# Restart wireplumber.service so it loads the rules
|
||||
# This sample rule increases the priority of the stereo output on a Raspberry Pi,
|
||||
# so it is used by default.
|
||||
monitor.alsa.rules = [
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
node.name = "alsa_output.platform-fe00b840.mailbox.stereo-fallback"
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
priority.driver = 3000
|
||||
priority.session = 3000
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
```text
|
||||
# Goes to ~/.config/pipewire/client.conf.d/default-pw-play-output.conf
|
||||
# Restart wireplumber.service so it loads the rules
|
||||
# This sample rule uses a specific sound card for playback with pw-play.
|
||||
# If it does not exist, WirePlumber takes the next suitable one.
|
||||
stream.rules = [
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
application.name = "pw-play"
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
target.object = "alsa_output.usb-PreSonus_Audio_AudioBox_USB-01.pro-output-0"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Debugging
|
||||
|
||||
* Setting WirePlumber log level: https://pipewire.pages.freedesktop.org/wireplumber/daemon/logging.html
|
||||
* `pw-play --target [ID|node.name] myfile.mp3` plays a sound file and tries to use the given target; useful for trying to find out the correct target
|
||||
* [Automatically Link Pipewire Nodes with Wireplumber](https://bennett.dev/auto-link-pipewire-ports-wireplumber/)
|
||||
|
||||
|
||||
|
||||
## PulseAudio API
|
||||
|
||||
* [Migrating from PulseAudio to PipeWire](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Migrate-PulseAudio)
|
||||
* [PulseAudio clients and usage](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio) for PipeWire
|
||||
|
||||
Many PulseAudio tools also work for PipeWire, like:
|
||||
|
||||
* `pavucontrol` (GUI to configure sound cards, select profiles, etc.)
|
||||
* `pactl` (CLI configuration tool, e.g. for setting the default audio sink)
|
||||
* `paplay` and `parecord` for playing and recording audio
|
||||
|
||||
|
|
@ -1,5 +1,93 @@
|
|||
/** \page page_overview Overview
|
||||
|
||||
# The role of PipeWire
|
||||
|
||||
Today’s Linux systems use ALSA (Advanced Linux Sound Architecture) to play and record sound and video.
|
||||
ALSA is built directly into the Linux Kernel including drivers for sound cards, and applications can use ALSA to play sound.
|
||||
However, each sound card can only be used by one application at a time – which is one reason why another layer like PipeWire is required:
|
||||
It mixes multiple audio streams together and sends that to ALSA directly.
|
||||
In addition, PipeWire also supports video and MIDI streams.
|
||||
|
||||
\image html SoundMixing.drawio.svg
|
||||
|
||||
# Strengths of PipeWire
|
||||
|
||||
PipeWire has 3 core strengths that make it so popular today:
|
||||
|
||||
- Backwards compatibility with older sound servers – your favourite application just runs
|
||||
- Low latency audio processing – important for audio professionals
|
||||
- Powerful routing – define where streams go
|
||||
|
||||
## Compatibility
|
||||
|
||||
There are a number of popular sound servers for Linux like JACK for low latency or PulseAudio.
|
||||
PipeWire is the newest one, combining the advantages of its predecessors.
|
||||
|
||||
Applications are programmed to support a certain backend, or sometimes they support more than one.
|
||||
Even if they do not support PipeWire, they still work with PipeWire because it provides interfaces
|
||||
that look like e.g. ALSA or PulseAudio.
|
||||
Even configuration tools like `pavucontrol`, which configures audio devices like volume, profile (Stereo or 7.1 etc.), and so on, work for PipeWire!
|
||||
|
||||
\image html LinuxSoundStack.drawio.svg
|
||||
|
||||
## Routing
|
||||
|
||||
Routing choices are made whenever you play back audio.
|
||||
(Same for recording and video/MIDI, but for simplicity we will focus on audio for now.)
|
||||
|
||||
When you play back an mp3 file with `vlc`, does it play on your laptop speakers or on your HDMI screen?
|
||||
What happens when you plug in your USB headphones, or connect your wireless earbuds?
|
||||
Every time a decision needs to be made where the audio stream goes after it leaves `vlc`.
|
||||
This is called *routing,* and it works a bit like connecting parts with cables, for example `vlc` and the earbuds.
|
||||
|
||||
PipeWire can do that, but it can do much more.
|
||||
|
||||
- Equalise audio before sending it to the speaker? The \ref page_module_filter_chain "Filter Chain" module
|
||||
does this – or you can use it to run any LADSPA/ffmpeg/… filter live over your audio stream.
|
||||
- Play back on a different PC? Route audio to the \ref page_module_pulse_tunnel "Pulse Tunnel" module.
|
||||
- Pretend your 6-channel audio interface is 3 different stereo sound cards, or your 10-channel interface
|
||||
is a 7.1 Surround interface? The \ref page_module_loopback "Loopback" module does that.
|
||||
- Cancel an echo in a video call? Use the \ref page_module_echo_cancel "Echo Cancel" module.
|
||||
|
||||
### Routing Examples
|
||||
|
||||
To illustrate routing, let’s start with a simple setup:
|
||||
VLC plays sound directly on the Jack output of your device.
|
||||
|
||||
\image html Routing-Direct.drawio.svg
|
||||
|
||||
Now we can place an equaliser in-between to lift some frequencies.
|
||||
|
||||
\image html Routing-FilterChain.drawio.svg
|
||||
|
||||
Actually, let’s lift the frequencies of the left speaker differently,
|
||||
and then add a reverb filter from LADSPA.
|
||||
|
||||
\image html Routing-FilterChainDouble.drawio.svg
|
||||
|
||||
Or, we want to use the first 6 channels of an 8-channel interface as 5.1
|
||||
and the remaining two channels as stereo output.
|
||||
|
||||
\image html Routing-Remap.drawio.svg
|
||||
|
||||
Most of these settings need configuration files, there is no GUI yet.
|
||||
To unlock the full power of PipeWire, you will have to dive into the deeper areas of Lake Audio!
|
||||
|
||||
# What do I need?
|
||||
|
||||
Normally, a system with PipeWire also runs **WirePlumber.**
|
||||
|
||||
While **PipeWire** *provides* the functionality for transporting and transforming audio and video, it does not actively react to events like connecting Bluetooth earbuds.
|
||||
This is the task of the session manager which *uses* PipeWire.
|
||||
|
||||
There is one PipeWire *server* which is used by a number of PipeWire *clients* (the processes that produce/consume multimedia).
|
||||
PipeWire, as well as WirePlumber, run in *userspace,* so interfacing with them with `systemd` (and `journald` etc.)
|
||||
happens in *user context* with the `--user` flag, for example
|
||||
`systemctl --user status pipewire.service` or `journalctl --user -fu wireplumber.service`.
|
||||
|
||||
**WirePlumber** provides [Session Management](https://pipewire.pages.freedesktop.org/wireplumber/design/understanding_session_management.html): It enables new devices when they appear on ALSA, creates and configures nodes,
|
||||
create links between nodes to route sound from an application to a consumer, etc.
|
||||
|
||||
# Concepts
|
||||
|
||||
## The PipeWire Server
|
||||
|
|
@ -48,9 +136,9 @@ A recommended pattern that is often used is a single client be a daemon that dea
|
|||
It provides another, higher-level API compared to the PipeWire one, and runs Lua scripts that implement the management logic using the said API.
|
||||
It ships with default scripts and configuration that handle linking policies as well as monitoring and automatic spawning of ALSA, bluez, libcamera and v4l2 devices.
|
||||
The API is available for any process, not only from WirePlumber’s Lua scripts.
|
||||
|
||||
### Node implementation
|
||||
|
||||
|
||||
### Node implementation
|
||||
|
||||
With the nodes which they implement, clients can send multimedia data into the graph or obtain multimedia data from the graph.
|
||||
A client can create multiple PipeWire nodes.
|
||||
That allows one to create more complex applications;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ extra_docs = [
|
|||
'tree.dox',
|
||||
'dox/index.dox',
|
||||
'dox/overview.dox',
|
||||
'dox/overview-for-users.md',
|
||||
'dox/modules.dox',
|
||||
'dox/pulse-modules.dox',
|
||||
'dox/programs/index.md',
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ Support interfaces provided by host
|
|||
\}
|
||||
|
||||
\page page_overview
|
||||
\page page_overview_for_users
|
||||
\page page_config
|
||||
\page page_programs
|
||||
\page page_modules
|
||||
|
|
|
|||