PipeWire 1.4.1
|
The filter-chain allows you to create an arbitrary processing graph from LADSPA, LV2 and builtin filters. This filter can be made into a virtual sink/source or between any 2 nodes in the graph.
The filter chain is built with 2 streams, a capture stream providing the input to the filter chain and a playback stream sending out the filtered stream to the next nodes in the graph.
Because both ends of the filter-chain are built with streams, the session manager can manage the configuration and connection with the sinks and sources automatically.
libpipewire-module-filter-chain
node.description
: a human readable name for the filter chainfilter.graph = []
: a description of the filter graph to run, see belowcapture.props = {}
: properties to be passed to the input streamplayback.props = {}
: properties to be passed to the output streamThe general structure of the graph description is as follows:
Nodes describe the processing filters in the graph. Use a tool like lv2ls or listplugins to get a list of available plugins, labels and the port names.
type
is one of ladspa
, lv2
, builtin
, sofa
or ebur128
.name
is the name for this node, you might need this later to refer to this node and its ports when setting controls or making links.plugin
is the type specific plugin name..so
to find the shared object with that name in the LADSPA plugin path.label
is the type specific filter inside the plugin.config
contains a filter specific configuration section. Some plugins need this. (convolver, sofa, delay, ...)control
contains the initial values for the control ports of the filter. normally these are given with the port name but it is also possible to give the control index as the key.Links can be made between ports of nodes. The portname
is given as <node_name>:<port_name>
.
You can tee the output of filters to multiple other filters. You need to use a mixer if you want the output of multiple filters to go into one filter input port.
links can be omitted when the graph has just 1 filter.
These are the entry and exit ports into the graph definition. Their number defines the number of channels used by the filter-chain.
The <portname>
can be null
when a channel is to be ignored.
Each input/output in the graph can only be linked to one filter input/output. You need to use the copy builtin filter if the stream signal needs to be routed to multiple filters. You need to use the mixer builtin plugin if multiple graph outputs need to go to one output stream.
inputs and outputs can be omitted, in which case the filter-chain will use all inputs from the first filter and all outputs from the last filter node. The graph will then be duplicated as many times to match the number of input/output channels of the streams.
Normally the volume of the sink/source is handled by the stream software volume. With the capture.volumes and playback.volumes properties this can be handled by a control port in the graph instead. Use capture.volumes for the volume of the input of the filter (when for example used as a sink). Use playback,volumes for the volume of the output of the filter (when for example used as a source).
The min and max values (defaults 0.0 and 1.0) respectively can be used to scale and translate the volume min and max values.
Normally the control values are linear and it is assumed that the plugin does not perform any scaling to the values. This can be changed with the scale property. By default this is linear but it can be set to cubic when the control applies a cubic transformation.
There are some useful builtin filters available. You select them with the label of the filter node.
Use the mixer
plugin if you have multiple input signals that need to be mixed together.
The mixer plugin has up to 8 input ports labeled "In 1" to "In 8" and each with a gain control labeled "Gain 1" to "Gain 8". There is an output port labeled "Out". Unused input ports will be ignored and not cause overhead.
Use the copy
plugin if you need to copy a stream input signal to multiple filters.
It has one input port "In" and one output port "Out".
Biquads can be used to do all kinds of filtering. They are also used when creating equalizers.
All biquad filters have an input port "In" and an output port "Out". They have a "Freq", "Q" and "Gain" control. Their meaning depends on the particular biquad that is used. The biquads also have "b0", "b1", "b2", "a0", "a1" and "a2" ports that are read-only except for the bq_raw biquad, which can configure default values depending on the graph rate and change those at runtime.
We refer to https://arachnoid.com/BiQuadDesigner/index.html for an explanation of the controls.
The following labels can be used:
bq_lowpass
a lowpass filter.bq_highpass
a highpass filter.bq_bandpass
a bandpass filter.bq_lowshelf
a low shelf filter.bq_highshelf
a high shelf filter.bq_peaking
a peaking filter.bq_notch
a notch filter.bq_allpass
an allpass filter.bq_raw
a raw biquad filter. You need a config section to specify coefficients per sample rate. The coefficients of the sample rate closest to the graph rate are selected:The parametric EQ chains a number of biquads together. It is more efficient than specifying a number of chained biquads and it can also load configuration from a file.
The parametric EQ supports multichannel processing and has 8 input and 8 output ports that don't all need to be connected. The ports are named In 1
to In 8
and Out 1
to Out 8
.
Either a filename
or a filters
array can be specified. The configuration will be used for all channels. Alternatively filenameX
or filtersX
where X is the channel number (between 1 and 8) can be used to load a channel specific configuration.
The filename
must point to a parametric equalizer configuration generated from the AutoEQ project or Squiglink. Both the projects allow equalizing headphones or an in-ear monitor to a target curve.
A popular example of the above being EQ'ing to the Harman target curve or EQ'ing one headphone/IEM to another.
For AutoEQ, see https://github.com/jaakkopasanen/AutoEq. For SquigLink, see https://squig.link/.
Parametric equalizer configuration generated from AutoEQ or Squiglink looks like below.
Fc, Gain and Q specify the frequency, gain and Q factor respectively. The fourth column can be one of PK, LSC or HSC specifying peaking, low shelf and high shelf filter respectively. More often than not only peaking filters are involved.
The filters
(or channel specific filtersX
where X is the channel between 1 and 8) can contain an array of filter specification object with the following keys:
type
specifies the filter type, choose one from the available biquad labels. freq
is the frequency passed to the biquad. gain
is the gain passed to the biquad. q
is the Q passed to the biquad.
This makes it possible to also use the param eq without a file and with all the available biquads.
The convolver can be used to apply an impulse response to a signal. It is usually used for reverbs or virtual surround. The convolver is implemented with a fast FFT implementation.
The convolver has an input port "In" and an output port "Out". It requires a config section in the node declaration in this format:
blocksize
specifies the size of the blocks to use in the FFT. It is a value between 64 and 256. When not specified, this value is computed automatically from the number of samples in the file.tailsize
specifies the size of the tail blocks to use in the FFT.gain
the overall gain to apply to the IR file.delay
The extra delay to add to the IR. A float number will be interpreted as seconds, and integer as samples. Using the delay in seconds is independent of the graph and IR rate and is recommended.filename
The IR to load or create. Possible values are:/hilbert
creates a hilbert function that can be used to phase shift the signal by +/-90 degrees. The length
will be used as the number of coefficients./dirac
creates a Dirac function that can be used as gain.offset
The sample offset in the file as the start of the IR.length
The number of samples to use as the IR.channel
The channel to use from the file as the IR.resample_quality
The resample quality in case the IR does not match the graph samplerate.The delay can be used to delay a signal in time.
The delay has an input port "In" and an output port "Out". It also has a "Delay (s)" control port. It requires a config section in the node declaration in this format:
max-delay
the maximum delay in seconds. The "Delay (s)" parameter will be clamped to this value.The invert plugin can be used to invert the phase of the signal.
It has an input port "In" and an output port "Out".
The clamp plugin can be used to clamp samples between min and max values.
It has an input port "In" and an output port "Out". It also has a "Control" and "Notify" port for the control values.
The final result is clamped to the "Min" and "Max" control values.
The linear plugin can be used to apply a linear transformation on samples or control values.
It has an input port "In" and an output port "Out". It also has a "Control" and "Notify" port for the control values.
The control value "Mult" and "Add" are used to configure the linear transform. Each sample or control value will be calculated as: new = old * Mult + Add.
The recip plugin can be used to calculate the reciprocal (1/x) of samples or control values.
It has an input port "In" and an output port "Out". It also has a "Control" and "Notify" port for the control values.
The abs plugin can be used to calculate the absolute value of samples.
It has an input port "In" and an output port "Out".
The sqrt plugin can be used to calculate the square root of samples.
It has an input port "In" and an output port "Out".
The exp plugin can be used to calculate the exponential (base^x) of samples or control values.
It has an input port "In" and an output port "Out". It also has a "Control" and "Notify" port for the control values.
The control value "Base" is used to calculate base ^ x for each sample.
The log plugin can be used to calculate the logarithm of samples or control values.
It has an input port "In" and an output port "Out". It also has a "Control" and "Notify" port for the control values.
The control value "Base", "M1" and "M2" are used to calculate out = M2 * log2f(fabsf(in * M1)) / log2f(Base) for each sample.
The mult plugin can be used to multiply samples together.
It has 8 input ports named "In 1" to "In 8" and an output port "Out".
All input ports samples are multiplied together into the output. Unused input ports will be ignored and not cause overhead.
The sine plugin generates a sine wave.
It has an output port "Out" and also a control output port "notify".
"Freq", "Ampl", "Offset" and "Phase" can be used to control the sine wave frequency, amplitude, offset and phase.
Use the max
plugin if you need to select the max value of two channels.
It has two input ports "In 1" and "In 2" and one output port "Out".
Use the dcblock
plugin implements a DC blocker.
It has 8 input ports "In 1" to "In 8" and corresponding output ports "Out 1" to "Out 8". Not all ports need to be connected.
It also has 1 control input port "R" that controls the DC block R factor.
Use the ramp
plugin creates a linear ramp from Start
to Stop
.
It has 3 input control ports "Start", "Stop" and "Duration (s)". It also has one output port "Out". A linear ramp will be created from "Start" to "Stop" for a duration given by the "Duration (s)" control in (fractional) seconds. The current value will be stored in the output notify port "Current".
The ramp output can, for example, be used as input for the mult
plugin to create a volume ramp up or down. For more a more coarse volume ramp, the "Current" value can be used in the linear
plugin.
There is an optional builtin SOFA filter available.
The spatializer can be used to place the sound in a 3D space.
The spatializer has an input port "In" and a stereo pair of output ports called "Out L" and "Out R". It requires a config section in the node declaration in this format:
The control can be changed at runtime to move the sounds around in the 3D space.
blocksize
specifies the size of the blocks to use in the FFT. It is a value between 64 and 256. When not specified, this value is computed automatically from the number of samples in the file.tailsize
specifies the size of the tail blocks to use in the FFT.filename
The SOFA file to load. SOFA files usually end in the .sofa extension and contain the HRTF for the various spatial positions.Azimuth
controls the azimuth, this is the direction the sound is coming from in degrees between 0 and 360. 0 is straight ahead. 90 is left, 180 behind, 270 right.Elevation
controls the elevation, this is how high/low the signal is in degrees between -90 and 90. 0 is straight in front, 90 is directly above and -90 directly below.Radius
controls how far away the signal is as a value between 0 and 100. default is 1.0.There is an optional EBU R128 filter available.
The ebur128 plugin can be used to measure the loudness of a signal.
It has 7 input ports "In FL", "In FR", "In FC", "In UNUSED", "In SL", "In SR" and "In DUAL MONO", corresponding to the different input channels for EBUR128. Not all ports need to be connected for this filter.
The input signal is passed unmodified on the "Out FL", "Out FR", "Out FC", "Out UNUSED", "Out SL", "Out SR" and "Out DUAL MONO" output ports.
There are 7 output control ports that contain the measured loudness information and that can be used to control the processing of the audio. Some of these ports contain values in LUFS, or "Loudness Units relative to Full Scale". These are negative values, closer to 0 is louder. You can use the lufs2gain plugin to convert this value to again to adjust a volume (See below).
"Momentary LUFS" contains the momentary loudness measurement with a 400ms window and 75% overlap. It works mostly like an R.M.S. meter.
"Shortterm LUFS" contains the shortterm loudness in LUFS over a 3 second window.
"Global LUFS" contains the global integrated loudness in LUFS over the max-history window. "Window LUFS" contains the global integrated loudness in LUFS over the max-window window.
"Range LU" contains the loudness range (LRA) in LU units.
"Peak" contains the peak loudness.
"True Peak" contains the true peak loudness oversampling the signal. This can more accurately reflect the peak compared to "Peak".
The node also has an optional config
section with extra configuration:
max-history
the maximum history to keep in (float) seconds. Default to 10.0max-window
the maximum window to keep in (float) seconds. Default to 0.0 You will need to set this to some value to get "Window LUFS" output control values.use-histogram
uses the histogram algorithm to calculate loudness. Defaults to false.The lufs2gain plugin can be used to convert LUFS control values to gain. It needs a target LUFS control input to drive the conversion.
It has 2 input control ports "LUFS" and "Target LUFS" and will produce 1 output control value "Gain". This gain can be used as input for the builtin linear
node, for example, to adust the gain.
Options with well-known behavior. Most options can be added to the global configuration or the individual streams:
Stream only properties:
This example uses the rnnoise LADSPA plugin to create a new virtual source.
Run with pipewire -c filter-chain.conf
. The configuration can also be put under pipewire.conf.d/
to run it inside the PipeWire server.
This example uses the ladpsa surround encoder to encode a 5.1 signal to a stereo Dolby Surround signal.