wireplumber.profiles = { policy = { agl.filter.equalizer-sink = required } } wireplumber.components = [ { name = libpipewire-module-filter-chain, type = pw-module arguments = { node.description = "Equalizer Sink" media.name = "Equalizer Sink" filter.graph = { nodes = [ { type = builtin name = bass label = bq_lowshelf # the cut off freq of the bass filter can be adjusted here. control = { "Freq" = 250.0 "Q" = 1.0 "Gain" = 0.0 } } { type = builtin name = treble label = bq_peaking # the cut off freq of the treble filter can be adjusted here. control = { "Freq" = 6000.0 "Q" = 1.0 "Gain" = 0.0 } } ] links = [ { output = "bass:Out" input = "treble:In" } ] } audio.channels = 2 audio.position = [ FL FR ] capture.props = { node.name = "eq-sink" # this is a sink filter, so it will appear as a sink in wpctl/pactl/etc, # it will target a sink and can be chained with other sink smart filters media.class = Audio/Sink # treat this as a smart filter filter.smart = true # the unique name of the filter filter.smart.name = "agl.filter.equalizer-sink" ## set this to always link the filter to a particular sink ## or leave it unset in order to follow the default sink #filter.smart.target = { node.name = "alsa_output.pci-0000_00_01.0.analog-stereo" } ## here you can specify filter dependencies, using their names ## (filter.smart.name) if you set up many of them to be linked in a chain #filter.smart.before = [] #filter.smart.after = [] } playback.props = { node.name = "eq-output-stream" # This must be set to ensure that the real audio sink is suspended # when there is no active client stream linked node.passive = true # Set this to avoid linking the filter to role-based sinks when # role-based sinks are defined and node.stream.default-media-role is # configured in the settings media.role = "DSP" } } provides = agl.filter.equalizer-sink requires = [ pw.node-factory.adapter ] after = [ support.standard-event-source ] } ]