pipewire-props(7)

πŸ’… pipewire-props(7) πŸ’…

Miscellaneous Information Manual

✨ NAME ✨

pipewire-props β€” PipeWire object property reference. πŸŽ€

🌸 DESCRIPTION 🌸

okay so PipeWire describes and configures audio and video elements with objects of these main types:

  • Node β€” Audio or video sink/source endpoint
  • Device β€” Sound cards, bluetooth devices, cameras, etc. May have multiple nodes.
  • Monitor β€” Finding devices and handling hotplugging
  • Port β€” Audio/video endpoint in a node
  • Link β€” Connection between ports, that transporting audio/video between them.
  • Client β€” Application connected to PipeWire.

All objects have properties (β€œprops”), most of which can be set in configuration files or at runtime when the object is created.

Some of the properties are β€œcommon properties” (for example node.description) and can be set on all objects of the given type. Other properties control settings of a specific kinds of device or node (ALSA, Bluetooth, ...), and have meaning only for those objects.

πŸ› οΈ CUSTOMIZING PROPERTIES πŸ› οΈ

Usually, all device properties are configured in the session manager configuration, see the session manager documentation. Application properties are configured in client.conf (for native PipeWire and ALSA applications), pipewire-pulse.conf (for Pulseaudio applications), and jack.conf (for JACK applications).

In minimal PipeWire setups without a session manager, the device properties can be configured via context.objects in pipewire.conf(5) when creating the devices.

πŸŽ€ Examples πŸŽ€

Device configuration using WirePlumber (requires WirePlumber restart to apply). See WirePlumber configuration

# ~/.config/wireplumber/wireplumber.conf.d/custom-props.conf

monitor.alsa.properties = {
  alsa.udev.expose-busy = true
}

monitor.alsa.rules = [
  {
    matches = [ { device.name = "~alsa_card.pci-.*" } ],
    actions = { update-props = { api.alsa.soft-mixer = true } }
  },
  {
    matches = [ { node.name = "alsa_output.pci-0000_03_00.1.hdmi-stereo-extra3" } ]
    actions = { update-props = { node.description = "Main Audio" } }
  }
]

monitor.alsa-midi.properties = {
  api.alsa.seq.ump = true
}

monitor.bluez.properties = {
  bluez5.hfphsp-backend = ofono
}

monitor.bluez.rules = [
  {
    matches = [ { device.name = "~bluez_card.*" } ],
    actions = { update-props = { bluez5.dummy-avrcp player = true } }
  }
]

Native client configuration (requires client application restart to apply). See pipewire-client.conf(5)

# ~/.config/pipewire/client.conf/custom-props.conf

stream.rules = [
  {
    matches = [ { application.name = "pw-play" } ]
    actions = { update-props = { node.description = "Some pw-cat stream" } }
  }
]

Pulseaudio client configuration (requires pipewire-pulse(1) restart to apply). See pipewire-pulse.conf(5)

# ~/.config/pipewire/pipewire-pulse.conf/custom-props.conf

stream.rules = [
  {
    matches = [ { application.name = "paplay" } ]
    actions = { update-props = { node.description = "Some paplay stream" } }
  }
]

JACK client configuration (requires client restart to apply). See pipewire-jack.conf(5)

# ~/.config/pipewire/jack.conf/custom-props.conf

jack.rules = [
  {
    matches = [ { client.name = "jack_delay" } ]
    actions = { update-props = { node.description = "Some JACK node" } }
  }
]

🎧 COMMON DEVICE PROPERTIES 🎧

These are common properties for devices.

  • device.name # string β€” A (unique) name for the device. It can be used by command-line and other tools to identify the device.
  • device.param.PARAM = { ... } # JSON β€” Set value of a device Param to a JSON value when the device is loaded. This works similarly as pw-cli(1) set-param command. The PARAM should be replaced with the name of the Param to set, ie. for example device.Param.Props = { ... } to set Props.
  • device.plugged # integer β€” when the device was created. As a uint64 in nanoseconds.
  • device.nick # string β€” a short device nickname
  • device.description # string β€” localized human readable device one-line description. Ex. "Foobar USB Headset"
  • device.serial # string β€” Serial number if applicable.
  • device.vendor.id # integer β€” vendor ID if applicable
  • device.vendor.name # string β€” vendor name if applicable
  • device.product.id # integer β€” product ID if applicable
  • device.product.name # string β€” product name if applicable
  • device.class # string β€” device class
  • device.form-factor # string β€” form factor if applicable. One of "internal", "speaker", "handset", "tv", "webcam", "microphone", "headset", "headphone", "hands-free", "car", "hifi", "computer", "portable"
  • device.icon # string β€” icon for the device. A base64 blob containing PNG image data
  • device.icon-name # string β€” an XDG icon name for the device. Ex. "sound-card-speakers-usb"
  • device.intended-roles # string β€” intended use. A space separated list of roles (see media.role) this device is particularly well suited for, due to latency, quality or form factor.
  • device.disabled = false # boolean β€” Disable the creation of this device in session manager.

There are other common device.* properties for technical purposes and not usually user-configurable.

See also

Key Names in the API documentation for a full list.

πŸ¦‹ COMMON NODE PROPERTIES πŸ¦‹

The properties here apply to general audio or video input/output streams, and other nodes such as sinks or sources corresponding to real or virtual devices.

πŸ’– Identifying Properties πŸ’–

These contain properties to identify the node or to display the node in a GUI application.

  • node.name # string β€” 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.
  • node.nick # string β€” A short name for the node.
  • node.description # string β€” A human readable description of the node or stream.
  • media.name β€” 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.
  • media.title β€” A user readable stream title.
  • media.artist β€” A user readable stream artist
  • media.copyright β€” User readable stream copyright information
  • media.software β€” User readable stream generator software information
  • media.language β€” Stream language in POSIX format. Ex: en_GB
  • media.filename β€” File name for the stream
  • media.icon β€” Icon for the media, a base64 blob with PNG image data
  • media.icon-name β€” An XDG icon name for the media. Ex: audio-x-mp3
  • media.comment β€” Extra stream comment
  • media.date β€” Date of the media
  • media.format β€” User readable stream format information
  • object.linger = false β€” If the object should outlive its creator.
  • device.id β€” ID of the device the node belongs to.

🌈 Classifying Properties 🌈

The classifying properties of a node are use for routing the signal to its destination and for configuring the settings.

  • 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"
  • media.category β€” 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.
  • media.role β€” 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.
  • media.class β€” 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..

⏱️ Scheduling Properties ⏱️

  • 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.
  • node.lock-quantum = false β€” 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.
  • node.force-quantum = INTEGER β€” 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.
  • 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.
  • 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.
  • node.force-rate = RATE β€” 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.
  • node.always-process = false β€” okay so when the node is active, it will always get joined with a driver node, even when literally nothing is linked to it. Setting this to true also implies node.want-driver = true. πŸ’…

This is the default for JACK nodes, because they always need their process callback called.

  • node.want-driver = true β€” the node wants to be linked to a driver so 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.
  • node.pause-on-idle = false
  • node.suspend-on-idle = false β€” 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. With this property it's possible to immediately pause a node when idle. 🫢

When the session manager does not suspend nodes (or when there is no session manager at all), the node.suspend-on-idle property can be used instead.

  • node.loop.name = null
  • node.loop.class = data.rt β€” add the node to a specific loop name or loop class. By default the node is added to the data.rt loop class. You can make more specific data loops and then assign the nodes to those. ✨

Other well known names are main-loop.0 and the main node.loop.class which runs the node data processing in the main loop.

  • priority.driver # integer β€” 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.

  • clock.name # string β€” 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 together. 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.

πŸŽ›οΈ Session Manager Properties

  • node.autoconnect = true β€” instructs the session manager to automatically connect this node to some other node, usually a sink or source.
  • node.exclusive = false β€” if this node wants to be linked exclusively to the sink/source.
  • target.object = <node.name|object.serial> β€” where the node should link to, this can be a node.name or an object.serial.
  • node.target = <node.name|object.id> β€” 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.
  • node.dont-reconnect = false β€” 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. πŸ“
  • node.dont-fallback = false β€” if linking this node to its specified target does not succeed, session manager should not fall back to linking it to the default target.
  • node.dont-move = false β€” whether the node target may be changed using metadata.
  • node.passive = false β€” 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.

  • 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. πŸ”
  • 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.
  • priority.session # integer β€” the priority for selecting this node as the default source or sink.
  • session.suspend-timeout-seconds = 3 # float β€” timeout in seconds, after which an idle node is suspended. Value 0 means the node will not be suspended.
  • state.restore-props = true β€” whether session manager should save state for this node.

🎚️ Format Properties

Streams and also most device nodes can be configured in a certain format with properties. fr fr this is the glow-up section πŸ’–

  • audio.rate = RATE β€” forces a samplerate on the node.
  • audio.channels = INTEGER β€” the number of audio channels to use. Must be a value between 1 and 64.
  • audio.format = FORMAT β€” 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, ...

  • audio.allowed-rates β€” an array of allowed samplerates for the node. ex. "[ 44100 48000 ]"

🧩 Other Properties

  • node.param.PARAM = { ... } # JSON β€” set value of a node Param to a JSON value when the device is loaded. This works similarly as pw-cli(1) set-param command. The PARAM should be replaced with the name of the Param to set, ie. for example node.param.Props = { ... } to set Props.
  • node.disabled = false # boolean β€” disable the creation of this node in session manager.

πŸ”Š AUDIO ADAPTER PROPERTIES

Most audio nodes (ALSA, Bluetooth, audio streams from applications, ...) have common properties for the audio adapter. The adapter performs sample format, sample rate and channel mixing operations. It's giving the multitasker of the audio world, honestly. πŸ‘‘

All properties listed below are node properties.

🧬 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.

  • 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 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. slay, offloaded ✨

Below is an explanation of the options that can be tuned in the sample converter.

  • resample.quality = 4 β€” the quality of the resampler. From 0 to 14, the default is 4.

The quality of a resampler depends on multiple factors: 🧐

  1. Anti-Aliasing, how well are unwanted frequencies filtered out. Poor anti-aliasing will make the original inaudible frequencies audible as distortion and noise.
  2. Cutoff frequency. At what frequency the transition band will start. This is the frequency where the signal will start to fade out. A too low cutoff might remove too much of the high frequencies and make the sound dull. A too high cutoff might cause aliasing. The cutoff frequency is usually expressed as a ratio of the Nyquist frequency, 1.0 being the Nyquist frequency (frequency/2).
  3. Transition band length. How quickly the unwanted frequencies are filtered out. A shorter transition band requires longer filters with more CPU and latency but causes less aliasing. The transition band length is expressed as a ratio of the Nyquist frequency.
  4. Stopband attenuation. How well the unwanted frequencies are filtered out. This is usually measured in dB. 96dB is below audible on CD quality audio, 150dB is below the precision of floating point values.
  5. CPU usage. Better anti-aliasing needs longer filters and is therefore more CPU intensive.
  6. Latency. Longer filters have a higher Latency. In real-time application the latency should be kept as low as possible. The required latency is usually (filter-length/2)/source-sample-rate, so a resample filter with length of 128 on a 48Khz signal has 1.3ms ((128/2)/48000) of latency.
  7. Ringing. A too short transition band length might cause ringing because of how the sinc filters work. This can sound like flutter on sharp attacks in the audio signal.

Increasing the quality will result in better cutoff and less aliasing at the expense of (much) more CPU consumption, latency and more ringing. 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. πŸ’…

  • Tune the cutoff frequency. Push the cutoff up to keep more of the high frequencies β€” you pay for it in aliasing.
  • Tune the transition band. Shrink the transition band so stuff right around the cutoff gets filtered out harder and you get less aliasing β€” the tradeoff is more ringing, more CPU and more latency. You do this by bumping the number of taps.
  • Tune the stopband attenuation. Crank the attenuation to reduce aliasing, at the cost of a wider transition band. Heads up: this one is kaiser only β€” the exp and blackman windows are locked in at 150dB and 96dB attenuation respectively.
  • resample.disable = false β€” nukes the resampler entirely πŸ’€. The node can then only negotiate with the graph when the samplerates are actually compatible.
  • resample.window = exp β€” which window function the resampler uses. Default is an exponential window, because it's the good balance between complexity and quality, periodt.

You can also say blackman or kaiser, both with their own tradeoffs. The kaiser window is the special one with extra tunable parameters for specific use cases.

  • resample.cutoff = 0.0 β€” the resampler cutoff frequency, a value between 0.0 and 1.0. A value of 0.0 means "use the predefined value based on the resampler quality."

A higher cutoff keeps more high frequency content, but depending on how big the transition band is it'll cause more aliasing.

The default quality 4 setting for all windows is 0.87.

  • resample.n-taps = 0 β€” the resampler number of taps. Value 0 means it uses a predefined value based on the resampler quality or other window function parameters.

More taps = more CPU, more latency, more ringing, but less aliasing.

The default quality setting for the exp window is 48.

  • resample.param.exp.A = 0.0 β€” the A parameter for the exponential window function. A value of 0.0 uses a predefined value based on the quality whenever the exp window is in use.

The default setting for the exp window is 16.97789.

  • resample.param.blackman.alpha = 0.0 β€” the alpha value of the blackman function. A value of 0.0 uses a predefined value based on the quality whenever the blackman window is in use.

The default quality setting for the blackman window is 0.16.

  • resample.param.kaiser.stopband-attenuation = 0.0 β€” the kaiser window stopband attenuation parameter, in dB. Default 0.0 uses a predefined value based on the quality.

A higher value filters out more of the unwanted frequencies and reduces aliasing, at the cost of a larger transition band. For reference: 96dB sits below the dynamic range of CD quality audio, and 150dB is the limit of the resampler's precision.

The default quality setting for the kaiser window is 130.000000.

  • resample.param.kaiser.transition-bandwidth = 0.0 β€” the kaiser window transition bandwidth parameter. Default 0.0 uses a predefined value based on the quality.

A smaller transition band gives you a steeper cutoff with less unwanted frequencies in the final signal β€” but a larger filter, more CPU usage and more latency. A smaller transition band can also cause more ringing.

The default quality setting for the kaiser window is 0.177032.

  • resample.param.kaiser.alpha = 0.0 β€” the kaiser window alpha parameter. Default 0.0 calculates an alpha value based on the stopband-attenuation and transition-bandwidth parameters.

This value is usually calculated from the other parameters, but you can set it explicitly with this property πŸŽ€

The default quality setting for the kaiser window is 4.254931.

πŸŽ›οΈ Channel Mixer Parameters

Sources, sinks, capture and playback streams can all apply channel mixing to the incoming signal. It's giving very versatile.

Normally the channel mixer is not used for devices β€” device channels are usually exposed exactly as they are. That policy is usually enforced by the session manager, so go read its documentation over 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. That volume adjustment happens on the original channel layout. Example: a stereo playback stream that gets up-mixed to 5.1 has 2 volume controls, left and right.

  • channelmix.disable = false β€” disables the channel mixer completely. The stream will then only be able to link to compatible sources/sinks with the exact same channel layout.
  • channelmix.min-volume = 0.0
  • channelmix.max-volume = 10.0

These two give the min and max volume values allowed. Any volume that gets set will be clamped to these values.

  • channelmix.normalize = false β€” makes sure that during such mixing & resampling the original 0 dB level is preserved, so nothing sounds wildly quieter/louder.

While this option prevents clipping, it can in some cases produce too low volume 😭. Just increase the volume in that case, or disable normalization.

  • channelmix.lock-volumes = false β€” completely disable volume or mute changes. Defaults to false.
  • 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's no subwoofer and the speakers can reproduce the low frequency signal.
  • channelmix.upmix = true β€” 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 enables up-mixing of LFE when channelmix.lfe-cutoff is set to something other than 0 and the target has an LFE channel. The LFE channel is produced by adding the stereo channels.

If channelmix.upmix is true, up-mixing of the rear channels is enabled too, and it's controlled with the channelmix-upmix-method property.

  • channelmix.upmix-method = psd β€” 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. Fast, but it can produce phasing effects.
    3. psd. The rear channels are 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.
  • channelmix.lfe-cutoff = 150 β€” applies 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.
  • channelmix.fc-cutoff = 12000 β€” applies 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.

  • channelmix.rear-delay = 12.0 β€” applies a delay in milliseconds when up-mixing the rear channels. This improves specialization of the sound ✨. A typical delay of 12 milliseconds is the default.

This is only active when the psd up-mix method is used.

  • channelmix.stereo-widen = 0.0 β€” 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.

  • channelmix.hilbert-taps = 0 β€” this option applies a 90 degree phase shift to the rear channels to improve specialization. Taps need to be between 15 and 255, and higher values give more accurate results (with more CPU consumption, ofc).

This is only active when the psd up-mix method is used.

  • dither.noise = 0 β€” this option adds N bits of random data to the signal. When no dither.method is specified, the random data flips between [-(1<<(N-1)), 0] every 1024 samples. With a dither.method, the dither noise is amplified with 1<<(N-1) bits.

This can be used to keep some amplifiers alive during silent periods. One or two bits of noise is usually enough β€” otherwise the noise becomes audible. It's usually used together with session.suspend-timeout-seconds to disable suspend in the session manager.

Note that PipeWire uses floating point operations with 24 bits precision for all of the audio processing. Conversion to 24 bits integer sample formats is lossless, and conversion to 32 bits integer sample formats is simply padded with 0 bits at the end. This means the dither noise is always only in the 24 most significant bits. πŸ’…
  • dither.method = none β€” optional dithering 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. Adds random bits in the [-0.5, 0.5] range to the signal with even distribution.
    3. triangular β€” dithering with a triangular noise distribution. Adds random bits in the [-1.0, 1.0] range to the signal with triangular distribution around 0.0.
    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 uses 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 uses the Lipshitz filter.

Dithering is only useful for conversion to a format with less than 24 bits, and will be disabled otherwise.

πŸ› Debug Parameters

  • debug.wav-path = "" β€” makes the stream also write the raw samples to a WAV file, for debugging purposes πŸ•΅οΈβ€β™€οΈ

πŸ”§ Other Parameters

These control low-level technical features:

  • clock.quantum-limit β€” see pipewire.conf(5)
  • resample.peaks = false # boolean β€” ok so instead of actually resampling, this just spits out peak amplitude values as the output 🎚️. It's the vibe check for volume monitoring, and it gets set as a property on the "recording" stream. Peak girly behavior only πŸ’…
  • resample.prefill = false # boolean β€” prefills the resampler buffers with silence 🫧. Lowkey affects the very first samples the resampler produces, so like… the opening bars of the audio, basically. ngl it matters.
  • adapter.auto-port-config = null # JSON β€” if you set this, the ports of the node get configured right when it's created, instead of you know, leaving that whole task to the session manager 🫢. This is useful (only) for minimal configurations where there's no session manager at all. fr fr, only then.

The value is SPA JSON shaped like this:

{
    mode = "none",          # "none", "passthrough", "convert", "dsp"
    monitor = false,        # boolean
    control = false,        # boolean
    position = "preserve"   # "unknown", "aux", "preserve"
}

See spa_param_port_config for the meaning of all that ✨.


πŸ”₯ ALSA PROPERTIES πŸ”₯

🎧 Monitor properties

  • alsa.use-acp = true # boolean β€” use ALSA Card Profiles (ACP) to configure the device πŸ‘‘. It autodetects the ALSA devices that are available and sets up port and hardware mixers for you. Iconic, honestly.
  • alsa.use-ucm # boolean β€” enable or disable UCM for all the devices 🌈. Default: unset.
  • alsa.udev.expose-busy # boolean β€” expose the ALSA card even if it's busy / in use πŸ’€. Default false. Genuinely useful when some of the PCMs are being hogged by other applications but the other free PCMs should still be exposed. like, don't punish the free ones bestie.

πŸ› οΈ Device properties

  • api.alsa.path # string β€” the ALSA device path, in the exact form you'd use in snd_pcm_open() and snd_ctl_open() πŸ”Œ.
  • api.alsa.use-ucm = true # boolean β€” when ACP is enabled and a UCM configuration is available for a device, UCM gets used by default instead of the ACP profiles ✨. This option lets you disable that and use the ACP profiles instead. Heads up: this option does nothing if alsa.use-acp is set to false. periodt.
  • api.alsa.soft-mixer = false # boolean β€” set this to true and the hardware mixer is disabled for volume control and mute 🚫🎚️. All volume handling then goes through software volume and mute, leaving the hardware mixer untouched. Lowkey interesting for working around bugs in the mixer detection or the decibel reporting. Important though: the hardware mixer will still be used to mute unused audio paths in the device. Use api.alsa.disable-mixer-path to also disable mixer path selection, iykyk.
  • api.alsa.disable-mixer-path = false # boolean β€” set this to true and hardware mixer path selection is disabled πŸ”‡. What even is the hardware mixer path? It's the configuration of the mixer depending on which jacks are inserted in the card 🎧. Disable it and you'll have to manually enable and disable mixer controls yourself β€” but it can work around bugs in the mixer. And the hardware mixer will still be used for volume and mute. To also disable hardware volume and mute, use api.alsa.soft-mixer. The two options are besties, they work as a pair 🫢.
  • api.alsa.ignore-dB = false # boolean β€” set to true and the decibel setting configured by the driver gets ignored πŸ™ˆ. Use this when the driver reports wrong settings. not me trusting the driver… anyway.
  • device.profile-set # string β€” this option selects a custom ACP profile-set name for the device πŸŽ€. You can configure it in UDev rules, but you can also just specify it here. Default is to use "default.conf" unless there's a matching udev rule.
  • device.profile # string β€” the initial active profile name 🌟. Default is to start from the "Off" profile and then let the session manager pick the best profile based on its policy.
  • api.acp.auto-profile = true # boolean β€” automatically select the best profile for the device πŸ‘‘. The session manager usually disables this because it handles the whole task itself. You can enable it in custom configurations where the session manager isn't handling it.
  • api.acp.auto-port = true # boolean β€” automatically select the highest priority port that's available 🌸. Quick vocab moment: "port" is a PulseAudio/ACP term, the equivalent of a "Route" in PipeWire. The session manager usually disables this too, since it handles it instead. Enable it in custom configurations without the session manager doing that job.
  • api.acp.probe-rate # integer β€” sets the samplerate used for probing the ALSA devices and collecting the profiles and ports πŸ”.
  • api.acp.pro-channels # integer β€” sets the number of channels to use when probing the "Pro Audio" profile πŸŽ›οΈ. Normally the maximum amount of channels gets used, but with this you can reduce it, which can make it possible to use other samplerates on some devices. cute little tradeoff.
  • api.alsa.split-enable # boolean β€” for UCM devices with split PCMs, don't split into multiple PCMs using alsa-lib plugins πŸͺ„. Instead, add api.alsa.split properties to the emitted nodes with the PCM splitting information.
  • api.acp.disable-pro-audio = false # boolean β€” disables the "Pro Audio" profile for this device πŸ’€.
  • api.acp.use-eld-channels = false # boolean β€” use the channel count and mapping that the connected HDMI device provides via ELD information πŸ“Ί. it's giving "let the TV decide".

🎚️ Node properties

  • audio.channels # integer β€” the number of audio channels to open the device with πŸ”’. The default depends on the profile of the device.
  • audio.rate # integer β€” the audio rate to open the device with ⏱️. Default is 0, which means open the device with a rate as close to the graph rate as possible. slay.
  • audio.format # string β€” the audio format to open the device in 🎡. By default this is "UNKNOWN", which opens the device in the best possible bits (32/24/16/8..). You can force a format like S16_LE or S32_LE.
  • audio.position # JSON array of strings β€” the audio position of the channels in the device πŸ“. It's auto detected based on the profile. You can configure an array of channel positions, like "[ FL, FR ]".
  • audio.layout # string β€” the audio layout of the channels in the device 🧊. You can use any of the predefined layouts, like "Stereo", "5.1" etc.
  • audio.allowed-rates # JSON array of integers β€” 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. And when the graph is running at a rate that's not listed in the allowed-rates, the resampler gets used to resample to the nearest allowed rate πŸ”„.
  • api.alsa.period-size # integer β€” the period size to open the device in πŸ“. By default this is 0, which opens the device in the default period size to minimize latency.
  • api.alsa.period-num # integer β€” the amount of periods to use in the device πŸ”’. By default this is 0, which means use as many as possible.
  • api.alsa.headroom # integer β€” the amount of extra space to keep in the ringbuffer 🫧. Default is 0. You can configure higher values when the device read and write pointers aren't accurately reported. trust issues with the pointers, honestly.
  • api.alsa.start-delay = 0 # integer β€” some devices need a little time before they can report accurate hardware pointer positions 😴. In those cases an extra start delay can be added to compensate for the startup delay. This sets the startup delay in samples.
  • api.alsa.disable-mmap = false # boolean β€” disable the mmap operation of the device and use the ALSA read/write API instead 🚫. Default is false, because mmap is preferred. obviously.
  • api.alsa.disable-batch # boolean β€” ignore the ALSA batch flag 🏁. If the batch flag is set, ALSA needs an extra period to update the read/write pointers, so ignoring this flag from ALSA can reduce latency. Default is false.
  • api.alsa.use-chmap # boolean β€” use the driver-provided channel map πŸ—ΊοΈ. Default is true when using UCM, false otherwise β€” because many drivers don't report this correctly πŸ™ƒ. classic.
  • api.alsa.multi-rate # boolean β€” allow devices from the same card to be opened in multiple sample rates 🎢. Default is true. Some older drivers didn't properly advertise the capabilities of the device and only really supported opening the device in one rate. old drivers stay messy.
  • api.alsa.htimestamp = false # boolean β€” use ALSA htimestamps in scheduling instead of the system clock ⏰. Some ALSA drivers produce bad timestamps, so this isn't enabled by default β€” and it'll be disabled at runtime if it looks like the ALSA timestamps are bad. self-cleaning, we love.
  • api.alsa.htimestamp.max-errors # integer β€” the number of consecutive errors before htimestamp gets disabled πŸ’€. Setting this to 0 makes htimestamp never get disabled. zero means infinite, bestie.
  • api.alsa.disable-tsched = false # boolean β€” disable timer-based scheduling, and use IRQ for scheduling instead ⚑. The "Pro Audio" profile will usually enable this setting if it's expected to work on the hardware.
  • api.alsa.dll-bandwidth-max # double β€” sets the maximum bandwidth of the DLL (delay-locked loop) filter used to smooth out rate adjustments πŸ“‰. The default value may be too responsive in some scenarios. For example, with UAC2 pitch control, the host reacts more slowly compared to local resampling, so using a lower bandwidth helps avoid oscillations or instability. like, calm down the filter a little πŸ§˜β€β™€οΈ.
  • api.alsa.auto-link = false # boolean β€” link follower PCM devices to the driver PCM device when using IRQ-based scheduling πŸ”—. The "Pro Audio" profile will usually enable this setting if it's expected to work on the hardware.
  • latency.internal.rate # integer β€” statically set the device systemic latency, in samples at playback rate ⏳.
  • latency.internal.ns # integer β€” statically set the device systemic latency, in nanoseconds ⏱️.
  • api.alsa.path # string β€” UNDOCUMENTED πŸ’€
  • api.alsa.pcm.card # integer β€” card index to open πŸƒ. Usually determined from api.alsa.path.
  • api.alsa.open.ucm # boolean β€” open the device using UCM 🌈.
  • api.alsa.bind-ctls # boolean β€” UNDOCUMENTED πŸ’€
  • api.alsa.bind-ctl.NAME # boolean β€” UNDOCUMENTED πŸ’€
  • iec958.codecs # JSON array of string β€” enable only specific IEC958 codecs πŸŽ›οΈ. This can be used to disable some codecs the hardware supports. Available values: PCM, AC3, DTS, MPEG, MPEG2-AAC, EAC3, TRUEHD, DTSHD. pick your fighters.
  • api.alsa.split.parent # boolean β€” this PCM is a UCM SplitPCM parent PCM, to be opened with SplitPCM set πŸ‘¨β€πŸ‘©β€πŸ‘§.
  • api.alsa.split.position # JSON β€” (SPA JSON list) if present, this is a virtual device corresponding to a subset of channels in an underlying PCM, listed in this property 🧩. Informative property.
  • api.alsa.split.hw-position # JSON β€” (SPA JSON list) channel map of the underlying split PCM πŸ—ΊοΈ. Informative property.
  • api.alsa.dsd-lsb = false # boolean β€” use LSB bit order for DSD audio output 🎧.

🎹 ALSA MIDI PROPERTIES 🎹

πŸŽ›οΈ Node properties

okay so for ALSA MIDI in Wireplumber, the MIDI bridge node properties are configured in the monitor properties. that's the vibe. periodt. ✨

  • api.alsa.seq.ump = true # boolean β€” use MIDI 2.0 if possible. bestie, we love a forward-compatible moment πŸ’…
  • api.alsa.seq.min-pool = 500 # integer β€” literally labeled UNDOCUMENTED. that's all we get, no cap πŸ™ˆ
  • api.alsa.seq.max-pool = 2000 # integer β€” also UNDOCUMENTED. mysterious icon behavior πŸ•΅οΈβ€β™€οΈ
  • clock.name = "clock.system.monotonic" # string β€” the clock to follow. main character clock energy ⏰
  • api.alsa.path = "default" # string β€” the sequencer device to use. yes ma'am 🎹
  • api.alsa.disable-longname = true # boolean β€” if the card long name should not be passed to the MIDI port. sometimes less is more, iykyk πŸŽ€

πŸ’™ BLUETOOTH PROPERTIES πŸ’™

πŸ“‘ Monitor properties

these are settings for the Bluetooth device monitor, not device or node properties. important distinction, bestie 🫢

  • bluez5.roles = [ a2dp_sink a2dp_source bap_sink bap_source bap_bcast_sink bap_bcast_source hfp_hf hfp_ag ] # JSON array of string β€” enabled roles. 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 are:
    • 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)
    • bap_bcast_sink (LE Audio Basic Audio Profile Broadcast Sink)
    • bap_bcast_source (LE Audio Basic Audio Profile Broadcast Source)
  • bluez5.codecs # JSON array of string β€” 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. codec buffet, obsessed πŸ“
  • bluez5.default.rate # integer β€” default audio rate.
  • bluez5.default.channels # integer β€” default audio channels.
  • bluez5.hfphsp-backend # integer β€” HFP/HSP backend (default: native). available values: any, none, hsphfpd, ofono, native.
  • bluez5.hfphsp-backend-native-modem # string β€” that's it. no description in the original, bestie. it's giving mystery box 🎁
  • bluez5.hfphsp-backend-native-pts # boolean β€” enable specific workarounds for Bluetooth qualification.
  • bluez5.disable-dummy-call # boolean β€” by default a call status event is sent on audio stream connection/disconnection to work around some headset timeout disconnection when the HFP HF is used by another application than the telephony one, e.g. a conference application/website. this prevents sending this event.
  • bluez5.dummy-avrcp player # boolean β€” register dummy AVRCP player. some devices have wrongly functioning volume or playback controls if this is not enabled. default: false.
  • bluez5.enable-sbc-xq # boolean β€” override device quirk list and enable SBC-XQ for devices for which it is disabled.
  • bluez5.enable-msbc # boolean β€” override device quirk list and enable MSBC for devices for which it is disabled.
  • bluez5.enable-hw-volume # boolean β€” override device quirk list and enable hardware volume for devices for which it is disabled.
  • bluez5.hw-offload-sco # boolean β€” 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. not me warning you dramatically, but also yes πŸ’€
  • bluez5.hw-offload-datapath # integer β€” HFP/HSP hardware offload data path ID (default: 0). this feature configures the SCO hardware-offload data path for HFP/HSP using the Bluetooth SIG–specified procedure. it is intended for advanced setups and vendor integrations. do not edit this unless required; incorrect values can disable SCO offload.
  • bluez5.a2dp.opus.pro.channels = 3 # integer β€” PipeWire Opus Pro audio profile channel count.
  • bluez5.a2dp.opus.pro.coupled-streams = 1 # integer β€” PipeWire Opus Pro audio profile coupled stream count.
  • bluez5.a2dp.opus.pro.locations = "FL,FR,LFE" # string β€” PipeWire Opus Pro audio profile audio channel locations.
  • bluez5.a2dp.opus.pro.max-bitrate = 600000 # integer β€” PipeWire Opus Pro audio profile max bitrate.
  • bluez5.a2dp.opus.pro.frame-dms = 50 # integer β€” PipeWire Opus Pro audio profile frame duration (1/10 ms).
  • bluez5.a2dp.opus.pro.bidi.channels = 1 # integer β€” PipeWire Opus Pro audio profile duplex channels.
  • bluez5.a2dp.opus.pro.bidi.coupled-streams = 0 # integer β€” PipeWire Opus Pro audio profile duplex coupled stream count.
  • bluez5.a2dp.opus.pro.bidi.locations = "FC" # string β€” PipeWire Opus Pro audio profile duplex coupled channel locations.
  • bluez5.a2dp.opus.pro.bidi.max-bitrate = 160000 # integer β€” PipeWire Opus Pro audio profile duplex max bitrate.
  • bluez5.a2dp.opus.pro.bidi.frame-dms = 400 # integer β€” PipeWire Opus Pro audio profile duplex frame duration (1/10 ms).
  • bluez5.bcast_source.config = [] # JSON β€” for a per-adapter configuration of multiple BIGs, use an "adapter" entry in the BIG with the BD address. example:
bluez5.bcast_source.config = [
  {
    "broadcast_code": "BΓΈrne House",
    "encryption: false,
    "sync_factor": 2,
    "bis": [
      { # BIS configuration
        "qos_preset": "16_2_1", # QOS preset name from table Table 6.4 from BAP_v1.0.1.
        "audio_channel_allocation": 1, # audio channel allocation configuration for the BIS
        "metadata": [ # metadata configurations for the BIS
           { "type": 1, "value": [ 1, 1 ] }
        ]
      }
    ]
  }
]
  • bluez5.bap-server-capabilities.rates # Array of integers β€” supported sampling frequencies for the LC3 codec (default: all). possible values: 8000, 16000, 24000, 32000, 44100, 48000.
  • bluez5.bap-server-capabilities.durations # Array of doubles β€” supported frame durations for the LC3 codec (default: all). possible values: 7.5, 10.
  • bluez5.bap-server-capabilities.channels # Array of integers β€” supported audio channel counts for the LC3 codec (default: [1, 2]). possible values: 1, 2, 3, 4, 5, 6, 7, 8.
  • bluez5.bap-server-capabilities.framelen_min # integer β€” minimum number of octets supported per codec frame for the LC3 codec (default: 20).
  • bluez5.bap-server-capabilities.framelen_max # integer β€” maximum number of octets supported per codec frame for the LC3 codec (default: 400).
  • bluez5.bap-server-capabilities.max_frames # integer β€” maximum number of codec frames supported per SDU for the LC3 codec (default: 2).
  • bluez5.bap-server-capabilities.sink.locations # JSON or integer β€” sink audio locations of the server, as channel positions or PACS bitmask. example: FL,FR.
  • bluez5.bap-server-capabilities.sink.contexts # integer β€” available sink contexts PACS bitmask of the server.
  • bluez5.bap-server-capabilities.sink.supported-contexts # integer β€” supported sink contexts PACS bitmask of the server.
  • bluez5.bap-server-capabilities.sink.delay-min # integer β€” minimum presentation delay supported, in microseconds.
  • bluez5.bap-server-capabilities.sink.delay-max # integer β€” maximum presentation delay supported, in microseconds.
  • bluez5.bap-server-capabilities.sink.preferred-delay-min # integer β€” minimum preferred presentation delay supported, in microseconds.
  • bluez5.bap-server-capabilities.sink.preferred-delay-max # integer β€” maximum preferred presentation delay supported, in microseconds.
  • bluez5.bap-server-capabilities.source.locations # JSON or integer β€” source audio locations of the server, as channel positions or PACS bitmask. example: FL,FR.
  • bluez5.bap-server-capabilities.source.contexts # integer β€” available source contexts PACS bitmask of the server.
  • bluez5.bap-server-capabilities.source.supported-contexts # integer β€” supported source contexts PACS bitmask of the server.
  • bluez5.bap-server-capabilities.source.delay-min # integer β€” minimum presentation delay supported, in microseconds.
  • bluez5.bap-server-capabilities.source.delay-max # integer β€” maximum presentation delay supported, in microseconds.
  • bluez5.bap-server-capabilities.source.preferred-delay-min # integer β€” minimum preferred presentation delay supported, in microseconds.
  • bluez5.bap-server-capabilities.source.preferred-delay-max # integer β€” maximum preferred presentation delay supported, in microseconds.
  • bluez5.bap-server-tmap-features = null # array of string β€” override advertised TMAP service features. see TMAP specification for their meaning. possible values: "cg", "ct", "ums", "umr", "bms", "bmr". default: none.
  • bluez5.bap-server-gmap-features = null # array of string β€” override advertised GMAP service features. see GMAP specification for their meaning. possible values: "ugg", "ugt", "bgs", "bgr", "ugg-multiplex", "ugg-96kbps-source", "ugg-multisink", "ugt-source", "ugt-80kbps-source", "ugt-sink", "ugt-64kbps-sink", "ugt-multiplex", "ugt-multisink", "ugt-multisource", "bgs-96kbps", "bgr-multisink", "bgr-multiplex". default: none.

🎧 Device properties

  • bluez5.auto-connect # boolean β€” auto-connect devices on start up. disabled by default if the property is not specified.
  • bluez5.hw-volume = [ hfp_ag hsp_ag a2dp_source ] # JSON array of string β€” profiles for which to enable hardware volume control.
  • bluez5.profile # string β€” initial device profile. this usually has no effect as the session manager overrides it. lowkey just vibes, but okay πŸ’…
  • bluez5.a2dp.ldac.quality = "auto" # string β€” 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)
  • bluez5.a2dp.aac.bitratemode = 0 # integer β€” AAC variable bitrate mode. available values: 0 (cbr, default), 1-5 (quality level).
  • bluez5.a2dp.opus.pro.application = "audio" # string β€” PipeWire Opus Pro Audio encoding mode: audio, voip, lowdelay.
  • bluez5.a2dp.opus.pro.bidi.application = "audio" # string β€” PipeWire Opus Pro Audio duplex encoding mode: audio, voip, lowdelay.
  • bluez5.bap.cig = "auto" # integer, or 'auto' β€” set CIG ID for BAP unicast streams of the device.
  • bluez5.bap.preset = "auto" # string β€” BAP QoS preset name that needed to be used with vendor config. this property is experimental. available: "48_2_1", ... as in the BAP specification.
  • bluez5.bap.rtn # integer β€” BAP QoS preset name that needed to be used with vendor config. this property is experimental. default: as per QoS preset.
  • πŸ¦‹ bluez5.bap.latency (integer) β€” the BAP QoS latency you want applied when you're using a vendor-defined preset. this one is experimental, okurrr. Default: same as the QoS preset.
  • πŸ¦‹ bluez5.bap.delay = 40000 (integer) β€” the BAP QoS delay to slap onto a vendor-defined preset. also experimental, no cap. Default: as per the QoS preset.
  • πŸ¦‹ bluez5.framing = false (boolean) β€” BAP QoS framing for vendor-defined presets. experimental bestie. Default: as per QoS preset.
  • πŸ¦‹ bluez5.bap.force-target-latency = "balanced" (string) β€” forces a BAP QoS target latency profile for QoS configuration selection. if it's not set, or you set it to "balanced", then both the low-latency and high-reliability QoS configuration tables get used. this is experimental πŸ’€. Available: low-latency, high-reliability, balanced

🎧 Node properties

  • 🎀 bluez5.media-source-role (string) β€” the media source role for Bluetooth clients connecting to this instance. Available values:
    • playback: playing stream to speakers πŸ”Š
    • input: appear as a source node πŸŽ™οΈ
  • 🎀 bluez5.decode-buffer.latency (integer) β€” applies on media source nodes, and defines the target amount of samples to buffer on the output of the decoder. Default: 0, which literally means "figure it out yourself" (automatically determined ✨).
  • 🎀 node.latency-offset-msec (string) β€” applies only for BLE MIDI nodes. it's a latency adjustment applied on the node. larger values add a constant latency, but they reduce the timing jitter caused by the Bluetooth transport. so like, tradeoff city 😭.
  • 🎀 bluez5.debug.iso-mono = false (boolean) β€” a debugging option that forces ISO sinks to send identical packets out for all streams. debug brainrot only, iykyk πŸ™ˆ.

πŸŽ€ PORT PROPERTIES πŸŽ€

so port properties are usually not directly configurable via PipeWire configuration files, because they're determined by the applications creating them. periodt. but here are some port properties that might be interesting for users:

  • port.name (string) β€” port name 🏷️
  • port.alias (string) β€” port alias 🏷️

πŸ‘€ See also

Key Names in the API documentation for a full list.


link properties are also usually not directly configurable via PipeWire configuration files, since they're determined by the applications creating them. same vibe as ports, fr fr.

πŸ‘€ See also

Key Names in the API documentation for a full list.


πŸ§‘β€πŸ€β€πŸ§‘ CLIENT PROPERTIES πŸ§‘β€πŸ€β€πŸ§‘

client properties are usually not directly configurable via PipeWire configuration files either β€” they're determined by the application connecting to PipeWire. but clients are affected by the settings in pipewire.conf(5) and by session manager settings, so like, they're not fully off the grid.

⚠️ Note β€” only the properties pipewire.* are safe to use for security purposes, like identifying applications and their capabilities. that's because clients can set and change other properties freely πŸ’€. do not trust the rest for security, bestie, i'm serious.

below are some client properties that might be interesting for users.

  • 🧸 application.name (string) β€” application keys. this is the application name. Ex: "Totem Music Player"
  • 🧸 application.process.id (integer) β€” process id (pid)
  • 🧸 pipewire.sec.pid (integer) β€” client pid, set by the protocol. note that for PulseAudio applications, this is the PID of the pipewire-pulse process πŸ‘‘

πŸ‘€ See also

Key Names in the API documentation for a full list.


βš™οΈ RUNTIME SETTINGS βš™οΈ

okay so objects like devices and nodes also have parameters that you can modify after the object has been created. like the active device profile, channel volumes, and so on. main character energy: the object doesn't have to be born perfect, you can glow it up later πŸ’….

for some objects, the parameters also let you change some of the properties. the settings of most ALSA and virtual device parameters can be configured at runtime too. slay.

these settings live in a device parameter called Props in its params field. you can see them, e.g. with pw-dump <id> for an ALSA device:

{
...
      "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"
            ]
          }
...

they generally have the same names and meaning as the corresponding properties. consistency icon ✨.

one or more params can be changed using pw-cli(1):

pw-cli s <id> Props '{ params = [ "api.alsa.headroom" 1024 ] }'
🚨 these settings are not saved and need to be reapplied for each session manager restart. so yeah, they vanish like your motivation at 3am 😭.

πŸ”Š ALSA CARD PROFILES πŸ”Š

the sound card profiles ("Analog stereo", "Analog stereo duplex", ...) β€” except "Pro Audio" β€” come from two sources:

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. and get this β€” it's possible to override individual files locally by putting a modified copy into the ACP directories under ~/.config or /etc. customizing queen behavior πŸŽ€.


πŸ“¦ OTHER OBJECT TYPES πŸ“¦

technically, PipeWire objects is what are manipulated by applications using the PipeWire API. grammar? we don't know her. the facts? immaculate.

the list of object types that are usually "exported" (i.e. appear in pw-dump(1) output) is larger than what we talked about above:

  • Node
  • Device
  • Port
  • Link
  • Client
  • Metadata
  • Module
  • Profiler
  • SecurityContext

Monitors do not appear in this list β€” they're not usually exported, and technically they're also Device objects. they're considered above as a separate object type because they have configurable properties. special little guys πŸ¦‹.

Metadata objects are what is manipulated with pw-metadata(1).

Modules can be loaded in configuration files, or by PipeWire applications.

the Profiler and SecurityContext objects only provide corresponding PipeWire APIs. that's it, that's the whole personality.

πŸ—‚οΈ INDEX

okay so this is the master list β€” literally every property on this page, sorted by which kind of object it lives on. use it like a map, bestie: spot the name you need, then scroll to the section that explains it. no cap, it's giving table of contents but make it fashion. πŸ’…

πŸ‘€ Monitor properties

the monitor-flavoured ones β€” alsa.*, api.alsa.*, and a whole parade of bluez5.* (plus clock.name at the end, hi queen):

  • alsa.udev.expose-busy
  • alsa.use-acp
  • alsa.use-ucm
  • api.alsa.disable-longname
  • api.alsa.path
  • api.alsa.seq.max-pool
  • api.alsa.seq.min-pool
  • api.alsa.seq.ump
  • bluez5.a2dp.opus.pro.bidi.channels
  • bluez5.a2dp.opus.pro.bidi.coupled-streams
  • bluez5.a2dp.opus.pro.bidi.frame-dms
  • bluez5.a2dp.opus.pro.bidi.locations
  • bluez5.a2dp.opus.pro.bidi.max-bitrate
  • bluez5.a2dp.opus.pro.channels
  • bluez5.a2dp.opus.pro.coupled-streams
  • bluez5.a2dp.opus.pro.frame-dms
  • bluez5.a2dp.opus.pro.locations
  • bluez5.a2dp.opus.pro.max-bitrate
  • bluez5.bap-server-capabilities.channels
  • bluez5.bap-server-capabilities.durations
  • bluez5.bap-server-capabilities.framelen_max
  • bluez5.bap-server-capabilities.framelen_min
  • bluez5.bap-server-capabilities.max_frames
  • bluez5.bap-server-capabilities.rates
  • bluez5.bap-server-capabilities.sink.contexts
  • bluez5.bap-server-capabilities.sink.delay-max
  • bluez5.bap-server-capabilities.sink.delay-min
  • bluez5.bap-server-capabilities.sink.locations
  • bluez5.bap-server-capabilities.sink.preferred-delay-max
  • bluez5.bap-server-capabilities.sink.preferred-delay-min
  • bluez5.bap-server-capabilities.sink.supported-contexts
  • bluez5.bap-server-capabilities.source.contexts
  • bluez5.bap-server-capabilities.source.delay-max
  • bluez5.bap-server-capabilities.source.delay-min
  • bluez5.bap-server-capabilities.source.locations
  • bluez5.bap-server-capabilities.source.preferred-delay-max
  • bluez5.bap-server-capabilities.source.preferred-delay-min
  • bluez5.bap-server-capabilities.source.supported-contexts
  • bluez5.bap-server-gmap-features
  • bluez5.bap-server-tmap-features
  • bluez5.bcast_source.config
  • bluez5.codecs
  • bluez5.default.channels
  • bluez5.default.rate
  • bluez5.disable-dummy-call
  • bluez5.dummy-avrcp
  • bluez5.enable-hw-volume
  • bluez5.enable-msbc
  • bluez5.enable-sbc-xq
  • bluez5.hfphsp-backend
  • bluez5.hfphsp-backend-native-modem
  • bluez5.hfphsp-backend-native-pts
  • bluez5.hw-offload-datapath
  • bluez5.hw-offload-sco
  • bluez5.roles
  • clock.name

🎧 Device properties

the device-side crew β€” api.acp.*, api.alsa.*, bluez5.*, and all the device.* classics. (yes, api.alsa.path shows up in more than one list, she contains multitudes ✨)

  • api.acp.auto-port
  • api.acp.auto-profile
  • api.acp.disable-pro-audio
  • api.acp.pro-channels
  • api.acp.probe-rate
  • api.acp.use-eld-channels
  • api.alsa.disable-mixer-path
  • api.alsa.ignore-dB
  • api.alsa.path
  • api.alsa.soft-mixer
  • api.alsa.split-enable
  • api.alsa.split.parent
  • api.alsa.use-ucm
  • bluez5.a2dp.aac.bitratemode
  • bluez5.a2dp.ldac.quality
  • bluez5.a2dp.opus.pro.application
  • bluez5.a2dp.opus.pro.bidi.application
  • bluez5.auto-connect
  • bluez5.bap.cig
  • bluez5.bap.delay
  • bluez5.bap.force-target-latency
  • bluez5.bap.latency
  • bluez5.bap.preset
  • bluez5.bap.rtn
  • bluez5.framing
  • bluez5.hw-volume
  • bluez5.profile
  • device.class
  • device.description
  • device.disabled
  • device.form-factor
  • device.icon
  • device.icon-name
  • device.intended-roles
  • device.name
  • device.nick
  • device.param.PARAM
  • device.plugged
  • device.product.id
  • device.product.name
  • device.profile
  • device.profile-set
  • device.serial
  • device.vendor.id
  • device.vendor.name

πŸ”Š Node properties

the big one. this list is long long β€” adapter.*, api.alsa.*, audio.*, bluez5.*, channelmix.*, clock.*, debug.*, device.*, dither.*, iec958.*, latency.*, media.*, monitor.*, node.*, object.*, priority.*, resample.*, session.*, state.*, stream.*, and target.object. iconic behavior honestly πŸ‘‘

  • adapter.auto-port-config
  • api.alsa.auto-link
  • api.alsa.bind-ctl.NAME
  • api.alsa.bind-ctls
  • api.alsa.disable-batch
  • api.alsa.disable-mmap
  • api.alsa.disable-tsched
  • api.alsa.dll-bandwidth-max
  • api.alsa.dsd-lsb
  • api.alsa.headroom
  • api.alsa.htimestamp
  • api.alsa.htimestamp.max-errors
  • api.alsa.multi-rate
  • api.alsa.open.ucm
  • api.alsa.path
  • api.alsa.pcm.card
  • api.alsa.period-num
  • api.alsa.period-size
  • api.alsa.split.hw-position
  • api.alsa.split.position
  • api.alsa.start-delay
  • api.alsa.use-chmap
  • audio.allowed-rates
  • audio.channels
  • audio.format
  • audio.layout
  • audio.position
  • audio.rate
  • bluez5.debug.iso-mono
  • bluez5.decode-buffer.latency
  • bluez5.media-source-role
  • channelmix.disable
  • channelmix.fc-cutoff
  • channelmix.hilbert-taps
  • channelmix.lfe-cutoff
  • channelmix.lock-volumes
  • channelmix.max-volume
  • channelmix.min-volume
  • channelmix.mix-lfe
  • channelmix.normalize
  • channelmix.rear-delay
  • channelmix.stereo-widen
  • channelmix.upmix
  • channelmix.upmix-method
  • clock.name
  • clock.quantum-limit
  • debug.wav-path
  • device.id
  • dither.method
  • dither.noise
  • iec958.codecs
  • latency.internal.ns
  • latency.internal.rate
  • media.artist
  • media.category
  • media.class
  • media.comment
  • media.copyright
  • media.date
  • media.filename
  • media.format
  • media.icon
  • media.icon-name
  • media.language
  • media.name
  • media.role
  • media.software
  • media.title
  • media.type
  • monitor.channel-volumes
  • node.always-process
  • node.autoconnect
  • node.description
  • node.disabled
  • node.dont-fallback
  • node.dont-move
  • node.dont-reconnect
  • node.exclusive
  • node.force-quantum
  • node.force-rate
  • node.latency
  • node.latency-offset-msec
  • node.link-group
  • node.lock-quantum
  • node.lock-rate
  • node.loop.class
  • node.loop.name
  • node.name
  • node.nick
  • node.param.PARAM
  • node.passive
  • node.pause-on-idle
  • node.rate
  • node.suspend-on-idle
  • node.target
  • node.want-driver
  • object.linger
  • priority.driver
  • priority.session
  • resample.cutoff
  • resample.disable
  • resample.n-taps
  • resample.param.blackman.alpha
  • resample.param.exp.A
  • resample.param.kaiser.alpha
  • resample.param.kaiser.stopband-attenuation
  • resample.param.kaiser.transition-bandwidth
  • resample.peaks
  • resample.prefill
  • resample.quality
  • resample.window
  • session.suspend-timeout-seconds
  • state.restore-props
  • stream.dont-remix
  • target.object

πŸ”Œ Port properties

short and sweet. two lil icons, that's the whole group:

  • port.alias
  • port.name

πŸͺͺ Client properties

same energy β€” three of them, and they're all about who the client is:

  • application.name
  • application.process.id
  • pipewire.sec.pid

πŸ‘‘ AUTHORS

The PipeWire Developers β€” ping them at <https://gitlab.freedesktop.org/pipewire/pipewire/issues> 🫢, and yeah, PipeWire is available from <https://pipewire.org>. go say hi, they're doing the lord's work honestly.

πŸ¦‹ SEE ALSO

  • pipewire.conf(5) β€” the other page you'll have open in a second terminal tab, fr fr

okay that's the whole entire page, bestie!! you made it to the end πŸŽ‰ go forth and configure your little heart out. and remember: this was pipewire-props(7) from PipeWire 1.6.8 β€” that's the version, that's the page, that's the source, and the date line lives down in the footer where the manpage gremlins keep it. slay, bye πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from