# Stereo to 5.1 upmix sink # # Copy this file into a conf.d/ directory such as # ~/.config/pipewire/filter-chain.conf.d/ # context.modules = [ { name = libpipewire-module-filter-chain args = { node.description = "Upmix Sink" filter.graph = { nodes = [ { type = builtin name = copyFL label = copy } { type = builtin name = copyFR label = copy } { type = builtin name = copyOFL label = copy } { type = builtin name = copyOFR label = copy } { # this mixes the front left and right together # for filtering the center and subwoofer signal- name = mixF type = builtin label = mixer control = { "Gain 1" = 0.707 "Gain 2" = 0.707 } } { # filtering of the FC and LFE channel. We use a 2 channel # parametric equalizer with custom filters for each channel. # This makes it possible to run the filters in parallel. type = builtin name = eq_FC_LFE label = param_eq config = { filters1 = [ # FC is a crossover filter (with 2 lowpass biquads) { type = bq_lowpass freq = 12000 }, { type = bq_lowpass freq = 12000 }, ] filters2 = [ # LFE is first a gain adjustment (with a highself) and # then a crossover filter (with 2 lowpass biquads) { type = bq_highshelf freq = 0 gain = -20.0 }, # gain -20dB { type = bq_lowpass freq = 120 }, { type = bq_lowpass freq = 120 }, ] } } { # for the rear channels, we subtract the front channels. Do this # with a mixer with negative gain to flip the sign. name = subR type = builtin label = mixer control = { "Gain 1" = 0.707 "Gain 2" = -0.707 } } { # a delay for the rear Left channel. This can be # replaced with the convolver below. */ type = builtin name = delayRL label = delay config = { "max-delay" = 1 } control = { "Delay (s)" = 0.012 } } { # a delay for the rear Right channel. This can be # replaced with the convolver below. */ type = builtin name = delayRR label = delay config = { "max-delay" = 1 } control = { "Delay (s)" = 0.012 } } { # an optional convolver with a hilbert curve to # change the phase. It also has a delay, making the above # left delay filter optional. type = builtin name = convRL label = convolver config = { gain = 1.0 delay = 0.012 filename = "/hilbert" length = 33 } } { # an optional convolver with a hilbert curve to # change the phase. It also has a delay, making the above # right delay filter optional. type = builtin name = convRR label = convolver config = { gain = -1.0 delay = 0.012 filename = "/hilbert" length = 33 } } ] links = [ { output = "copyFL:Out" input="mixF:In 1" } { output = "copyFR:Out" input="mixF:In 2" } { output = "copyFL:Out" input="copyOFR:In" } { output = "copyFR:Out" input="copyOFL:In" } { output = "mixF:Out" input="eq_FC_LFE:In 1" } { output = "mixF:Out" input="eq_FC_LFE:In 2" } { output = "copyFL:Out" input="subR:In 1" } { output = "copyFR:Out" input="subR:In 2" } # here we can choose to just delay or also convolve # #{ output = "subR:Out" input="delayRL:In" } #{ output = "subR:Out" input="delayRR:In" } { output = "subR:Out" input="convRL:In" } { output = "subR:Out" input="convRR:In" } ] inputs = [ "copyFL:In" "copyFR:In" ] outputs = [ "copyOFL:Out" "copyOFR:Out" "eq_FC_LFE:Out 1" "eq_FC_LFE:Out 2" # here we can choose to just delay or also convolve # #"delayRL:Out" #"delayRR:Out" "convRL:Out" "convRR:Out" ] } capture.props = { node.name = "effect_input.upmix_5.1" media.class = "Audio/Sink" audio.position = [ FL FR ] } playback.props = { node.name = "effect_output.upmix_5.1" audio.position = [ FL FR FC LFE RL RR ] stream.dont-remix = true node.passive = true } } } ]