diff --git a/hosts/common/programs/pipewire/20-virtual.conf b/hosts/common/programs/pipewire/20-virtual.conf new file mode 100644 index 000000000..c504cdb08 --- /dev/null +++ b/hosts/common/programs/pipewire/20-virtual.conf @@ -0,0 +1,64 @@ +# Virtual stereo sink +# +# the main purpose is to provide a junction where audio can be selectively routed *to* this device, +# and then consumers can tunnel it to some other place. +# for example, `blast` can be used to cast this sink (source) to a TV. +# +# based on: +# but modified: +# - duplicate both FL *and* FR + +context.modules = [ + { name = libpipewire-module-filter-chain + flags = [ nofail ] + args = { + node.description = "Virtual Sink" + media.name = "Virtual Sink" + filter.graph = { + nodes = [ + { + name = copyIL + type = builtin + label = copy + } + { + name = copyIR + type = builtin + label = copy + } + { + name = copyOL + type = builtin + label = copy + } + { + name = copyOR + type = builtin + label = copy + } + ] + links = [ + # we can only tee from nodes, not inputs so we need + # to copy the inputs and then tee. + { output = "copyIL:Out" input = "copyOL:In" } + { output = "copyIR:Out" input = "copyOR:In" } + ] + inputs = [ "copyIL:In" "copyIR:In" ] + outputs = [ "copyOL:Out" "copyOR:Out" ] + } + capture.props = { + node.name = "effect_input.virtual" + media.class = Audio/Sink + audio.channels = 2 + audio.position = [ FL FR ] + } + playback.props = { + node.name = "effect_output.virtual" + node.passive = true + audio.channels = 2 + audio.position = [ FL FR ] + } + } + } +] + diff --git a/hosts/common/programs/pipewire/default.nix b/hosts/common/programs/pipewire/default.nix index 5fd5cddf6..0a73c6ac3 100644 --- a/hosts/common/programs/pipewire/default.nix +++ b/hosts/common/programs/pipewire/default.nix @@ -102,6 +102,7 @@ in default.clock.max-quantum = ${builtins.toString cfg.config.max-quantum} } ''; + fs.".config/pipewire/pipewire.conf.d/20-virtual.conf".symlink.target = ./20-virtual.conf; fs.".config/pipewire/pipewire.conf.d/20-spatializer-7.1.conf".symlink.target = ./20-spatializer-7.1.conf; # reduce realtime scheduling priority to prevent GPU instability,