diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index add2e890f..4d9dc63bf 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -19,7 +19,7 @@ QUIET = YES WARN_NO_PARAMDOC = YES HAVE_DOT = @HAVE_DOT@ INPUT = @inputs@ -FILTER_PATTERNS = "*.c=@c_input_filter@" "*.h=@h_input_filter@" +FILTER_PATTERNS = "*.c=@c_input_filter@" "*.h=@h_input_filter@" "*.md=@md_input_filter@" FILE_PATTERNS = "*.h" "*.c" RECURSIVE = YES EXAMPLE_PATH = "@top_srcdir@/src/examples" \ diff --git a/doc/custom.css b/doc/custom.css index 97f033f75..46e58ddae 100644 --- a/doc/custom.css +++ b/doc/custom.css @@ -25,16 +25,36 @@ .textblock h1 { font-size: 150%; + border-bottom: 1px solid var(--page-foreground-color); + margin-top: 1.5em; } .textblock h2 { - font-size: 100%; + font-size: 120%; + margin-top: 1.5em; } .textblock h3, .textblock h4, .textblock h5, .textblock h6 { font-size: 100%; font-style: italic; font-size: medium; + margin-top: 1.5em; } .textblock dl.section dd { margin-left: 2rem; } + +ul.multicol li { + word-break: break-word; + padding-left: 3em; + text-indent: -3em; +} + +ul.multicol li a.el { + font-weight: normal; +} + +div.contents div.toc li { + word-break: break-word; + padding-left: 2em; + text-indent: -2em; +} diff --git a/doc/dox/config/index.md b/doc/dox/config/index.md index 837b1fe83..578199c15 100644 --- a/doc/dox/config/index.md +++ b/doc/dox/config/index.md @@ -23,20 +23,60 @@ configuration options and files: Configuration of daemons: -- [PipeWire daemon configuration](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PipeWire) +- \ref page_man_pipewire_conf_5 +- \ref page_man_pipewire-pulse_conf_5 - [WirePlumber daemon configuration](https://pipewire.pages.freedesktop.org/wireplumber/) -- [PipeWire PulseAudio daemon configuration](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio) +- [Wiki page on PipeWire daemon configuration](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PipeWire) +- [Wiki page on PipeWire PulseAudio daemon configuration](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio) Configuration of devices: +- \ref page_man_pipewire-devices_7 - [WirePlumber configuration](https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration.html) -- [Device runtime settings](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-Devices) +- [Wiki page on device runtime settings](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-Devices) Configuration for client applications, either connecting via the native PipeWire interface, or the emulated ALSA, JACK, or PulseAudio interfaces: -- [PipeWire native clients](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-client) -- [PipeWire ALSA clients](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-ALSA) -- [PipeWire JACK clients](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-JACK) -- [PipeWire PulseAudio clients](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio) +- \ref page_man_pipewire-client_conf_5 +- \ref page_man_pipewire-jack_conf_5 +- \ref page_man_pipewire-pulse_conf_5 +- [Wiki page on native clients](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-client) +- [Wiki page on ALSA clients](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-ALSA) +- [Wiki page on JACK clients](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-JACK) +- [Wiki page on PulseAudio clients](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio) + +# Configuration Index + +\ref page_man_pipewire_conf_5 "pipewire.conf" + +@SECREF@ pipewire.conf + +\ref page_man_pipewire_conf_5 "pipewire-pulse.conf" + +@SECREF@ pipewire-pulse.conf + +\ref page_man_pipewire_conf_5 "client.conf, client-rt.conf" + +@SECREF@ client.conf + +\ref page_man_pipewire_conf_5 "jack.conf" + +@SECREF@ jack.conf + +**Runtime settings** + +@SECREF@ pipewire-settings + +**Environment variables** + +@SECREF@ pipewire-env client-env jack-env pulse-env + +**Device properties** + +@SECREF@ device-property + +**Device parameters** + +@SECREF@ device-param diff --git a/doc/dox/programs/index.md b/doc/dox/programs/index.md index 47721f694..6eff77066 100644 --- a/doc/dox/programs/index.md +++ b/doc/dox/programs/index.md @@ -4,9 +4,12 @@ Manual pages: - \subpage page_man_pipewire_1 - \subpage page_man_pipewire_conf_5 +- \subpage page_man_pipewire-client_conf_5 - \subpage page_man_pipewire-pulse_1 - \subpage page_man_pipewire-pulse_conf_5 - \subpage page_man_pipewire-pulse-modules_7 +- \subpage page_man_pipewire-jack_conf_5 +- \subpage page_man_pipewire-devices_7 - \subpage page_man_pw-cat_1 - \subpage page_man_pw-cli_1 - \subpage page_man_pw-config_1 diff --git a/doc/dox/programs/pipewire-client.conf.5.md b/doc/dox/programs/pipewire-client.conf.5.md new file mode 100644 index 000000000..edae946fe --- /dev/null +++ b/doc/dox/programs/pipewire-client.conf.5.md @@ -0,0 +1,600 @@ +\page page_man_pipewire-client_conf_5 client.conf + +The PipeWire client configuration file. + +\tableofcontents + +# SYNOPSIS + +*$XDG_CONFIG_HOME/pipewire/client.conf* + +*$(PIPEWIRE_CONFIG_DIR)/client.conf* + +*$(PIPEWIRE_CONFDATADIR)/client.conf* + +*$(PIPEWIRE_CONFDATADIR)/client.conf.d/* + +*$(PIPEWIRE_CONFIG_DIR)/client.conf.d/* + +*$XDG_CONFIG_HOME/pipewire/client.conf.d/* + +*$XDG_CONFIG_HOME/pipewire/client-rt.conf* + +*$(PIPEWIRE_CONFIG_DIR)/client-rt.conf* + +*$(PIPEWIRE_CONFDATADIR)/client-rt.conf* + +*$(PIPEWIRE_CONFDATADIR)/client-rt.conf.d/* + +*$(PIPEWIRE_CONFIG_DIR)/client-rt.conf.d/* + +*$XDG_CONFIG_HOME/pipewire/client-rt.conf.d/* + +# DESCRIPTION + +Configuration for PipeWire native clients, and for PipeWire's ALSA +plugin. + +A PipeWire native client program selects the default config to load, +and if nothing is specified, it usually loads `client.conf`. + +The ALSA plugin uses the `client-rt.conf` file, as do some PipeWire +native clients such as \ref page_man_pw-cat_1 "pw-cat(1)". + +The configuration file format is the same as for `pipewire.conf(5)`. + +# CONFIGURATION FILE SECTIONS + +The same sections as in \ref page_man_pipewire_conf_5 "pipewire.conf(5)" +are available. However, a client usually sets the +`core.daemon` property to false, and has a limited set of +`context.spa-libs` usually only to create audio nodes and a poll loop. + +\par stream.properties +Configures options for native client streams. + +\par stream.rules +Configures rules for native client streams. + +\par alsa.properties +ALSA client configuration. + +\par alsa.rules +ALSA client match rules. + +# STREAM PROPERTIES @IDX@ client.conf + +The client configuration files contain a stream.properties section that configures the options for client streams: +``` +stream.properties = { + #node.latency = 1024/48000 + #node.autoconnect = true + #resample.disable = false + #resample.quality = 4 + #monitor.channel-volumes = false + #channelmix.disable = false + #channelmix.min-volume = 0.0 + #channelmix.max-volume = 10.0 + #channelmix.normalize = false + #channelmix.mix-lfe = true + #channelmix.upmix = true + #channelmix.upmix-method = psd # none, simple + #channelmix.lfe-cutoff = 150.0 + #channelmix.fc-cutoff = 12000.0 + #channelmix.rear-delay = 12.0 + #channelmix.stereo-widen = 0.0 + #channelmix.hilbert-taps = 0 + #dither.noise = 0 + #dither.method = none # rectangular, triangular, triangular-hf, wannamaker3, shaped5 + #debug.wav-path = "" +} +``` + +Some of the properties refer to different aspects of the stream: + +* General stream properties to identify the stream. +* General stream properties to classify the stream. +* How it is going to be scheduled by the graph. +* How it is going to be linked by the session manager. +* How the internal processing will be done. +* Properties to configure the media format. + +## Identifying Properties @IDX@ client.conf + +These contain properties to identify the node or to display the node in a GUI application. + +@PAR@ client.conf node.name +A (unique) name for the node. This is usually set on sink and sources to identify them +as targets for linking by the session manager. + +@PAR@ client.conf node.description +A human readable description of the node or stream. + +@PAR@ client.conf media.name +@PAR@ client.conf media.title +@PAR@ client.conf media.artist +A user readable media name, usually the artist and title. These are usually shown in user facing applications +to inform the user about the current playing media. + +Other media properties exist such as copyright and icon. + +@PAR@ client.conf object.linger = false +If the object should outlive its creator. + +## Classifying Properties @IDX@ client.conf + +The classifying properties of a node are use for routing the signal to its destination and +for configuring the settings. + +@PAR@ client.conf media.type +The media type contains a broad category of the media that is being processed by the node. +Possible values include "Audio", "Video", "Midi" + +@PAR@ client.conf media.category +\parblock +What kind of processing is done with the media. Possible values include: + +* Playback: media playback. +* Capture: media capture. +* Duplex: media capture and playback or media processing in general. +* Monitor: a media monitor application. Does not actively change media data but monitors + activity. +* Manager: Will manage the media graph. +\endparblock + +@PAR@ client.conf media.role +\parblock +The Use case of the media. Possible values include: + +* Movie: Movie playback with audio and video. +* Music: Music listening. +* Camera: Recording video from a camera. +* Screen: Recording or sharing the desktop screen. +* Communication: VOIP or other video chat application. +* Game: Game. +* Notification: System notification sounds. +* DSP: Audio or Video filters and effect processing. +* Production: Professional audio processing and production. +* Accessibility: Audio and Visual aid for accessibility. +* Test: Test program. +\endparblock + +@PAR@ client.conf media.class +\parblock +The media class is to classify the stream function. Possible values include: + +* Video/Source: a producer of video, like a webcam. +* Video/Sink: a consumer of video, like a display window. +* Audio/Source: a source of audio samples like a microphone. +* Audio/Sink: a sink for audio samples, like an audio card. +* Audio/Duplex: a node that is both a sink and a source. +* Stream/Output/Audio: a playback stream. +* Stream/Input/Audio: a capture stream. + +The session manager assigns special meaning to the nodes based on the media.class. Sink or Source +classes are used as targets for Stream classes, etc.. +\endparblock + +## Scheduling Properties @IDX@ client.conf + +@PAR@ client.conf node.latency = 1024/48000 +Sets a suggested latency on the node as a fraction. This is just a suggestion, the graph will try to configure this latency or less for the graph. It is however possible that the graph is forced to a higher latency. + +@PAR@ client.conf node.lock-quantum = false +\parblock +When this node is active, the quantum of the graph is locked and not allowed to change automatically. +It can still be changed forcibly with metadata or when a node forces a quantum. + +JACK clients use this property to avoid unexpected quantum changes. +\endparblock + +@PAR@ client.conf node.force-quantum = INTEGER +\parblock +While the node is active, force a quantum in the graph. The last node to be activated with this property wins. + +A value of 0 unforces the quantum. +\endparblock + +@PAR@ client.conf node.rate = RATE +Suggest a rate (samplerate) for the graph. The suggested rate will only be applied when doing so would not cause +interruptions (devices are idle) and when the rate is in the list of allowed rates in the server. + +@PAR@ client.conf node.lock-rate = false +When the node is active, the rate of the graph will not change automatically. It is still possible to force a rate change with metadata or with a node property. + +@PAR@ client.conf node.force-rate = RATE +\parblock +When the node is active, force a specific sample rate on the graph. The last node to activate with this property wins. + +A RATE of 0 means to force the rate in `node.rate` denominator. +\endparblock + +@PAR@ client.conf node.always-process = false +\parblock +When the node is active, it will always be joined with a driver node, even when nothing is linked to the node. +Setting this property to true also implies node.want-driver = true. + +This is the default for JACK nodes, that always need their process callback called. +\endparblock + +@PAR@ client.conf node.want-driver = true +The node wants to be linked to a driver so that it can start processing. This is the default for streams +and filters since 0.3.51. Nodes that are not linked to anything will still be set to the idle state, +unless node.always-process is set to true. + +@PAR@ client.conf node.pause-on-idle = false +@PAR@ client.conf node.suspend-on-idle = false +\parblock +When the node is not linked anymore, it becomes idle. Normally idle nodes keep processing and are suspended by the session manager after some timeout. It is possible to immediately pause a node when idle with this property. + +When the session manager does not suspend nodes (or when there is no session manager), the node.suspend-on-idle property can be used instead. +\endparblock + +## Session Manager Properties @IDX@ client.conf + +@PAR@ client.conf node.autoconnect = true +Instructs the session manager to automatically connect this node to some other node, usually +a sink or source. + +@PAR@ client.conf node.exclusive = false +If this node wants to be linked exclusively to the sink/source. + +@PAR@ client.conf node.target = +Where this node should be linked to. This can be a node.name or an object.id of a node. This property is +deprecated, the target.object property should be used instead, which uses the more unique object.serial as +a possible target. + +@PAR@ client.conf target.object = +Where the node should link to ths can be a node.name or an object.serial. + +@PAR@ client.conf node.dont-reconnect = false +\parblock +When the node has a target configured and the target is destroyed, destroy the node as well. +This property also inhibits that the node is moved to another sink/source. + +Note that if a stream should appear/disappear in sync with the target, a session manager (WirePlumber) script +should be written instead. +\endparblock + +@PAR@ client.conf node.passive = false +\parblock +This is a passive node and so it should not keep sinks/sources busy. This property makes the session manager create passive links to the sink/sources. If the node is not otherwise linked (via a non-passive link), the node and the sink it is linked to are idle (and eventually suspended). + +This is used for filter nodes that sit in front of sinks/sources and need to suspend together with the sink/source. +\endparblock + +@PAR@ client.conf node.link-group = ID +Add the node to a certain link group. Nodes from the same link group are not automatically linked to each other by the session manager. And example is a coupled stream where you don't want the output to link to the input streams, making a useless loop. + +@PAR@ client.conf stream.dont-remix = false +Instruct the session manager to not remix the channels of a stream. Normally the stream channel configuration is changed to match the sink/source it is connected to. With this property set to true, the stream will keep its original channel layout and the session manager will link matching channels with the sink. + +## Audio Adapter Parameters @IDX@ client.conf + +An audio stream (and also audio device nodes) contain an audio adapter that can perform, +sample format, sample rate and channel mixing operations. + +### Merger Parameters + +The merger is used as the input for a sink device node or a capture stream. It takes the various channels and merges them into a single stream for further processing. + +The merger will also provide the monitor ports of the input channels and can +apply a software volume on the monitor signal. + +@PAR@ client.conf monitor.channel-volumes = false +The volume of the input channels is applied to the volume of the monitor ports. Normally +the monitor ports expose the raw unmodified signal on the input ports. + +### Resampler Parameters + +Source, sinks, capture and playback streams contain a high quality adaptive resampler. +It uses [sinc](https://ccrma.stanford.edu/~jos/resample/resample.pdf) based resampling +with linear interpolation of filter banks to perform arbitrary +resample factors. The resampler is activated in the following cases: + +* The hardware of a device node does not support the graph samplerate. Resampling will occur + from the graph samplerate to the hardware samplerate. +* The hardware clock of a device does not run at the same speed as the graph clock and adaptive + resampling is required to match the clocks. +* A stream does not have the same samplerate as the graph and needs to be resampled. +* An application wants to activate adaptive resampling in a stream to make it match some other + clock. + +PipeWire performs most of the sample conversions and resampling in the client (Or in the case of the PulseAudio server, in the pipewire-pulse server that creates the streams). This ensures all the conversions are offloaded to the clients and the server can deal with one single format for performance reasons. + +Below is an explanation of the options that can be tuned in the sample converter. + +@PAR@ client.conf resample.quality = 4 +\parblock +The quality of the resampler. from 0 to 14, the default is 4. + +Increasing the quality will result in better cutoff and less aliasing at the expense of +(much) more CPU consumption. The default quality of 4 has been selected as a good compromise +between quality and performance with no artifacts that are well below the audible range. + +See [Infinite Wave](https://src.infinitewave.ca/) for a comparison of the performance. +\endparblock + +@PAR@ client.conf resample.disable = false +Disable the resampler entirely. The node will only be able to negotiate with the graph +when the samplerates are compatible. + +### Channel Mixer Parameters + +Source, sinks, capture and playback streams can apply channel mixing on the incoming signal. + +Normally the channel mixer is not used for devices, the device channels are usually exposed as they are. This policy is usually enforced by the session manager, so we refer to its documentation there. + +Playback and capture streams are usually configured to the channel layout of the sink/source +they connect to and will thus perform channel mixing. + +The channel mixer also implements a software volume. This volume adjustment is performed on the original +channel layout. ex: A stereo playback stream that is up-mixed to 5.1 has 2 a left an right volume control. + +@PAR@ client.conf channelmix.disable = false +Disables the channel mixer completely. The stream will only be able to link to compatible +sources/sinks with the exact same channel layout. + +@PAR@ client.conf channelmix.min-volume = 0.0 +@PAR@ client.conf channelmix.max-volume = 10.0 +Gives the min and max volume values allowed. Any volume that is set will be clamped to these +values. + +@PAR@ client.conf channelmix.normalize = false +\parblock +Makes sure that during such mixing & resampling original 0 dB level is preserved, so nothing sounds wildly quieter/louder. + +While this options prevents clipping, it can in some cases produce too low volume. Increase the +volume in that case or disable normalization. +\endparblock + +@PAR@ client.conf channelmix.mix-lfe = true +Mixes the low frequency effect channel into the front center or stereo pair. This might enhance the dynamic range of the signal if there is no subwoofer and the speakers can reproduce the low frequency signal. + +@PAR@ client.conf channelmix.upmix = true +\parblock +Enables up-mixing of the front center (FC) when the target has a FC channel. +The sum of the stereo channels is used and an optional lowpass filter can be used +(see `channelmix.fc-cutoff`). + +Also enabled up-mixing of LFE when `channelmix.lfe-cutoff` is set to something else than 0 and +the target has an LFE channel. The LFE channel is produced by adding the stereo channels. + +If `channelmix.upmix` is true, the up-mixing of the rear channels is also enabled and controlled +with the `channelmix-upmix-method` property. +\endparblock + +@PAR@ client.conf channelmix.upmix-method = psd +\parblock +3 methods are provided to produce the rear channels in a surround sound: + +1. none. No rear channels are produced. + +2. simple. Front channels are copied to the rear. This is fast but can produce phasing effects. + +3. psd. The rear channels as produced from the front left and right ambient sound (the +difference between the channels). A delay and optional phase shift are added to the rear signal +to make the sound bigger. +\endparblock + +@PAR@ client.conf channelmix.lfe-cutoff = 150 +Apply a lowpass filter to the low frequency effects. The value is expressed in Hz. Typical subwoofers have a cutoff at around 150 and 200. The default value of 0 disables the feature. + +@PAR@ client.conf channelmix.fc-cutoff = 12000 +\parblock +Apply a lowpass filter to the front center frequency. The value is expressed in Hz. + +Since the front center contains the dialogs, a typical cutoff frequency is 12000 Hz. + +This option is only active when the up-mix is enabled. +\endparblock + +@PAR@ client.conf channelmix.rear-delay = 12.0 +\parblock +Apply a delay in milliseconds when up-mixing the rear channels. This improves +spacialization of the sound. A typical delay of 12 milliseconds is the default. + +This is only active when the `psd` up-mix method is used. +\endparblock + +@PAR@ client.conf channelmix.stereo-widen = 0.0 +\parblock +Subtracts some of the front center signal from the stereo channels. This moves the dialogs +more to the center speaker and leaves the ambient sound in the stereo channels. + +This is only active when up-mix is enabled and a Front Center channel is mixed. +\endparblock + +@PAR@ client.conf channelmix.hilbert-taps = 0 +\parblock +This option will apply a 90 degree phase shift to the rear channels to improve spacialization. +Taps needs to be between 15 and 255 with more accurate results (and more CPU consumption) +for higher values. + +This is only active when the `psd` up-mix method is used. +\endparblock + +@PAR@ client.conf dither.noise = 0 +This option will add N bits of random data to the signal. This can be used +to keep some amplifiers alive during silent periods. This is usually used together with +`session.suspend-timeout-seconds` to disable suspend in the session manager. + +@PAR@ client.conf dither.method = none +\parblock +Optional [dithering](https://en.wikipedia.org/wiki/Dither) can be done on the quantized +output signal. + +There are 6 modes available: + +1. none No dithering is done. +2. rectangular Dithering with a rectangular noise distribution. +3. triangular Dithering with a triangular noise distribution. +4. triangular-hf Dithering with a sloped triangular noise distribution. +5. wannamaker3 Additional noise shaping is performed on the sloped triangular + dithering to move the noise to the more inaudible range. This is using + the "F-Weighted" noise filter described by Wannamaker. +6. shaped5 Additional noise shaping is performed on the triangular dithering + to move the noise to the more inaudible range. This is using the + Lipshitz filter. + +Dithering is only useful for conversion to a format with less than 24 bits and will be +disabled otherwise. +\endparblock + +## Debug Parameters + +@PAR@ client.conf debug.wav-path = "" +Make the stream to also write the raw samples to a WAV file for debugging puposes. + +## Format Properties + +Streams and also most device nodes can be configured in a certain format with properties. + +@PAR@ client.conf audio.rate = RATE +Forces a samplerate on the node. + +@PAR@ client.conf audio.channels = INTEGER +The number of audio channels to use. Must be a value between 1 and 64. + +@PAR@ client.conf audio.format = FORMAT +\parblock +Forces an audio format on the node. This is the format used internally in the node because the graph processing format is always float 32. + +Valid formats include: S16, S32, F32, F64, S16LE, S16BE, ... +\endparblock + +@PAR@ client.conf audio.allowed-rates +An array of allowed samplerates for the node. ex. "[ 44100 48000 ]" + +# STREAM RULES @IDX@ client.conf + +You can add \ref pipewire_conf__match_rules "match rules, see pipewire(1)" +to set properties for certain streams and filters. + +`stream.rules` and `filter.rules` provides an `update-props` action +that takes an object with properties that are updated on the node +object of the stream and filter. + +Add a `stream.rules` or `filter.rules` section in the config file like +this: + +``` +stream.rules = [ + { + matches = [ + { + # all keys must match the value. ! negates. ~ starts regex. + application.process.binary = "firefox" + } + ] + actions = { + update-props = { + node.name = "My Name" + } + } + } +] +``` + +Will set the node.name of Firefox to "My Name". + +# ALSA PROPERTIES @IDX@ client.conf + +An `alsa.properties` section can be added to configure ALSA specific client config. + +```css +alsa.properties = { + #alsa.deny = false + #alsa.format = 0 + #alsa.rate = 0 + #alsa.channels = 0 + #alsa.period-bytes = 0 + #alsa.buffer-bytes = 0 + #alsa.volume-method = cubic # linear, cubic +} +``` + +@PAR@ client.conf alsa.deny +Denies ALSA access for the client. Useful in rules or PIPEWIRE_ALSA environment variable. + +@PAR@ client.conf alsa.format +The ALSA format to use for the client. This is an ALSA format name. default 0, which is to +allow all formats. + +@PAR@ client.conf alsa.rate +The samplerate to use for the client. The default is 0, which is to allow all rates. + +@PAR@ client.conf alsa.channels +The number of channels for the client. The default is 0, which is to allow any number of channels. + +@PAR@ client.conf alsa.period-bytes +The number of bytes per period. The default is 0 which is to allow any number of period bytes. + +@PAR@ client.conf alsa.buffer-bytes +The number of bytes in the alsa buffer. The default is 0, which is to allow any number of bytes. + +@PAR@ client.conf alsa.volume-method = cubic | linear +This controls the volume curve used on the ALSA mixer. Possible values are `cubic` and +`linear`. The default is to use `cubic`. + +# ALSA RULES @IDX@ client.conf + +It is possible to set ALSA client specific properties by using +\ref pipewire_conf__match_rules "Match rules, see pipewire(1)". You can +set any of the above ALSA properties or any of the `stream.properties`. + +### Example +``` +alsa.rules = [ + { matches = [ { application.process.binary = "resolve" } ] + actions = { + update-props = { + alsa.buffer-bytes = 131072 + } + } + } +] +``` + +# ENVIRONMENT VARIABLES @IDX@ client-env + +See \ref page_man_pipewire_1 "pipewire(1)" for common environment +variables. Many of these also apply to client applications. + +The environment variables also influence ALSA applications that are +using PipeWire's ALSA plugin. + +@PAR@ client-env PIPEWIRE_ALSA +\parblock +This can be an object with properties from `alsa.properties` or `stream.properties` that will +be used to construct the client and streams. + +For example: +``` +PIPEWIRE_ALSA='{ alsa.buffer-bytes=16384 node.name=foo }' aplay ... +``` +Starts aplay with custom properties. +\endparblock + +@PAR@ client-env PIPEWIRE_NODE +\parblock +Instructs the ALSA client to link to a particular sink or source `object.serial` or `node.name`. + +For example: +``` +PIPEWIRE_NODE=alsa_output.pci-0000_00_1b.0.analog-stereo aplay ... +``` +Makes aplay play on the give audio sink. +\endparblock + +# AUTHORS + +The PipeWire Developers <$(PACKAGE_BUGREPORT)>; +PipeWire is available from <$(PACKAGE_URL)> + +# SEE ALSO + +\ref page_module_protocol_pulse "libpipewire-module-protocol-pulse(7)", +\ref page_man_pipewire_conf_5 "pipewire.conf(5)", +\ref page_man_pipewire-pulse_1 "pipewire-pulse(1)", +\ref page_man_pipewire-pulse-modules_7 "pipewire-pulse-modules(7)" diff --git a/doc/dox/programs/pipewire-devices.7.md b/doc/dox/programs/pipewire-devices.7.md new file mode 100644 index 000000000..c9f286e5e --- /dev/null +++ b/doc/dox/programs/pipewire-devices.7.md @@ -0,0 +1,411 @@ +\page page_man_pipewire-devices_7 pipewire-devices + +PipeWire device and node property reference. + +\tableofcontents + +# DESCRIPTION + +Devices such as audio sinks and sources, cameras and Bluetooth +endpoints have properties that can be set in configuration files or at +runtime. + +Technically, nodes and devices have both "properties" and "parameters". +The "properties" appear in \ref page_man_pw-dump_1 "pw-dump(1)" as `"props"`, +and generally control other aspects than hardware features. +The "parameters" are lower-level device settings, and technically +are the configuration of the underlying SPA device/node implementation. + +All device settings are usually configured in the session manager configuration. +For how to configure them, see the session manager documentation. + +In minimal PipeWire setups without a session manager, they can be configured via +\ref pipewire_conf__context_objects "context.objects in pipewire.conf(5)". + +# RUNTIME PARAMETERS @IDX@ device-param + +Most ALSA and virtual device parameters can be configured also at runtime. + +The settings are available in device `Props` in the `params` +field. They can be seen e.g. using `pw-dump ` for an ALSA device: + +```json +{ +... + "Props": [ + { + ... + "params": [ + "audio.channels", + 2, + "audio.rate", + 0, + "audio.format", + "UNKNOWN", + "audio.position", + "[ FL, FR ]", + "audio.allowed-rates", + "[ ]", + "api.alsa.period-size", + 0, + "api.alsa.period-num", + 0, + "api.alsa.headroom", + 0, + "api.alsa.start-delay", + 0, + "api.alsa.disable-mmap", + false, + "api.alsa.disable-batch", + false, + "api.alsa.use-chmap", + false, + "api.alsa.multi-rate", + true, + "latency.internal.rate", + 0, + "latency.internal.ns", + 0, + "clock.name", + "api.alsa.c-1" + ] + } +... +``` + +One or more `params` can be changed using \ref page_man_pw-cli_1 "pw-cli(1)": +``` +pw-cli s Props '{ params = [ "api.alsa.headroom" 1024 ] }' +``` +These settings are not saved and need to be reapplied for each session manager restart. + +# COMMON NODE PROPERTIES @IDX@ device-param + +These are common properties for nodes. + +@PAR@ device-property priority.driver +\parblock +The priority of choosing this device as the driver in the graph. The driver is selected from all linked devices by selecting the device with the highest priority. + +Normally, the session manager assigns higher priority to sources so that they become the driver in the graph. The reason for this is that adaptive resampling should be done on the sinks rather than the source to avoid signal distortion when capturing audio. +\endparblock + +@PAR@ device-property priority.session +The priority for selecting this device as the default device. + +@PAR@ device-property clock.name +\parblock +The name of the clock. This name is auto generated from the card index and stream direction. Devices with the same clock name will not use a resampler to align the clocks. This can be used to link devices together with a shared word clock. + +In Pro Audio mode, nodes from the same device are assumed to have the same clock and no resampling will happen when linked togther. So, linking a capture port to a playback port will not use any adaptive resampling in Pro Audio mode. + +In Non Pro Audio profile, no such assumption is made and adaptive resampling is done in all cases by default. This can also be disabled by setting the same clock.name on the nodes. +\endparblock + +# AUDIO CONVERTER PARAMETERS @IDX@ device-param + +Most audio nodes (ALSA, Bluetooth, ...) have common parameters for the audio +converter. See \ref client_conf__stream_properties "pipewire-client.conf(5) stream.properties" +for explanations. + +@PAR@ device-param clock.quantum-limit +\ref pipewire_conf__default_clock_quantum-limit "See pipewire.conf(5)" + +@PAR@ device-param channelmix.disable +\ref client_conf__channelmix_disable "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.min-volume +\ref client_conf__channelmix_min-volume "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.max-volume +\ref client_conf__channelmix_max-volume "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.normalize +\ref client_conf__channelmix_normalize "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.mix-lfe +\ref client_conf__channelmix_mix-lfe "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.upmix +\ref client_conf__channelmix_upmix "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.lfe-cutoff +\ref client_conf__channelmix_lfe-cutoff "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.fc-cutoff +\ref client_conf__channelmix_fc-cutoff "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.rear-delay +\ref client_conf__channelmix_rear-delay "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.stereo-widen +\ref client_conf__channelmix_stereo-widen "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.hilbert-taps +\ref client_conf__channelmix_hilbert-taps "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.upmix-method +\ref client_conf__channelmix_upmix-method "See pipewire-client.conf(5)" + +@PAR@ device-param channelmix.lock-volumes +UNDOCUMENTED + +@PAR@ device-param resample.quality +\ref client_conf__resample_quality "See pipewire-client.conf(5)" + +@PAR@ device-param resample.disable +\ref client_conf__resample_disable "See pipewire-client.conf(5)" + +@PAR@ device-param resample.peaks +UNDOCUMENTED + +@PAR@ device-param resample.prefill +UNDOCUMENTED + +@PAR@ device-param monitor.channel-volumes +\ref client_conf__monitor_channel-volumes "See pipewire-client.conf(5)" + +@PAR@ device-param dither.noise +\ref client_conf__dither_noise "See pipewire-client.conf(5)" + +@PAR@ device-param dither.method +\ref client_conf__dither_method "See pipewire-client.conf(5)" + +@PAR@ device-param debug.wav-path +\ref client_conf__debug_wav-path "See pipewire-client.conf(5)" + +@PAR@ device-param adapter.auto-port-config +UNDOCUMENTED + + +# ALSA PARAMETERS @IDX@ device-param + +ALSA node parameters: + +@PAR@ device-param audio.channels +The number of audio channels to open the device with. Defaults depends on the profile of the device. + +@PAR@ device-param audio.rate +The audio rate to open the device with. Default is 0, which means to open the device with a rate as close to the graph rate as possible. + +@PAR@ device-param audio.format +The audio format to open the device in. By default this is "UNKNOWN", which will open the device in the best possible bits (32/24/16/8..). You can force a format like S16_LE or S32_LE. + +@PAR@ device-param audio.position +The audio position of the channels in the device. This is auto detected based on the profile. You can configure an array of channel positions, like "[ FL, FR ]". + +@PAR@ device-param audio.allowed-rates +\parblock +The allowed audio rates to open the device with. Default is "[ ]", which means the device can be opened in any supported rate. + +Only rates from the array will be used to open the device. When the graph is running with a rate not listed in the allowed-rates, the resampler will be used to resample to the nearest allowed rate. +\endparblock + +@PAR@ device-param api.alsa.period-size +The period size to open the device in. By default this is 0, which will open the device in the default period size to minimize latency. + +@PAR@ device-param api.alsa.period-num +The amount of periods to use in the device. By default this is 0, which means to use as many as possible. + +@PAR@ device-param api.alsa.headroom +The amount of extra space to keep in the ringbuffer. The default is 0. Higher values can be configured when the device read and write pointers are not accurately reported. + +@PAR@ device-param api.alsa.start-delay +Some devices require a startup period. The default is 0. Higher values can be set to send silence samples to the device first. + +@PAR@ device-param api.alsa.disable-mmap +Disable mmap operation of the device and use the ALSA read/write API instead. Default is false, mmap is preferred. + +@PAR@ device-param api.alsa.disable-batch +Ignore the ALSA batch flag. If the batch flag is set, ALSA will need an extra period to update the read/write pointers. Ignore this flag from ALSA can reduce the latency. Default is false. + +@PAR@ device-param api.alsa.use-chmap +Use the driver provided channel map. Default is false because many drivers don't report this correctly. + +@PAR@ device-param api.alsa.multi-rate +UNDOCUMENTED + +@PAR@ device-param api.alsa.htimestamp +UNDOCUMENTED + +@PAR@ device-param api.alsa.disable-tsched +UNDOCUMENTED + +@PAR@ device-param api.alsa.auto-link +UNDOCUMENTED + +@PAR@ device-param latency.internal.rate +Static set the device systemic latency, in samples at playback rate. + +@PAR@ device-param latency.internal.ns +Static set the device systemic latency, in nanoseconds. + +@PAR@ device-param api.alsa.path +UNDOCUMENTED + +@PAR@ device-param api.alsa.open.ucm +UNDOCUMENTED + +@PAR@ device-param api.alsa.bind-ctls +UNDOCUMENTED + +@PAR@ device-param iec958.codecs +UNDOCUMENTED + +# BLUETOOTH PARAMETERS @IDX@ device-param + +The following are global Bluetooth parameters, not specific to a +specific device or node: + +@PAR@ device-param bluez5.roles +\parblock +Enabled roles (default: [ a2dp_sink a2dp_source bap_sink bap_source hfp_hf hfp_ag ]) + +Currently some headsets (Sony WH-1000XM3) are not working with +both hsp_ag and hfp_ag enabled, so by default we enable only HFP. + +Supported roles: +- hsp_hs (HSP Headset), +- hsp_ag (HSP Audio Gateway), +- hfp_hf (HFP Hands-Free), +- hfp_ag (HFP Audio Gateway) +- a2dp_sink (A2DP Audio Sink) +- a2dp_source (A2DP Audio Source) +- bap_sink (LE Audio Basic Audio Profile Sink) +- bap_source (LE Audio Basic Audio Profile Source) +\endparblock + +@PAR@ device-param bluez5.codecs +Enabled A2DP codecs (default: all). +Possible values: sbc sbc_xq aac aac_eld aptx aptx_hd aptx_ll aptx_ll_duplex faststream faststream_duplex lc3plus_h3 ldac opus_05 opus_05_51 opus_05_71 opus_05_duplex opus_05_pro opus_g lc3 + +@PAR@ device-param bluez5.default.rate +Default audio rate. + +@PAR@ device-param bluez5.default.channels +Default audio channels. + +@PAR@ device-param bluez5.hfphsp-backend +HFP/HSP backend (default: native). Available values: any, none, hsphfpd, ofono, native + +@PAR@ device-param bluez5.hfphsp-backend-native-modem + +@PAR@ device-param bluez5.dummy-avrcp player +Register dummy AVRCP player. Some devices have wrongly functioning +volume or playback controls if this is not enabled. Default: false + +@PAR@ device-param bluez5.enable-sbc-xq +Override device quirk list and enable SBC-XQ for devices for which it is disabled. + +@PAR@ device-param bluez5.enable-msbc +Override device quirk list and enable MSBC for devices for which it is disabled. + +@PAR@ device-param bluez5.enable-hw-volume +Override device quirk list and enable hardware volume fo devices for which it is disabled. + +@PAR@ device-param bluez5.hw-offload-sco +\parblock +HFP/HSP hardware offload SCO support (default: false). + +This feature requires a custom configuration that routes SCO audio to ALSA nodes, +in a platform-specific way. See `tests/examples/bt-pinephone.lua` in WirePlumber for an example. +Do not enable this setting if you don't know what all this means, as it won't work. +\endparblock + +@PAR@ device-param bluez5.a2dp.opus.pro.channels = 3 +PipeWire Opus Pro audio profile channel count. + +@PAR@ device-param bluez5.a2dp.opus.pro.coupled-streams = 1 +PipeWire Opus Pro audio profile coupled stream count. + +@PAR@ device-param bluez5.a2dp.opus.pro.locations = "FL,FR,LFE" +PipeWire Opus Pro audio profile audio channel locations. + +@PAR@ device-param bluez5.a2dp.opus.pro.max-bitrate = 600000 +PipeWire Opus Pro audio profile max bitrate. + +@PAR@ device-param bluez5.a2dp.opus.pro.frame-dms = 50 +PipeWire Opus Pro audio profile frame duration (1/10 ms). + +@PAR@ device-param bluez5.a2dp.opus.pro.bidi.channels = 1 +PipeWire Opus Pro audio profile duplex channels. + +@PAR@ device-param bluez5.a2dp.opus.pro.bidi.coupled-streams = 0 +PipeWire Opus Pro audio profile duplex coupled stream count. + +@PAR@ device-param bluez5.a2dp.opus.pro.bidi.locations = "FC" +PipeWire Opus Pro audio profile duplex coupled channel locations. + +@PAR@ device-param bluez5.a2dp.opus.pro.bidi.max-bitrate = 160000 +PipeWire Opus Pro audio profile duplex max bitrate. + +@PAR@ device-param bluez5.a2dp.opus.pro.bidi.frame-dms = 400 +PipeWire Opus Pro audio profile duplex frame duration (1/10 ms). + +## Device parameters + +@PAR@ device-param bluez5.auto-connect +Auto-connect devices on start up. Disabled by default if +the property is not specified. + +@PAR@ device-param bluez5.hw-volume = [ PROFILE1 PROFILE2... ] +Profiles for which to enable hardware volume control (default: [ hfp_ag hsp_ag a2dp_source ]). + +@PAR@ device-param bluez5.profile +Initial device profile. This usually has no effect as the session manager +overrides it. + +@PAR@ device-param bluez5.a2dp.ldac.quality +LDAC encoding quality +Available values: +- auto (Adaptive Bitrate, default) +- hq (High Quality, 990/909kbps) +- sq (Standard Quality, 660/606kbps) +- mq (Mobile use Quality, 330/303kbps) + +@PAR@ device-param bluez5.a2dp.aac.bitratemode +AAC variable bitrate mode. +Available values: 0 (cbr, default), 1-5 (quality level) + +@PAR@ device-param bluez5.a2dp.opus.pro.application = "audio" +PipeWire Opus Pro Audio encoding mode: audio, voip, lowdelay + +@PAR@ device-param bluez5.a2dp.opus.pro.bidi.application = "audio" +PipeWire Opus Pro Audio duplex encoding mode: audio, voip, lowdelay + +## Node parameters + +@PAR@ device-param bluez5.media-source-role +\parblock +Media source role for Bluetooth clients connecting to +this instance. Available values: + - playback: playing stream to speakers + - input: appear as source node. +\endparblock + +# ALSA CARD PROFILES @IDX@ device-param + +The sound card profiles ("Analog stereo", "Analog stereo duplex", ...) except "Pro Audio" come from two sources: + +- UCM: ALSA Use Case Manager: the profile configuration system from ALSA. See https://github.com/alsa-project/alsa-ucm-conf/ +- ACP ("Alsa Card Profiles"): Pulseaudio's profile system ported to PipeWire. See https://www.freedesktop.org/wiki/Software/PulseAudio/Backends/ALSA/Profiles/ + +See the above links on how to configure these systems. + +For ACP, PipeWire looks for the profile configuration files under + +- ~/.config/alsa-card-profile +- /etc/alsa-card-profile +- /usr/share/alsa-card-profile/mixer`. + +The `path` and `profile-set` files are in subdirectories `paths` and `profile-sets` of these directories. +It is possible to override individual files locally by putting a modified copy into the ACP directories under `~/.config` or `/etc`. + +# AUTHORS + +The PipeWire Developers <$(PACKAGE_BUGREPORT)>; +PipeWire is available from <$(PACKAGE_URL)> + +# SEE ALSO + +\ref page_man_pipewire_conf_5 "pipewire.conf(5)" diff --git a/doc/dox/programs/pipewire-jack.conf.5.md b/doc/dox/programs/pipewire-jack.conf.5.md new file mode 100644 index 000000000..cae770fbd --- /dev/null +++ b/doc/dox/programs/pipewire-jack.conf.5.md @@ -0,0 +1,339 @@ +\page page_man_pipewire-jack_conf_5 jack.conf + +The PipeWire JACK client configuration file. + +\tableofcontents + +# SYNOPSIS + +*$XDG_CONFIG_HOME/pipewire/jack.conf* + +*$(PIPEWIRE_CONFIG_DIR)/jack.conf* + +*$(PIPEWIRE_CONFDATADIR)/jack.conf* + +*$(PIPEWIRE_CONFDATADIR)/jack.conf.d/* + +*$(PIPEWIRE_CONFIG_DIR)/jack.conf.d/* + +*$XDG_CONFIG_HOME/pipewire/jack.conf.d/* + +# DESCRIPTION + +Configuration for PipeWire native clients, and for PipeWire's ALSA +plugin. + +A PipeWire native client program selects the default config to load, +and if nothing is specified, it usually loads `client.conf`. + +The ALSA plugin uses the `client-rt.conf` file, as do some PipeWire +native clients such as \ref page_man_pw-cat_1 "pw-cat(1)". + +The configuration file format is the same as for `pipewire.conf(5)`. + +# CONFIGURATION FILE SECTIONS + +The same sections as in \ref page_man_pipewire_conf_5 "pipewire.conf(5)" +are available. However, a client usually sets the +`core.daemon` property to false, and has a limited set of +`context.spa-libs` usually only to create audio nodes and a poll loop. + +\par jack.properties +JACK client configuration. + +\par jack.rules +JACK client match rules. + +# JACK PROPERTIES @IDX@ jack.conf + +The configuration file can contain an extra JACK specific section called `jack.properties` like this: +``` +... +jack.properties = { + #rt.prio = 88 + #node.latency = 1024/48000 + #node.lock-quantum = true + #node.force-quantum = 0 + #jack.show-monitor = true + #jack.merge-monitor = true + #jack.show-midi = true + #jack.short-name = false + #jack.filter-name = false + #jack.filter-char = " " + # + # allow: Don't restrict self connect requests + # fail-external: Fail self connect requests to external ports only + # ignore-external: Ignore self connect requests to external ports only + # fail-all: Fail all self connect requests + # ignore-all: Ignore all self connect requests + #jack.self-connect-mode = allow + #jack.locked-process = true + #jack.default-as-system = false + #jack.fix-midi-events = true + #jack.global-buffer-size = false + #jack.passive-links = false + #jack.max-client-ports = 768 + #jack.fill-aliases = false + #jack.writable-input = false + +} +``` + +See `stream.properties` in +\ref client_conf__stream_properties "pipewire-client.conf(5)" for +an explanation of the generic node properties. + +It is also possible to have per-client settings, see Match Rules below. + +@PAR@ jack.conf rt.prio +To limit the realtime priority that jack clients can acquire. + +@PAR@ jack.conf node.latency +To force a specific minimum buffer size for the JACK applications, configure: +``` +node.latency = 1024/48000 +``` +This configures a buffer-size of 1024 samples at 48KHz. If the graph is running at a different sample rate, the buffer-size will be adjusted accordingly. + +@PAR@ jack.conf node.lock-quantum +To make sure that no automatic quantum is changes while JACK applications are running, configure: +``` +node.lock-quantum = true +``` +The quantum can then only be changed by metadata or when an application is started with node.force-quantum. JACK Applications will also be able to use jack_set_buffersize() to override the quantum. + +@PAR@ jack.conf node.force-quantum +To force the quantum to a certain value and avoid changes to it: +``` + node.force-quantum = 1024 +``` +The quantum can then only be changed by metadata or when an application is started with node.force-quantum (or JACK applications that use jack_set_buffersize() to override the quantum). + +@PAR@ jack.conf jack.show-monitor +Show the Monitor client and its ports. + +@PAR@ jack.conf jack.merge-monitor +\parblock +Exposes the capture ports and monitor ports on the same JACK device client. This is how JACK presents monitor ports to the clients. The default is however *not* to merge them together because this results in more user friendly user interfaces, usually. An extra client with a `Monitor` suffix is created that contains the monitor ports. + +For example, this is (part of) the output of `jack_lsp` with the default setting (`jack.merge-monitor = false`): + +Compare: + +| `jack.merge-monitor = true` | `jack.merge-monitor = false` | +|:--|:--| +| Built-in Audio Analog Stereo:playback_FL | Built-in Audio Analog Stereo:playback_FL +| Built-in Audio Analog Stereo:monitor_FL | Built-in Audio Analog Stereo Monitor:monitor_FL +| Built-in Audio Analog Stereo:playback_FR | Built-in Audio Analog Stereo:playback_FR +| Built-in Audio Analog Stereo:monitor_FR |Built-in Audio Analog Stereo Monitor:monitor_FR +\endparblock + +@PAR@ jack.conf jack.show-midi +Show the MIDI clients and their ports. + +@PAR@ jack.conf jack.short-name +\parblock +To use shorter names for the device client names use `jack.short-name = true`. Compare: + +| `jack.short-name = true` | `jack.short-name = false` | +|:--|:--| +| HDA Intel PCH:playback_FL | Built-in Audio Analog Stereo:playback_FL +| HDA Intel PCH Monitor:monitor_FL | Built-in Audio Analog Stereo Monitor:monitor_FL +| HDA Intel PCH:playback_FR | Built-in Audio Analog Stereo:playback_FR +| HDA Intel PCH Monitor:monitor_FR |Built-in Audio Analog Stereo Monitor:monitor_FR +\endparblock + +@PAR@ jack.conf jack.filter-name +@PAR@ jack.conf jack.filter-char +Will replace all special characters with `jack.filter-char`. For clients the special characters are ` ()[].:*$` and for ports they are ` ()[].*$`. Use this option when a client is not able to deal with the special characters. (and older version of PortAudio was known to use the client and port names as a regex, and thus failing when there are regex special characters in the name). + +@PAR@ jack.conf jack.self-connect-mode +\parblock +Restrict a client from making connections to and from itself. Possible values and their meaning are summarized as: + +| Value | Behavior +|:--|:--| +| `allow` | Don't restrict self connect requests. +| `fail-external` | Fail self connect requests to external ports only. +| `ignore-external` | Ignore self connect requests to external ports only. +| `fail-all` | Fail all self connect requests. +| `ignore-all` | Ignore all self connect requests. +\endparblock + +@PAR@ jack.conf jack.locked-process +Make sure the process and callbacks can not be called at the same time. This is the +normal operation but it can be disabled in case a specific client can handle this. + +@PAR@ jack.conf jack.default-as-system +\parblock +Name the default source and sink as `system` and number the ports to maximize +compatibility with JACK programs. + +| `jack.default-as-system = false` | `jack.default-as-system = true` | +|:--|:--| +| HDA Intel PCH:playback_FL | system:playback_1 +| HDA Intel PCH Monitor:monitor_FL | system:monitor_1 +| HDA Intel PCH:playback_FR | system:playback_2 +| HDA Intel PCH Monitor:monitor_FR | system:monitor_2 +\endparblock + +@PAR@ jack.conf jack.fix-midi-events +Fix NoteOn events with a 0 velocity to NoteOff. This is standard behaviour in JACK and is thus +enabled by default to maximize compatibility. Especially LV2 plugins do not allow NoteOn +with 0 velocity. + +@PAR@ jack.conf jack.global-buffer-size +When a client has this option, buffersize changes will be applied globally and permanently for all PipeWire clients using the metadata. + +@PAR@ jack.conf jack.passive-links +Makes JACK clients make passive links. This option only works when the server link-factory was configured with the `allow.link.passive` option. + +@PAR@ jack.conf jack.max-client-ports +Limit the number of allowed ports per client to this value. + +@PAR@ jack.conf jack.fill-aliases +Automatically set the port alias1 and alias2 on the ports. + +@PAR@ jack.conf jack.writable-input +\parblock +Makes the input buffers writable. This is the default because some JACK clients write to the +input buffer. This however can cause corruption in other clients when they are also reading +from the buffer. + +Set this to true to avoid buffer corruption if you are only dealing with non-buggy clients. +\endparblock + +# MATCH RULES @IDX@ jack.conf + +`jack.rules` provides an `update-props` action that takes an object with properties that are updated +on the client and node object of the jack client. + +Add a `jack.rules` section in the config file like this: + +``` +jack.rules = [ + { + matches = [ + { + # all keys must match the value. ! negates. ~ starts regex. + application.process.binary = "jack_simple_client" + } + ] + actions = { + update-props = { + node.latency = 512/48000 + } + } + } + { + matches = [ + { + client.name = "catia" + } + ] + actions = { + update-props = { + jack.merge-monitor = true + } + } + } +] +``` +Will set the latency of jack_simple_client to 512/48000 and makes Catia see the monitor client merged with the playback client. + +# ENVIRONMENT VARIABLES @IDX@ jack-env + +See \ref page_man_pipewire_1 "pipewire(1)" for common environment +variables. Many of these also apply to JACK client applications. + +Environment variables can be used to control the behavior of the PipeWire JACK client library. + +@PAR@ jack-env PIPEWIRE_NOJACK +@PAR@ jack-env PIPEWIRE_INTERNAL +When any of these variables is set, the JACK client library will refuse to open a client. The `PIPEWIRE_INTERNAL` variable is set by the PipeWire main daemon to avoid self connections. + +@PAR@ jack-env PIPEWIRE_PROPS +Adds/overrides the properties specified in the `jack.conf` file. Check out the output of this: +``` +> PIPEWIRE_PROPS='{ jack.short-name=true jack.merge-monitor=true }' jack_lsp +... +HDA Intel PCH:playback_FL +HDA Intel PCH:monitor_FL +HDA Intel PCH:playback_FR +HDA Intel PCH:monitor_FR +... +``` + +@PAR@ jack-env PIPEWIRE_LATENCY +\parblock +``` +PIPEWIRE_LATENCY=/ +``` +A quick way to configure the maximum buffer-size for a client. It will run this client with the specified buffer-size (or smaller). + +`PIPEWIRE_LATENCY=256/48000 jack_lsp` is equivalent to `PIPEWIRE_PROPS='{ node.latency=256/48000 }' jack_lsp` + +A better way to start a jack session in a specific buffer-size is to force it with: +``` +pw-metadata -n settings 0 clock.force-quantum +``` +This always works immediately and the buffer size will not change until the quantum is changed back to 0. +\endparblock + +@PAR@ jack-env PIPEWIRE_RATE +\parblock +``` +PIPEWIRE_RATE=1/ +``` + +A quick way to configure the rate of the graph. It will try to switch the samplerate of the graph. This can usually only be done with the graph is idle and the rate is part of the allowed sample rates. + +`PIPEWIRE_RATE=1/48000 jack_lsp` is equivalent to `PIPEWIRE_PROPS='{ node.rate=1/48000 }' jack_lsp` + +A better way to start a jack session in a specific rate is to force the rate with: +``` +pw-metadata -n settings 0 clock.force-rate +``` +This always works and the samplerate does not need to be in the allowed rates. The rate will also not change until it is set back to 0. +\endparblock + +@PAR@ jack-env PIPEWIRE_QUANTUM +\parblock +``` +PIPEWIRE_QUANTUM=/ +``` + +Is similar to using `PIPEWIRE_LATENCY=/` and `PIPEWIRE_RATE=1/` (see above), except that it is not just a suggestion but it actively *forces* the graph to change the rate and quantum. It can be used to set both a buffersize and samplerate at the same time. + +When 2 applications force a quantum, the last one wins. When the winning app is stopped, the quantum of the previous app is restored. +\endparblock + +@PAR@ jack-env PIPEWIRE_LINK_PASSIVE +\parblock +``` +PIPEWIRE_LINK_PASSIVE=true qjackctl +``` +Make this client create passive links only. All links created by the client will be marked passive and will not keep the sink/source busy. + +You can use this to link filters to devices. When there is no client connected to the filter, only passive links remain between the filter and the device and the device will become idle and suspended. +\endparblock + +@PAR@ jack-env PIPEWIRE_NODE +\parblock +``` +PIPEWIRE_NODE= +``` +Will sort the ports so that only the ports of the node with are listed. You can use this to force an application to only deal with the ports of a certain node, for example when auto connecting. +\endparblock + +# AUTHORS + +The PipeWire Developers <$(PACKAGE_BUGREPORT)>; +PipeWire is available from <$(PACKAGE_URL)> + +# SEE ALSO + +\ref page_module_protocol_pulse "libpipewire-module-protocol-pulse(7)", +\ref page_man_pipewire_conf_5 "pipewire.conf(5)", +\ref page_man_pipewire-pulse_1 "pipewire-pulse(1)", +\ref page_man_pipewire-pulse-modules_7 "pipewire-pulse-modules(7)" diff --git a/doc/dox/programs/pipewire-pulse.1.md b/doc/dox/programs/pipewire-pulse.1.md index 90ed98f16..d77bd989e 100644 --- a/doc/dox/programs/pipewire-pulse.1.md +++ b/doc/dox/programs/pipewire-pulse.1.md @@ -28,6 +28,20 @@ Show version information. \par -c | \--config=FILE Load the given config file (Default: pipewire-pulse.conf). +# ENVIRONMENT VARIABLES + +The generic \ref pipewire-env "pipewire(1) environment variables" +are supported. + +In addition: + +@PAR@ pulse-env PULSE_RUNTIME_PATH + +@PAR@ pulse-env XDG_RUNTIME_DIR + +Directory where to create the native protocol pulseaudio socket. + + # AUTHORS The PipeWire Developers <$(PACKAGE_BUGREPORT)>; diff --git a/doc/dox/programs/pipewire-pulse.conf.5.md b/doc/dox/programs/pipewire-pulse.conf.5.md index fe94352f3..064a9277c 100644 --- a/doc/dox/programs/pipewire-pulse.conf.5.md +++ b/doc/dox/programs/pipewire-pulse.conf.5.md @@ -2,6 +2,8 @@ The PipeWire Pulseaudio server configuration file +\tableofcontents + # SYNOPSIS *$XDG_CONFIG_HOME/pipewire/pipewire-pulse.conf* @@ -26,6 +28,14 @@ settings. # CONFIGURATION FILE SECTIONS +\par stream.properties +Dictionary. These properties configure the PipeWire Pulseaudio server +properties. + +\par stream.rules +Dictionary. These properties configure the PipeWire Pulseaudio server +properties. + \par pulse.properties Dictionary. These properties configure the PipeWire Pulseaudio server properties. @@ -43,6 +53,129 @@ for the detailed description. In addition, the general PipeWire daemon configuration sections apply, see \ref page_man_pipewire_conf_5 "pipewire.conf(5)". +# STREAM PROPERTIES @IDX@ pipewire-pulse.conf + +The `stream.properties` section contains properties for streams created +by the pipewire-pulse server. + +Available options are described in +\ref client_conf__stream_properties "pipewire-client.conf(5) stream.properties". + +Some of these properties map to the PulseAudio `/etc/pulse/default.pa` config entries as follows: + +| PulseAudio | PipeWire | Notes | +| ------------------------------ | --------------------- | -------------------- | +| remixing-use-all-sink-channels | channelmix.upmix | | +| remixing-produce-lfe | channelmix.lfe-cutoff | Set to > 0 to enable | +| remixing-consume-lfe | channelmix.mix-lfe | | +| lfe-crossover-freq | channelmix.lfe-cutoff | | + +## Example + +```css +pulse.properties = { + #node.latency = 1024/48000 + #node.autoconnect = true + #resample.disable = false + #resample.quality = 4 + #monitor.channel-volumes = false + #channelmix.disable = false + #channelmix.min-volume = 0.0 + #channelmix.max-volume = 10.0 + #channelmix.normalize = false + #channelmix.mix-lfe = true + #channelmix.upmix = true + #channelmix.upmix-method = psd # none, simple + #channelmix.lfe-cutoff = 150.0 + #channelmix.fc-cutoff = 12000.0 + #channelmix.rear-delay = 12.0 + #channelmix.stereo-widen = 0.0 + #channelmix.hilbert-taps = 0 + #dither.noise = 0 + #dither.method = none # rectangular, triangular, triangular-hf, wannamaker3, shaped5 + #debug.wav-path = "" +} +``` + +# STREAM RULES @IDX@ pipewire-pulse.conf + +The `stream.rules` section works the same as +\ref client_conf__stream_rules "pipewire-client.conf(5) stream.rules". + +# PULSEAUDIO PROPERTIES @IDX@ pipewire-pulse.conf + +For `pulse.properties` section, +see \ref page_module_protocol_pulse "libpipewire-module-protocol-pulse(7)" +for available options. + +# PULSEAUDIO RULES @IDX@ pipewire-pulse.conf + +For each client, a set of rules can be written in `pulse.rules` +section to configure quirks of the client or to force some pulse +specific stream configuration. + +The general look of this section is as follows and follows the layout of +\ref pipewire_conf__match_rules "match rules, see pipewire(1)". + +See \ref page_module_protocol_pulse "libpipewire-module-protocol-pulse(7)" +for available options. + +## Example + +```css +pulse.rules = [ + { + # skype does not want to use devices that don't have an S16 sample format. + matches = [ + { application.process.binary = "teams" } + { application.process.binary = "teams-insiders" } + { application.process.binary = "skypeforlinux" } + ] + actions = { quirks = [ force-s16-info ] } + } + { + # speech dispatcher asks for too small latency and then underruns. + matches = [ { application.name = "~speech-dispatcher*" } ] + actions = { + update-props = { + pulse.min.req = 1024/48000 # 21ms + pulse.min.quantum = 1024/48000 # 21ms + } + } + } +] +``` + +# PULSEAUDIO COMMANDS @IDX@ pipewire-pulse.conf + +As part of the server startup procedure you can execute some +additional commands with the `pulse.cmd` section in +`pipewire-pulse.conf`. + +```css +... +pulse.cmd = [ + { cmd = "load-module" args = "module-always-sink" flags = [ ] } + { cmd = "load-module" args = "module-switch-on-connect" } + { cmd = "load-module" args = "module-gsettings" flags = [ "nofail" ] } +] +... +``` + +Additional commands can also be run via the +\ref pipewire_conf__context_exec "context.exec section, see pipewire.conf(5)". + +Supported commands: + +@PAR@ pipewire-pulse.conf load-module +Load the specified Pulseaudio module on startup, as if using **pactl(1)** +to load the module. + +# PULSEAUDIO MODULES @IDX@ pipewire-pulse.conf + +For contents of section `pulse.modules`, +see \ref page_man_pipewire-pulse-modules_7 "pipewire-pulse-modules(7)". + # AUTHORS The PipeWire Developers <$(PACKAGE_BUGREPORT)>; diff --git a/doc/dox/programs/pipewire.1.md b/doc/dox/programs/pipewire.1.md index 9b6c389d5..35cab4afb 100644 --- a/doc/dox/programs/pipewire.1.md +++ b/doc/dox/programs/pipewire.1.md @@ -2,6 +2,8 @@ The PipeWire media server +\tableofcontents + # SYNOPSIS **pipewire** \[*options*\] @@ -29,6 +31,204 @@ Show version information. \par -c | \--config=FILE Load the given config file (Default: pipewire.conf). +# RUNTIME SETTINGS @IDX@ pipewire + +A PipeWire daemon will also expose a settings metadata object that can +be used to change some settings at runtime. + +Normally these settings can bypass any of the restrictions listed in +the config options above, such as quantum and samplerate values. + +The settings can be modified using \ref page_man_pw-metadata_1 "pw-metadata(1)": +``` +pw-metadata -n settings # list settings +pw-metadata -n settings 0 # list server settings +pw-metadata -n settings 0 log.level 2 # modify a server setting +``` + +@PAR@ pipewire-settings log.level = INTEGER +Change the log level of the PipeWire daemon. + +@PAR@ pipewire-settings clock.rate = INTEGER +The default samplerate. + +@PAR@ pipewire-settings clock.allowed-rates = [ RATE1 RATE2... ] +The allowed samplerates. + +@PAR@ pipewire-settings clock.force-rate = INTEGER +\parblock +Temporarily forces the graph to operate in a fixed sample rate. +Both DSP processing and devices will switch to the new rate immediately. +Running streams (PulseAudio, native and ALSA applications) will automatically +resample to match the new rate. + +Set the value to 0 to allow the sample rate to vary again. +\endparblock + +@PAR@ pipewire-settings clock.quantum = INTEGER +The default quantum (buffer size). + +@PAR@ pipewire-settings clock.min-quantum = INTEGER +Smallest quantum to be used. + +@PAR@ pipewire-settings clock.max-quantum = INTEGER +Largest quantum to be used. + +@PAR@ pipewire-settings clock.force-quantum = INTEGER +\parblock +Temporarily force the graph to operate in a fixed quantum. + +Set the value to 0 to allow the quantum to vary again. +\endparblock + +# ENVIRONMENT VARIABLES @IDX@ pipewire-env + +## Socket directories + +@PAR@ pipewire-env PIPEWIRE_RUNTIME_DIR + +@PAR@ pipewire-env XDG_RUNTIME_DIR + +@PAR@ pipewire-env USERPROFILE +Used to find the PipeWire socket on the server (and native clients). + +@PAR@ pipewire-env PIPEWIRE_CORE +Name of the socket to make. + +@PAR@ pipewire-env PIPEWIRE_REMOTE +Name of the socket to connect to. + +@PAR@ pipewire-env PIPEWIRE_DAEMON +If set to true then the process becomes a new PipeWire server. + +## Config directories, config file name and prefix + +@PAR@ pipewire-env PIPEWIRE_CONFIG_DIR + +@PAR@ pipewire-env XDG_CONFIG_HOME + +@PAR@ pipewire-env HOME +Used to find the config file directories. + +@PAR@ pipewire-env PIPEWIRE_CONFIG_PREFIX + +@PAR@ pipewire-env PIPEWIRE_CONFIG_NAME +Used to override the application provided +config prefix and config name. + +@PAR@ pipewire-env PIPEWIRE_NO_CONFIG +Enables (false) or disables (true) overriding on the default configuration. + +## Context information + +As part of a client context, the following information is collected +from environment variables and placed in the context properties: + +@PAR@ pipewire-env LANG +The current language in `application.language`. + +@PAR@ pipewire-env XDG_SESSION_ID +Set as the `application.process.session-id` property. + +@PAR@ pipewire-env DISPLAY +Is set as the `window.x11.display` property. + +## Modules + +@PAR@ pipewire-env PIPEWIRE_MODULE_DIR +Sets the directory where to find PipeWire modules. + +@PAR@ pipewire-env SPA_SUPPORT_LIB +The name of the SPA support lib to load. This can be used to switch to +an alternative support library, for example, to run on the EVL realtime kernel. + +## Logging options + +@PAR@ pipewire-env JOURNAL_STREAM +Is used to parse the stream used for the journal. This is usually configured by +systemd. + +@PAR@ pipewire-env PIPEWIRE_LOG_LINE +Enables the logging of line numbers. Default true. + +@PAR@ pipewire-env PIPEWIRE_LOG +Specifies a log file to use instead of the default logger. + +@PAR@ pipewire-env PIPEWIRE_LOG_SYSTEMD +Enables the use of systemd for the logger, default true. + +## Other settings + +@PAR@ pipewire-env PIPEWIRE_CPU +Selects the CPU and flags. This is a bitmask of any of the \ref CPU flags + +@PAR@ pipewire-env PIPEWIRE_VM +Selects the Virtual Machine PipeWire is running on. This can be any of the \ref CPU "VM" +types. + +@PAR@ pipewire-env DISABLE_RTKIT +Disables the use of RTKit or the Realtime Portal for realtime scheduling. + +@PAR@ pipewire-env NO_COLOR +Disables the use of colors in the console output. + +## Debugging options + +@PAR@ pipewire-env PIPEWIRE_DLCLOSE +Enables (true) or disables (false) the use of dlclose when a shared library +is no longer in use. When debugging, it might make sense to disable dlclose to be able to get +debugging symbols from the object. + +## Stream options + +@PAR@ pipewire-env PIPEWIRE_NODE +Makes a stream connect to a specific `object.serial` or `node.name`. + +@PAR@ pipewire-env PIPEWIRE_PROPS +Adds extra properties to a stream or filter. + +@PAR@ pipewire-env PIPEWIRE_QUANTUM +Forces a specific rate and buffer-size for the stream or filter. + +@PAR@ pipewire-env PIPEWIRE_LATENCY +Sets a specific latency for a stream or filter. This is only a suggestion but +the configured latency will not be larger. + +@PAR@ pipewire-env PIPEWIRE_RATE +Sets a rate for a stream or filter. This is only a suggestion. The rate will be +switched when the graph is idle. + +@PAR@ pipewire-env PIPEWIRE_AUTOCONNECT +Overrides the default stream autoconnect settings. + +## Plugin options + +@PAR@ pipewire-env SPA_PLUGIN_DIR +Is used to locate SPA plugins. + +@PAR@ pipewire-env SPA_DATA_DIR +Is used to locate plugin specific config files. This is used by the +bluetooth plugin currently to locate the quirks database. + +@PAR@ pipewire-env SPA_DEBUG +Set the log level for SPA plugins. This is usually controlled by the `PIPEWIRE_DEBUG` variable +when the plugins are managed by PipeWire but some standalone tools (like spa-inspect) uses this +variable. + +@PAR@ pipewire-env ACP_BUILDDIR +If set, the ACP profiles are loaded from the builddir. + +@PAR@ pipewire-env ACP_PATHS_DIR + +@PAR@ pipewire-env ACP_PROFILES_DIR +Used to locate the ACP paths and profile directories respectively. + +@PAR@ pipewire-env LADSPA_PATH +Comma separated list of directories where the ladspa plugins can be found. + +@PAR@ pipewire-env LIBJACK_PATH +Directory where the jack1 or jack2 libjack.so can be found. + # AUTHORS The PipeWire Developers <$(PACKAGE_BUGREPORT)>; diff --git a/doc/dox/programs/pipewire.conf.5.md b/doc/dox/programs/pipewire.conf.5.md index 4abe21605..5edb5b761 100644 --- a/doc/dox/programs/pipewire.conf.5.md +++ b/doc/dox/programs/pipewire.conf.5.md @@ -2,6 +2,8 @@ The PipeWire server configuration file +\tableofcontents + # SYNOPSIS *$XDG_CONFIG_HOME/pipewire/pipewire.conf* @@ -37,7 +39,9 @@ order and the contents of the `*.conf` files inside them are appended to the main configuration file as overrides. Object sections are merged and array sections are appended. -# CONFIGURATION FILE FORMAT +# CONFIGURATION FILE FORMAT @IDX@ pipewire.conf + +The configuration file is in (SPA) JSON format. The configuration file format is grouped into sections. A section is either a dictionary, {}, or an array, \[\]. Dictionary and array entries @@ -53,7 +57,7 @@ or a dictionary. For example: name = [ { k = v1 } { k = v2 } ] # an array of dictionaries ``` -The configuration files can be expressed in full JSON syntax but for +The configuration files can be expressed in standard JSON syntax but for ease of use, a relaxed format may be used where: - `:` to delimit keys and values can be substuted by `=` or a space. @@ -90,6 +94,284 @@ this mode of operation has since been demoted to development aid. Avoid starting a session manager in this way in production environment. \endparblock +# CONTEXT PROPERTIES @IDX@ pipewire.conf + +Available PipeWire properties in `context.properties` and possible +default values. + +@PAR@ pipewire.conf clock.power-of-two-quantum = true +The quantum requests from the clients and the final graph quantum are +rounded down to a power of two. A power of two quantum can be more +efficient for many processing tasks. + +@PAR@ pipewire.conf context.data-loop.library.name.system +The name of the shared library to use for the system functions for the data processing +thread. This can typically be changed if the data thread is running on a realtime +kernel such as EVL. + +@PAR@ pipewire.conf core.daemon = false +Makes the PipeWire process, started with this config, a daemon +process. This means that it will manage and schedule a graph for +clients. You would also want to configure a core.name to give it a +well known name. + +@PAR@ pipewire.conf core.name = pipewire-0 +The name of the PipeWire context. This will also be the name of the +PipeWire socket clients can connect to. + +@PAR@ pipewire.conf cpu.zero.denormals = false +Configures the CPU to zero denormals automatically. This will be +enabled for the data processing thread only, when enabled. + +@PAR@ pipewire.conf default.clock.rate = 48000 +The default clock rate determines the real time duration of the +min/max/default quantums. You might want to change the quantums when +you change the default clock rate to maintain the same duration for +the quantums. + +@PAR@ pipewire.conf default.clock.allowed-rates = [ ] +It is possible to specify up to 32 alternative sample rates. The graph +sample rate will be switched when devices are idle. Note that this is +not enabled by default for now because of various kernel and Bluetooth +issues. + +@PAR@ pipewire.conf default.clock.min-quantum = 32 +Default minimum quantum. + +@PAR@ pipewire.conf default.clock.max-quantum = 8192 +Default maximum quantum. + +@PAR@ pipewire.conf default.clock.quantum = 1024 +Default quantum used when no client specifies one. + +@PAR@ pipewire.conf default.clock.quantum-limit = 8192 +Maximum quantum to reserve space for. + +@PAR@ pipewire.conf default.video.width + +@PAR@ pipewire.conf default.video.height + +@PAR@ pipewire.conf default.video.rate.num + +@PAR@ pipewire.conf default.video.rate.denom + +@PAR@ pipewire.conf library.name.system = support/libspa-support +The name of the shared library to use for the system functions for the main thread. + +@PAR@ pipewire.conf link.max-buffers = 64 +The maximum number of buffers to negotiate between nodes. Note that version < 3 clients +can only support 16 buffers. More buffers is almost always worse than less, latency +and memory wise. + +@PAR@ pipewire.conf log.level = 2 +The default log level used by the process. + +@PAR@ pipewire.conf mem.allow-mlock = true +Try to mlock the memory for the realtime processes. Locked memory will +not be swapped out by the kernel and avoid hickups in the processing +threads. + +@PAR@ pipewire.conf mem.warn-mlock = false +Warn about failures to lock memory. + +@PAR@ pipewire.conf mem.mlock-all = false +Try to mlock all current and future memory by the process. + +@PAR@ pipewire.conf settings.check-quantum = false +Check if the quantum in the settings metadata update is compatible +with the configured limits. + +@PAR@ pipewire.conf settings.check-rate = false +Check if the rate in the settings metadata update is compatible +with the configured limits. + +@PAR@ pipewire.conf support.dbus = true +Enable DBus support. This will enable DBus support in the various modules that require +it. Disable this if you want to globally disable DBus support in the process. + +@PAR@ pipewire.conf vm.overrides = { default.clock.min-quantum = 1024 } +Any property in the vm.overrides property object will override the property +in the context.properties when PipeWire detects it is running in a VM. + +\par CONDITION = true / false +The `context.modules` and `context.objects` sections can declare +additional condition variables, which control whether a specific +module or object to be loaded on startup. + +# SPA LIBRARIES @IDX@ pipewire.conf + +SPA plugins are loaded based on their factory-name. This is a well +known name that uniquely describes the features that the plugin should +have. The `context.spa-libs` section provides a mapping between the +factory-name and the plugin where the factory can be found. + +Factory names can contain a wildcard to group several related factories into one +plugin. The plugin is loaded from the first matching factory-name. + +## Example + +```json +context.spa-libs = { + audio.convert.* = audioconvert/libspa-audioconvert + avb.* = avb/libspa-avb + api.alsa.* = alsa/libspa-alsa + api.v4l2.* = v4l2/libspa-v4l2 + api.libcamera.* = libcamera/libspa-libcamera + api.bluez5.* = bluez5/libspa-bluez5 + api.vulkan.* = vulkan/libspa-vulkan + api.jack.* = jack/libspa-jack + support.* = support/libspa-support + video.convert.* = videoconvert/libspa-videoconvert +} +``` + +# MODULES @IDX@ pipewire.conf + +PipeWire modules to be loaded. See +\ref page_man_libpipewire-modules_7 "libpipewire-modules(7)". + +```json +context.modules = [ + #{ name = MODULENAME + # ( args = { KEY = VALUE ... } ) + # ( flags = [ ( ifexists ) ( nofail ) ] ) + # ( condition = [ { KEY = VALUE ... } ... ] ) + #} + # +] +``` + +\par name +Name of module to be loaded + +\par args = { KEY = VALUE } +Argument to the module + +\par flags = [ ] +Loading flags. `ifexists` to only load module if it exists, +and `nofail` to not fail PipeWire startup if the module fails to load. + +\par condition = [ { KEY = VALUE }, ... ] +Named condition variables, which control whether a module is loaded. + +# CONTEXT OBJECTS @IDX@ pipewire.conf + +The `context.objects` section allows you to make some objects from factories (usually created +by loading modules in `context.modules`). + +```json +context.objects = [ + #{ factory = + # ( args = { = ... } ) + # ( flags = [ ( nofail ) ] ) + # ( condition = [ { = ... } ... ] ) + #} +] +``` +This section can be used to make nodes or links between nodes. + +\par name +Name of module to be loaded + +\par args = { KEY = VALUE } +Argument to the module + +\par flags = [ ] +Loading flags. `ifexists` to only load module if it exists, +and `nofail` to not fail PipeWire startup if the module fails to load. + +\par condition = [ { KEY = VALUE }, ... ] +Named condition variables, which control whether a module is loaded. + +## Example + +This fragment creates a new dummy driver node: + +```json +context.objects = [ + { factory = spa-node-factory + args = { + factory.name = support.node.driver + node.name = Dummy-Driver + node.group = pipewire.dummy + priority.driver = 20000 + } + } +] +``` + +# COMMAND EXECUTION @IDX@ pipewire.conf + +The `context.exec` section can be used to start arbitrary commands as +part of the initialization of the PipeWire program. + +```json +context.exec = [ + #{ path = + # ( args = "" ) + # ( condition = [ { = ... } ... ] ) + #} +] +``` + +\par path +Program to execute. + +\par args +Arguments to the program. + +\par condition +Condition variable definition. + +## Example + +The following fragment executes a pactl command with the given arguments: + +```json +context.exec = [ + { path = "pactl" args = "load-module module-always-sink" } +] +``` + +# MATCH RULES @IDX@ pipewire.conf + +Some configuration files can contain match rules. This makes it +possible to perform some action when an object (usually a node or +stream) is created/updated that matches certain properties. + +The general rules object follows the following pattern: +```json + = [ + { + matches = [ + # any of the following sets of properties are matched, if + # any matches, the actions are executed + { + # = + # all keys must match the value. ! negates. ~ starts regex. + #application.process.binary = "teams" + #application.name = "~speech-dispatcher.*" + } + { + # more matches here... + } + ... + ] + actions = { + = + ... + } + } +] +``` + +The rules is an array of things to match and what actions to perform +when a match is found. + +The available actions and their values depend on the specific rule +that is used. Usually it is possible to update some properties or set +some quirks on the object. + # AUTHORS The PipeWire Developers <$(PACKAGE_BUGREPORT)>; @@ -100,3 +382,5 @@ PipeWire is available from <$(PACKAGE_URL)> \ref page_man_pipewire_1 "pipewire(1)", \ref page_man_pw-mon_1 "pw-mon(1)", \ref page_man_libpipewire-modules_7 "libpipewire-modules(7)" +\ref page_man_pipewire-pulse_conf_5 "pipewire-pulse.conf(5)" +\ref page_man_pipewire-client_conf_5 "pipewire-client.conf(5)" diff --git a/doc/dox/tutorial/index.dox b/doc/dox/tutorial/index.dox index a4fc4d572..9f178e35d 100644 --- a/doc/dox/tutorial/index.dox +++ b/doc/dox/tutorial/index.dox @@ -1,4 +1,4 @@ -/** \page page_tutorial Tutorial +/** \page page_tutorial API Tutorial Welcome to the PipeWire API tutorial. The goal is to learn PipeWire API step-by-step with simple short examples. diff --git a/doc/input-filter-md.py b/doc/input-filter-md.py new file mode 100755 index 000000000..60aa46279 --- /dev/null +++ b/doc/input-filter-md.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +# -*- mode: python; coding: utf-8; eval: (blacken-mode); -*- +r"""input-filter-md.py FILENAME +input-filter-md.py --index FILENAMES... + +Doxygen .md input filter that adds extended syntax. +With --index, generates an index file. +Assumes BUILD_DIR environment variable is set. + +@PAR@
(...) + + Adds an index item and expands to + + \anchor + \par (...) + +@SECREF@
+ + Expands to + + \secreflist + \refitem ... + ... + \endsecreflist + + containing all index items from the specified section. + +# Section title @IDX@
+ + Adds the section title to the index, and expands to an anchor + + # Section title {#key} + +The index keys can be used in \ref and have format + + {section}__{name} + +where the parts are converted to lowercase and _ replaces +non-alphanumerics. + +""" +import sys +import re +import os + + +def index_key(section, name): + key = f"{section}__{name}".lower() + return re.sub(r"[^A-Za-z0-9_-]", "_", key) + + +BUILD_DIR = os.environ["BUILD_DIR"] +PAR_RE = r"^@PAR@\s+([^\s]*)[ \t]+(\S+)(.*)$" +IDX_RE = r"^(#+)(.*)@IDX@[ \t]+(\S+)[ \t]*$" +SECREF_RE = r"^@SECREF@[ \t]+([^\n]*)[ \t]*$" + + +def main(args): + fn = args[0] + with open(fn, "r") as f: + text = f.read() + + def par(m): + section = m.group(1) + name = m.group(2) + rest = m.group(3).strip() + key = index_key(section, name) + return f"\\anchor {key}\n\\par {name} {rest}" + + def idx(m): + level = m.group(1) + title = name = m.group(2).strip() + section = m.group(3) + if title == title.upper(): + name = name.capitalize() + key = index_key(section, name) + return f"{level} {title} {{#{key}}}" + + def secref(m): + import os + import json + + secs = m.group(1).split() + + with open(os.path.join(BUILD_DIR, "index.json"), "r") as f: + index = json.load(f) + + items = {} + + for sec in secs: + if sec not in index: + print(f"{fn}: no index '{sec}'", file=sys.stderr) + else: + for name, key in index[sec].items(): + if name in items: + pkey, psec = items.pop(name) + nname = f"{name} ({sec})" + items[nname] = (key, sec) + if pkey is not None: + pname = f"{name} ({psec})" + items[pname] = (pkey, psec) + items[name] = (None, None) + else: + items[name] = (key, sec) + + text = [r"\secreflist"] + for name, (key, sec) in sorted(items.items()): + if key is not None: + text.append(rf'\refitem {key} "{name}"') + text.append(r"\endsecreflist") + text = "\n".join(text) + return f"{text}\n" + + text = re.sub(PAR_RE, par, text, flags=re.M) + text = re.sub(IDX_RE, idx, text, flags=re.M) + text = re.sub(SECREF_RE, secref, text, flags=re.M) + + print(text) + + +def main_index(args): + import json + + sections = {} + + for fn in set(args): + with open(fn, "r") as f: + load_index(sections, f.read()) + + result = {} + + for section, items in sections.items(): + for name in items: + key = index_key(section, name) + result.setdefault(section, {})[name] = key + + with open(os.path.join(BUILD_DIR, "index.json"), "w") as f: + json.dump(result, f) + + +def load_index(sections, text): + def par(m): + section = m.group(1) + name = m.group(2) + sections.setdefault(section, []).append(name) + return "" + + def idx(m): + name = m.group(2).strip() + section = m.group(3) + if name == name.upper(): + name = name.capitalize() + sections.setdefault(section, []).append(name) + return "" + + text = re.sub(PAR_RE, par, text, flags=re.M) + text = re.sub(IDX_RE, idx, text, flags=re.M) + + +if __name__ == "__main__": + if len(sys.argv) >= 2 and sys.argv[1] == "--index": + main_index(sys.argv[2:]) + elif len(sys.argv) == 2: + main(sys.argv[1:]) + else: + print(__doc__.strip()) + sys.exit(1) diff --git a/doc/meson.build b/doc/meson.build index b04dd003f..05ea7f349 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -15,6 +15,7 @@ doxygen_env.set('PACKAGE_BUGREPORT', 'https://gitlab.freedesktop.org/pipewire/pi doxygen_env.set('PIPEWIRE_CONFIG_DIR', pipewire_configdir) doxygen_env.set('PIPEWIRE_CONFDATADIR', pipewire_confdatadir) doxygen_env.set('SPA_PLUGINDIR', spa_plugindir) +doxygen_env.set('BUILD_DIR', meson.current_build_dir()) dot_found = find_program('dot', required: false).found() summary({'dot (used with doxygen)': dot_found}, bool_yn: true, section: 'Optional programs') @@ -70,6 +71,9 @@ manpage_docs = [ 'dox/programs/pipewire-pulse.conf.5.md', 'dox/programs/pipewire.1.md', 'dox/programs/pipewire.conf.5.md', + 'dox/programs/pipewire-client.conf.5.md', + 'dox/programs/pipewire-jack.conf.5.md', + 'dox/programs/pipewire-devices.7.md', 'dox/programs/pw-cat.1.md', 'dox/programs/pw-cli.1.md', 'dox/programs/pw-config.1.md', @@ -196,6 +200,7 @@ doxygen_env.set('PIPEWIRE_PULSE_MODULES', '
  • ' + '
  • '.join(pulse_mo doxygen_layout = meson.project_source_root() / 'doc' / 'DoxygenLayout.xml' doxygen_filter_c = meson.project_source_root() / 'doc' / 'input-filter.py' doxygen_filter_h = meson.project_source_root() / 'doc' / 'input-filter-h.sh' +doxygen_filter_md = meson.project_source_root() / 'doc' / 'input-filter-md.py' doxyfile_conf.set('inputs', ' '.join(inputs + input_dirs)) doxyfile_conf.set('cssfiles', ' '.join(cssfiles)) @@ -203,6 +208,7 @@ doxyfile_conf.set('layout', doxygen_layout) doxyfile_conf.set('path_prefixes', ' '.join(path_prefixes)) doxyfile_conf.set('c_input_filter', doxygen_filter_c) doxyfile_conf.set('h_input_filter', doxygen_filter_h) +doxyfile_conf.set('md_input_filter', doxygen_filter_md) doxyfile = configure_file(input: 'Doxyfile.in', output: 'Doxyfile', @@ -213,8 +219,15 @@ if docdir == '' docdir = pipewire_datadir / 'doc' / meson.project_name() endif +index_json = custom_target('index.json', + command: [ doxygen_filter_md, '--index', '@INPUT@' ], + input: extra_docs + manpage_docs, + output: 'index.json', + env: doxygen_env +) + html_target = custom_target('pipewire-docs', - input: [ doxyfile, doxygen_layout, examples_dox, doxygen_filter_c, doxygen_filter_h ] + inputs + cssfiles, + input: [ doxyfile, doxygen_layout, examples_dox, doxygen_filter_c, doxygen_filter_h, index_json ] + inputs + cssfiles, output: [ 'html' ], command: [ doxygen, doxyfile ], env: doxygen_env,