From a595f88cf1a49bdf73f14f728620c94e9bf16680 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 7 May 2021 16:27:06 +0200 Subject: [PATCH] filter-chain: add example run with pipewire -c filter-chain/demonic.conf --- src/daemon/filter-chain/demonic.conf | 100 +++++++++++++++++++++++++++ src/daemon/filter-chain/meson.build | 10 +++ src/daemon/meson.build | 1 + src/modules/module-filter-chain.c | 7 ++ 4 files changed, 118 insertions(+) create mode 100644 src/daemon/filter-chain/demonic.conf create mode 100644 src/daemon/filter-chain/meson.build diff --git a/src/daemon/filter-chain/demonic.conf b/src/daemon/filter-chain/demonic.conf new file mode 100644 index 000000000..ffe3ea83a --- /dev/null +++ b/src/daemon/filter-chain/demonic.conf @@ -0,0 +1,100 @@ +# filter-chain example config file for PipeWire version @VERSION@ # +context.properties = { + ## Configure properties in the system. + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + log.level = 0 +} + +context.spa-libs = { + # = + # + # Used to find spa factory names. It maps an spa factory name + # regular expression to a library name that should contain + # that factory. + # + audio.convert.* = audioconvert/libspa-audioconvert + support.* = support/libspa-support +} + +context.modules = [ + # Uses RTKit to boost the data thread priority. + { name = libpipewire-module-rtkit + args = { + #nice.level = -11 + #rt.prio = 88 + #rt.time.soft = 200000 + #rt.time.hard = 200000 + } + flags = [ ifexists nofail ] + } + + # The native communication protocol. + { name = libpipewire-module-protocol-native } + + # Allows creating nodes that run in the context of the + # client. Is used by all clients that want to provide + # data to PipeWire. + { name = libpipewire-module-client-node } + + # Makes a factory for wrapping nodes in an adapter with a + # converter and resampler. + { name = libpipewire-module-adapter } + + { name = libpipewire-module-filter-chain + args = { + #audio.format = F32 + #audio.rate = 48000 + audio.channels = 2 + #audio.position = [ FL FR ] + node.name = "filter-chain-demonic" + node.description = "Demonic example" + media.name = "Demonic example" + filter.graph = { + nodes = [ + { + name = rev + type = ladspa + plugin = revdelay_1605 + label = revdelay + control = { + "Delay Time (s)" = 2.0 + } + } + { + name = pitch + type = ladspa + plugin = am_pitchshift_1433 + label = amPitchshift + control = { + "Pitch shift" = 0.6 + } + } + { + name = rev2 + type = ladspa + plugin = g2reverb + label = G2reverb + control = { + "Reverb tail" = 0.5 + "Damping" = 0.9 + } + } + ] + links = [ + { output = "rev:Output" input = "pitch:Input" } + { output = "pitch:Output" input = "rev2:In L" } + ] + inputs = [ "rev:Input" ] + outputs = [ "rev2:Out L" ] + } + capture.props = { + #media.class = Audio/Sink + } + playback.props = { + #media.class = Audio/Source + } + } + } +] diff --git a/src/daemon/filter-chain/meson.build b/src/daemon/filter-chain/meson.build new file mode 100644 index 000000000..454becf2e --- /dev/null +++ b/src/daemon/filter-chain/meson.build @@ -0,0 +1,10 @@ +conf_files = [ + [ 'demonic.conf', 'demonic.conf' ], +] + +foreach c : conf_files + configure_file(input : c.get(0), + output : c.get(1), + configuration : conf_config, + install_dir : conf_install_dir / 'filter-chain') +endforeach diff --git a/src/daemon/meson.build b/src/daemon/meson.build index dd768f9d8..daa655d6e 100644 --- a/src/daemon/meson.build +++ b/src/daemon/meson.build @@ -87,6 +87,7 @@ custom_target('pipewire-uninstalled', # ) #endif +subdir('filter-chain') if not get_option('media-session').disabled() subdir('media-session.d') endif diff --git a/src/modules/module-filter-chain.c b/src/modules/module-filter-chain.c index 62801819b..0b430bfe5 100644 --- a/src/modules/module-filter-chain.c +++ b/src/modules/module-filter-chain.c @@ -1019,6 +1019,13 @@ static int setup_input_port(struct graph *graph, struct port *port) struct link *link; uint32_t i, n_hndl = port->node->n_hndl; + if (port->n_links > 1) { + pw_log_warn("mixing not implemented yet"); + /* FIXME, add a mixer node here, connect all linked peer + * data to the input, make output data, connect to the input + * port */ + } + spa_list_for_each(link, &port->link_list, input_link) { struct port *peer = link->output; for (i = 0; i < n_hndl; i++) {