1libpipewire-module-filteMri-scchealilna(n7e)ous InformatliiobnpiMpaenwuiarle-module-filter-chain(7)
2
3
4
6 libpipewire-module-filter-chain - Filter-Chain
7
9 The filter-chain allows you to create an arbitrary processing graph
10 from LADSPA, LV2 and builtin filters.
11
12 This filter can be made into a virtual sink/source or between any 2
13 nodes in the graph.
14
15 The filter chain is built with 2 streams, a capture stream providing
16 the input to the filter chain and a playback stream sending out the
17 filtered stream to the next nodes in the graph.
18
19 Because both ends of the filter-chain are built with streams, the
20 session manager can manage the configuration and connection with the
21 sinks and sources automatically.
22
24 libpipewire-module-filter-chain
25
27 • node.description: a human readable name for the filter chain
28
29 • filter.graph = []: a description of the filter graph to run, see
30 below
31
32 • capture.props = {}: properties to be passed to the input stream
33
34 • playback.props = {}: properties to be passed to the output stream
35
37 The general structure of the graph description is as follows:
38
39 filter.graph = {
40 nodes = [
41 {
42 type = <ladspa | lv2 | builtin | sofa>
43 name = <name>
44 plugin = <plugin>
45 label = <label>
46 config = {
47 <configkey> = <value> ...
48 }
49 control = {
50 <controlname|controlindex> = <value> ...
51 }
52 }
53 ...
54 ]
55 links = [
56 { output = <portname> input = <portname> }
57 ...
58 ]
59 inputs = [ <portname> ... ]
60 outputs = [ <portname> ... ]
61 capture.volumes = [
62 { control = <portname> min = <value> max = <value> scale = <scale> } ...
63 ]
64 playback.volumes = [
65 { control = <portname> min = <value> max = <value> scale = <scale> } ...
66 ]
67 }
68
69 Nodes
70 Nodes describe the processing filters in the graph. Use a tool like
71 lv2ls or listplugins to get a list of available plugins, labels and the
72 port names.
73
74 • type is one of ladspa, lv2, builtin or sofa.
75
76 • name is the name for this node, you might need this later to refer to
77 this node and its ports when setting controls or making links.
78
79 • plugin is the type specific plugin name.
80
81 • For LADSPA plugins it will append .so to find the shared object
82 with that name in the LADSPA plugin path.
83
84 • For LV2, this is the plugin URI obtained with lv2ls.
85
86 • For builtin and sofa this is ignored
87
88 • label is the type specific filter inside the plugin.
89
90 • For LADSPA this is the label
91
92 • For LV2 this is unused
93
94 • For builtin and sofa this is the name of the filter to use
95
96 • config contains a filter specific configuration section. Some plugins
97 need this. (convolver, sofa, delay, ...)
98
99 • control contains the initial values for the control ports of the
100 filter. normally these are given with the port name but it is also
101 possible to give the control index as the key.
102
103 Links
104 Links can be made between ports of nodes. The portname is given as
105 <node_name>:<port_name>.
106
107 You can tee the output of filters to multiple other filters. You need
108 to use a mixer if you want the output of multiple filters to go into
109 one filter input port.
110
111 links can be omited when the graph has just 1 filter.
112
113 Inputs and Outputs
114 These are the entry and exit ports into the graph definition. Their
115 number defines the number of channels used by the filter-chain.
116
117 The <portname> can be null when a channel is to be ignored.
118
119 Each input/output in the graph can only be linked to one filter
120 input/output. You need to use the copy builtin filter if the stream
121 signal needs to be routed to multiple filters. You need to use the
122 mixer builtin plugin if multiple graph outputs need to go to one output
123 stream.
124
125 inputs and outputs can be omitted, in which case the filter-chain will
126 use all inputs from the first filter and all outputs from the last
127 filter node. The graph will then be duplicated as many times to match
128 the number of input/output channels of the streams.
129
130 Volumes
131 Normally the volume of the sink/source is handled by the stream
132 software volume. With the capture.volumes and playback.volumes
133 properties this can be handled by a control port in the graph instead.
134 Use capture.volumes for the volume of the input of the filter (when for
135 example used as a sink). Use playback,volumes for the volume of the
136 output of the filter (when for example used as a source).
137
138 The min and max values (defaults 0.0 and 1.0) respectively can be used
139 to scale and translate the volume min and max values.
140
141 Normally the control values are linear and it is assumed that the
142 plugin does not perform any scaling to the values. This can be changed
143 with the scale property. By default this is linear but it can be set to
144 cubic when the control applies a cubic transformation.
145
147 There are some useful builtin filters available. You select them with
148 the label of the filter node.
149
150 Mixer
151 Use the mixer plugin if you have multiple input signals that need to be
152 mixed together.
153
154 The mixer plugin has up to 8 input ports labeled 'In 1' to 'In 8' and
155 each with a gain control labeled 'Gain 1' to 'Gain 8'. There is an
156 output port labeled 'Out'. Unused input ports will be ignored and not
157 cause overhead.
158
159 Copy
160 Use the copy plugin if you need to copy a stream input signal to
161 multiple filters.
162
163 It has one input port 'In' and one output port 'Out'.
164
165 Biquads
166 Biquads can be used to do all kinds of filtering. They are also used
167 when creating equalizers.
168
169 All biquad filters have an input port 'In' and an output port 'Out'.
170 They have a 'Freq', 'Q' and 'Gain' control. Their meaning depends on
171 the particular biquad that is used. The biquads also have 'b0', 'b1',
172 'b2', 'a0', 'a1' and 'a2' ports that are read-only except for the
173 bq_raw biquad, which can configure default values depending on the
174 graph rate and change those at runtime.
175
176 We refer to https://arachnoid.com/BiQuadDesigner/index.html for an
177 explanation of the controls.
178
179 The following labels can be used:
180
181 • bq_lowpass a lowpass filter.
182
183 • bq_highpass a highpass filter.
184
185 • bq_bandpass a bandpass filter.
186
187 • bq_lowshelf a low shelf filter.
188
189 • bq_highshelf a high shelf filter.
190
191 • bq_peaking a peaking filter.
192
193 • bq_notch a notch filter.
194
195 • bq_allpass an allpass filter.
196
197 • bq_raw a raw biquad filter. You need a config section to specify
198 coefficients per sample rate. The coefficients of the sample rate
199 closest to the graph rate are selected:
200
201 filter.graph = {
202 nodes = [
203 {
204 type = builtin
205 name = ...
206 label = bq_raw
207 config = {
208 coefficients = [
209 { rate = 44100, b0=.., b1=.., b2=.., a0=.., a1=.., a2=.. },
210 { rate = 48000, b0=.., b1=.., b2=.., a0=.., a1=.., a2=.. },
211 { rate = 192000, b0=.., b1=.., b2=.., a0=.., a1=.., a2=.. }
212 ]
213 }
214 ...
215 }
216 }
217 ...
218 }
219
220 Convolver
221 The convolver can be used to apply an impulse response to a signal. It
222 is usually used for reverbs or virtual surround. The convolver is
223 implemented with a fast FFT implementation.
224
225 The convolver has an input port 'In' and an output port 'Out'. It
226 requires a config section in the node declaration in this format:
227
228 filter.graph = {
229 nodes = [
230 {
231 type = builtin
232 name = ...
233 label = convolver
234 config = {
235 blocksize = ...
236 tailsize = ...
237 gain = ...
238 delay = ...
239 filename = ...
240 offset = ...
241 length = ...
242 channel = ...
243 resample_quality = ...
244 }
245 ...
246 }
247 }
248 ...
249 }
250
251 • blocksize specifies the size of the blocks to use in the FFT. It is a
252 value between 64 and 256. When not specified, this value is computed
253 automatically from the number of samples in the file.
254
255 • tailsize specifies the size of the tail blocks to use in the FFT.
256
257 • gain the overall gain to apply to the IR file.
258
259 • delay The extra delay (in samples) to add to the IR.
260
261 • filename The IR to load or create. Possible values are:
262
263 • /hilbert creates a hilbert function that can be used to phase shift
264 the signal by +/-90 degrees. The length will be used as the number
265 of coefficients.
266
267 • /dirac creates a Dirac function that can be used as gain.
268
269 • A filename to load as the IR. This needs to be a file format
270 supported by sndfile.
271
272 • [ filename, ... ] an array of filenames. The file with the closest
273 samplerate match with the graph samplerate will be used.
274
275 • offset The sample offset in the file as the start of the IR.
276
277 • length The number of samples to use as the IR.
278
279 • channel The channel to use from the file as the IR.
280
281 • resample_quality The resample quality in case the IR does not match
282 the graph samplerate.
283
284 Delay
285 The delay can be used to delay a signal in time.
286
287 The delay has an input port 'In' and an output port 'Out'. It also has
288 a 'Delay (s)' control port. It requires a config section in the node
289 declaration in this format:
290
291 filter.graph = {
292 nodes = [
293 {
294 type = builtin
295 name = ...
296 label = delay
297 config = {
298 "max-delay" = ...
299 }
300 control = {
301 "Delay (s)" = ...
302 }
303 ...
304 }
305 }
306 ...
307 }
308
309 • max-delay the maximum delay in seconds. The 'Delay (s)' parameter
310 will be clamped to this value.
311
312 Invert
313 The invert plugin can be used to invert the phase of the signal.
314
315 It has an input port 'In' and an output port 'Out'.
316
317 Clamp
318 The clamp plugin can be used to clamp samples between min and max
319 values.
320
321 It has an input port 'In' and an output port 'Out'. It also has a
322 'Control' and 'Notify' port for the control values.
323
324 The final result is clamped to the 'Min' and 'Max' control values.
325
326 Linear
327 The linear plugin can be used to apply a linear transformation on
328 samples or control values.
329
330 It has an input port 'In' and an output port 'Out'. It also has a
331 'Control' and 'Notify' port for the control values.
332
333 The control value 'Mult' and 'Add' are used to configure the linear
334 transform. Each sample or control value will be calculated as: new =
335 old * Mult + Add.
336
337 Reciprocal
338 The recip plugin can be used to calculate the reciprocal (1/x) of
339 samples or control values.
340
341 It has an input port 'In' and an output port 'Out'. It also has a
342 'Control' and 'Notify' port for the control values.
343
344 Exp
345 The exp plugin can be used to calculate the exponential (base^x) of
346 samples or control values.
347
348 It has an input port 'In' and an output port 'Out'. It also has a
349 'Control' and 'Notify' port for the control values.
350
351 The control value 'Base' is used to calculate base ^ x for each sample.
352
353 Log
354 The log plugin can be used to calculate the logarithm of samples or
355 control values.
356
357 It has an input port 'In' and an output port 'Out'. It also has a
358 'Control' and 'Notify' port for the control values.
359
360 The control value 'Base', 'M1' and 'M2' are used to calculate out = M2
361 * log2f(fabsf(in * M1)) / log2f(Base) for each sample.
362
363 Multiply
364 The mult plugin can be used to multiply samples together.
365
366 It has 8 input ports named 'In 1' to 'In 8' and an output port 'Out'.
367
368 All input ports samples are multiplied together into the output. Unused
369 input ports will be ignored and not cause overhead.
370
371 Sine
372 The sine plugin generates a sine wave.
373
374 It has an output port 'Out' and also a control output port 'notify'.
375
377 There is an optional builtin SOFA filter available.
378
379 Spatializer
380 The spatializer can be used to place the sound in a 3D space.
381
382 The spatializer has an input port 'In' and a stereo pair of output
383 ports called 'Out L' and 'Out R'. It requires a config section in the
384 node declaration in this format:
385
386 The control can be changed at runtime to move the sounds around in the
387 3D space.
388
389 filter.graph = {
390 nodes = [
391 {
392 type = sofa
393 name = ...
394 label = spatializer
395 config = {
396 blocksize = ...
397 tailsize = ...
398 filename = ...
399 }
400 control = {
401 "Azimuth" = ...
402 "Elevation" = ...
403 "Radius" = ...
404 }
405 ...
406 }
407 }
408 ...
409 }
410
411 • blocksize specifies the size of the blocks to use in the FFT. It is a
412 value between 64 and 256. When not specified, this value is computed
413 automatically from the number of samples in the file.
414
415 • tailsize specifies the size of the tail blocks to use in the FFT.
416
417 • filename The SOFA file to load. SOFA files usually end in the .sofa
418 extension and contain the HRTF for the various spatial positions.
419
420 • Azimuth controls the azimuth, this is the direction the sound is
421 coming from in degrees between 0 and 360. 0 is straight ahead. 90 is
422 left, 180 behind, 270 right.
423
424 • Elevation controls the elevation, this is how high/low the signal is
425 in degrees between -90 and 90. 0 is straight in front, 90 is directly
426 above and -90 directly below.
427
428 • Radius controls how far away the signal is as a value between 0 and
429 100. default is 1.0.
430
432 Options with well-known behavior. Most options can be added to the
433 global configuration or the individual streams:
434
435 • remote.name
436
437 • audio.rate
438
439 • audio.channels
440
441 • audio.position
442
443 • media.name
444
445 • node.latency
446
447 • node.description
448
449 • node.group
450
451 • node.link.group
452
453 • node.virtual
454
455 • node.name: See notes below. If not specified, defaults to 'filter-
456 chain-<pid>-<module-id>'.
457
458 Stream only properties:
459
460 • media.class
461
462 • node.name: if not given per stream, the global node.name will be
463 prefixed with 'input.' and 'output.' to generate a capture and
464 playback stream node.name respectively.
465
467 This example uses the rnnoise LADSPA plugin to create a new virtual
468 source.
469
470 context.modules = [
471 { name = libpipewire-module-filter-chain
472 args = {
473 node.description = "Noise Canceling source"
474 media.name = "Noise Canceling source"
475 filter.graph = {
476 nodes = [
477 {
478 type = ladspa
479 name = rnnoise
480 plugin = ladspa/librnnoise_ladspa
481 label = noise_suppressor_stereo
482 control = {
483 "VAD Threshold (%)" 50.0
484 }
485 }
486 ]
487 }
488 capture.props = {
489 node.name = "capture.rnnoise_source"
490 node.passive = true
491 }
492 playback.props = {
493 node.name = "rnnoise_source"
494 media.class = Audio/Source
495 }
496 }
497 }
498 ]
499
501 This example uses the ladpsa surround encoder to encode a 5.1 signal to
502 a stereo Dolby Surround signal.
503
504 \code{.unparsed}
505 context.modules = [
506 { name = libpipewire-module-filter-chain
507 args = {
508 node.description = "Dolby Surround Sink"
509 media.name = "Dolby Surround Sink"
510 filter.graph = {
511 nodes = [
512 {
513 type = builtin
514 name = mixer
515 label = mixer
516 control = { "Gain 1" = 0.5 "Gain 2" = 0.5 }
517 }
518 {
519 type = ladspa
520 name = enc
521 plugin = surround_encoder_1401
522 label = surroundEncoder
523 }
524 ]
525 links = [
526 { output = "mixer:Out" input = "enc:S" }
527 ]
528 inputs = [ "enc:L" "enc:R" "enc:C" null "mixer:In 1" "mixer:In 2" ]
529 outputs = [ "enc:Lt" "enc:Rt" ]
530 }
531 capture.props = {
532 node.name = "effect_input.dolby_surround"
533 media.class = Audio/Sink
534 audio.channels = 6
535 audio.position = [ FL FR FC LFE SL SR ]
536 }
537 playback.props = {
538 node.name = "effect_output.dolby_surround"
539 node.passive = true
540 audio.channels = 2
541 audio.position = [ FL FR ]
542 }
543 }
544 }
545 ]
546
547PipeWire 1.0.0 libpipewire-module-filter-chain(7)