summaryrefslogtreecommitdiffstats
path: root/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl
diff options
context:
space:
mode:
Diffstat (limited to 'meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl')
-rw-r--r--meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/00-functions.lua27
-rw-r--r--meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/50-AGL-equalizer.conf75
-rw-r--r--meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/50-AGL-media-role-nodes.conf184
-rw-r--r--meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.conf73
-rw-r--r--meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.lua.d/10-default-policy.lua137
5 files changed, 259 insertions, 237 deletions
diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/00-functions.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/00-functions.lua
deleted file mode 100644
index 7e1794df0..000000000
--- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/00-functions.lua
+++ /dev/null
@@ -1,27 +0,0 @@
-components = {}
-
-function load_module(m)
- if not components[m] then
- components[m] = { "libwireplumber-module-" .. m, type = "module" }
- end
-end
-
-function load_pw_module(m)
- if not components[m] then
- components[m] = { "libpipewire-module-" .. m, type = "pw_module" }
- end
-end
-
-function load_script(s, a)
- if not components[s] then
- components[s] = { s, type = "script/lua", args = a }
- end
-end
-
-function load_monitor(s, a)
- load_script("monitors/" .. s .. ".lua", a)
-end
-
-function load_access(s, a)
- load_script("access/access-" .. s .. ".lua", a)
-end
diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/50-AGL-equalizer.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/50-AGL-equalizer.conf
new file mode 100644
index 000000000..061eae96c
--- /dev/null
+++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/50-AGL-equalizer.conf
@@ -0,0 +1,75 @@
+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 ]
+ }
+]
diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/50-AGL-media-role-nodes.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/50-AGL-media-role-nodes.conf
new file mode 100644
index 000000000..4e4f3323f
--- /dev/null
+++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/50-AGL-media-role-nodes.conf
@@ -0,0 +1,184 @@
+wireplumber.profiles = {
+ policy = {
+ agl.policy.linking.role-based.loopbacks = required
+ }
+}
+
+wireplumber.settings = {
+ # This sets a default media role to be applied to streams that don't have
+ # a role already set. This allows you to force all streams to go through
+ # the role loopbacks. If not set, then streams without a role will follow
+ # the standard desktop policy and will link to the default sink
+ node.stream.default-media-role = "Multimedia"
+
+ # The volume level that is applied when ducking
+ # Note that this is a raw linear volume, not cubic (0.2 is 58%)
+ linking.role-based.duck-level = 0.2
+
+ # Do not allow changing the targets of streams via `target.object` metadata
+ linking.allow-moving-streams = false
+}
+
+wireplumber.components.rules = [
+ # This encodes common arguments and dependencies of the role loopbacks so that
+ # we don't have to repeateadly write them on all instances below
+ {
+ matches = [
+ {
+ provides = "~loopback.sink.*"
+ }
+ ]
+ actions = {
+ merge = {
+ arguments = {
+ capture.props = {
+ # Explicitly mark all these sinks as valid role-based policy
+ # targets, meaning that any links between streams and these sinks
+ # will be managed by the role-based policy
+ policy.role-based.target = true
+
+ audio.position = [ FL, FR ]
+ media.class = Audio/Sink
+ }
+ playback.props = {
+ # 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 an unused role to make sure that loopbacks don't
+ # accidentally chain-link on to one another, especially when
+ # node.stream.default-media-role is configured in the settings
+ media.role = "Loopback"
+ }
+ }
+ requires = [ pw.node-factory.adapter ]
+ after = [ support.standard-event-source ]
+ }
+ }
+ }
+]
+
+wireplumber.components = [
+ {
+ type = virtual, provides = agl.policy.linking.role-based.loopbacks
+ requires = [ loopback.sink.role.multimedia
+ loopback.sink.role.speech-low
+ loopback.sink.role.custom-low
+ loopback.sink.role.navigation
+ loopback.sink.role.speech-high
+ loopback.sink.role.custom-high
+ loopback.sink.role.communication
+ loopback.sink.role.emergency ]
+ }
+ {
+ name = libpipewire-module-loopback, type = pw-module
+ arguments = {
+ node.name = "loopback.sink.role.multimedia"
+ node.description = "Multimedia"
+ capture.props = {
+ device.intended-roles = [ "Music", "Movie", "Game", "Multimedia" ]
+ policy.role-based.priority = 25
+ policy.role-based.action.same-priority = "mix"
+ policy.role-based.action.lower-priority = "mix"
+ }
+ }
+ provides = loopback.sink.role.multimedia
+ }
+ {
+ name = libpipewire-module-loopback, type = pw-module
+ arguments = {
+ node.name = "loopback.sink.role.speech-low"
+ node.description = "Speech (Low Priority)"
+ capture.props = {
+ device.intended-roles = [ "Speech-Low" ]
+ policy.role-based.priority = 30
+ policy.role-based.action.same-priority = "mix"
+ policy.role-based.action.lower-priority = "cork"
+ }
+ }
+ provides = loopback.sink.role.speech-low
+ }
+ {
+ name = libpipewire-module-loopback, type = pw-module
+ arguments = {
+ node.name = "loopback.sink.role.custom-low"
+ node.description = "Custom role (Low Priority)"
+ capture.props = {
+ device.intended-roles = [ "Custom-Low" ]
+ policy.role-based.priority = 35
+ policy.role-based.action.same-priority = "mix"
+ policy.role-based.action.lower-priority = "cork"
+ }
+ }
+ provides = loopback.sink.role.custom-low
+ }
+ {
+ name = libpipewire-module-loopback, type = pw-module
+ arguments = {
+ node.name = "loopback.sink.role.navigation"
+ node.description = "Navigation"
+ capture.props = {
+ device.intended-roles = [ "Navigation" ]
+ policy.role-based.priority = 50
+ policy.role-based.action.same-priority = "mix"
+ policy.role-based.action.lower-priority = "duck"
+ }
+ }
+ provides = loopback.sink.role.navigation
+ }
+ {
+ name = libpipewire-module-loopback, type = pw-module
+ arguments = {
+ node.name = "loopback.sink.role.speech-high"
+ node.description = "Speech (High Priority)"
+ capture.props = {
+ device.intended-roles = [ "Speech-High" ]
+ policy.role-based.priority = 60
+ policy.role-based.action.same-priority = "mix"
+ policy.role-based.action.lower-priority = "cork"
+ }
+ }
+ provides = loopback.sink.role.speech-high
+ }
+ {
+ name = libpipewire-module-loopback, type = pw-module
+ arguments = {
+ node.name = "loopback.sink.role.custom-high"
+ node.description = "Custom role (High Priority)"
+ capture.props = {
+ device.intended-roles = [ "Custom-High" ]
+ policy.role-based.priority = 65
+ policy.role-based.action.same-priority = "mix"
+ policy.role-based.action.lower-priority = "cork"
+ }
+ }
+ provides = loopback.sink.role.custom-high
+ }
+ {
+ name = libpipewire-module-loopback, type = pw-module
+ arguments = {
+ node.name = "loopback.sink.role.communication"
+ node.description = "Communication"
+ capture.props = {
+ device.intended-roles = [ "Communication" ]
+ policy.role-based.priority = 75
+ policy.role-based.action.same-priority = "mix"
+ policy.role-based.action.lower-priority = "cork"
+ }
+ }
+ provides = loopback.sink.role.communication
+ }
+ {
+ name = libpipewire-module-loopback, type = pw-module
+ arguments = {
+ node.name = "loopback.sink.role.emergency"
+ node.description = "Emergency"
+ capture.props = {
+ device.intended-roles = [ "Emergency", "Alert" ]
+ policy.role-based.priority = 99
+ policy.role-based.action.same-priority = "mix"
+ policy.role-based.action.lower-priority = "cork"
+ }
+ }
+ provides = loopback.sink.role.emergency
+ }
+]
diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.conf
deleted file mode 100644
index 42f714849..000000000
--- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.conf
+++ /dev/null
@@ -1,73 +0,0 @@
-# WirePlumber daemon context configuration #
-
-context.properties = {
- ## Properties to configure the PipeWire context and some modules
-
- application.name = "WirePlumber Policy"
- log.level = 2
- wireplumber.script-engine = lua-scripting
- wireplumber.export-core = false
-
- #mem.mlock-all = false
- #support.dbus = true
-}
-
-context.spa-libs = {
- #<factory-name regex> = <library-name>
- #
- # 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 = [
- #{ name = <module-name>
- # [ args = { <key> = <value> ... } ]
- # [ flags = [ [ ifexists ] [ nofail ] ]
- #}
- #
- # PipeWire modules to load.
- # If ifexists is given, the module is ignored when it is not found.
- # If nofail is given, module initialization failures are ignored.
- #
-
- # 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 }
-
- # Allows creating devices that run in the context of the
- # client. Is used by the session manager.
- { name = libpipewire-module-client-device }
-
- # Makes a factory for wrapping nodes in an adapter with a
- # converter and resampler.
- { name = libpipewire-module-adapter }
-
- # Allows applications to create metadata objects. It creates
- # a factory for Metadata objects.
- { name = libpipewire-module-metadata }
-
- # Provides factories to make session manager objects.
- { name = libpipewire-module-session-manager }
-]
-
-wireplumber.components = [
- #{ name = <component-name>, type = <component-type> }
- #
- # WirePlumber components to load
- #
-
- # The lua scripting engine
- { name = libwireplumber-module-lua-scripting, type = module }
-
- # The lua configuration file
- # Other components are loaded from there
- { name = policy.lua, type = config/lua }
-]
diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.lua.d/10-default-policy.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.lua.d/10-default-policy.lua
deleted file mode 100644
index 6814fce4d..000000000
--- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.lua.d/10-default-policy.lua
+++ /dev/null
@@ -1,137 +0,0 @@
--- Policy config file --
-
-policy_config = {}
-
-policy_config.endpoints = {
- -- [endpoint name] = { endpoint properties }
- ["endpoint.capture"] = {
- ["media.class"] = "Audio/Source",
- ["role"] = "Capture",
- },
- ["endpoint.multimedia"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Multimedia",
- },
- ["endpoint.speech_low"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Speech-Low",
- },
- ["endpoint.custom_low"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Custom-Low",
- },
- ["endpoint.navigation"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Navigation",
- },
- ["endpoint.speech_high"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Speech-High",
- },
- ["endpoint.custom_high"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Custom-High",
- },
- ["endpoint.communication"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Communication",
- },
- ["endpoint.emergency"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Emergency",
- },
-}
-
-policy_config.policy = {
- ["move"] = false, -- moves session items when metadata target.node changes
- ["follow"] = true, -- moves session items to the default device when it has changed
-
- -- Set to 'true' to disable channel splitting & merging on nodes and enable
- -- passthrough of audio in the same format as the format of the device.
- -- Note that this breaks JACK support; it is generally not recommended
- ["audio.no-dsp"] = false,
-
- -- how much to lower the volume of lower priority streams when ducking
- -- note that this is a linear volume modifier (not cubic as in pulseaudio)
- ["duck.level"] = 0.2,
-
- ["roles"] = {
- ["Capture"] = {
- ["alias"] = { "Multimedia", "Music", "Voice", "Capture" },
- ["priority"] = 25,
- ["action.default"] = "cork",
- ["action.Capture"] = "mix",
- ["media.class"] = "Audio/Source",
- },
- ["Multimedia"] = {
- ["alias"] = { "Movie", "Music", "Game" },
- ["priority"] = 25,
- ["action.default"] = "mix",
- },
- ["Speech-Low"] = {
- ["priority"] = 30,
- ["action.default"] = "cork",
- ["action.Speech-Low"] = "mix",
- },
- ["Custom-Low"] = {
- ["priority"] = 35,
- ["action.default"] = "cork",
- ["action.Custom-Low"] = "mix",
- },
- ["Navigation"] = {
- ["priority"] = 50,
- ["action.default"] = "duck",
- ["action.Navigation"] = "mix",
- },
- ["Speech-High"] = {
- ["priority"] = 60,
- ["action.default"] = "cork",
- ["action.Speech-High"] = "mix",
- },
- ["Custom-High"] = {
- ["priority"] = 65,
- ["action.default"] = "cork",
- ["action.Custom-High"] = "mix",
- },
- ["Communication"] = {
- ["priority"] = 75,
- ["action.default"] = "cork",
- ["action.Communication"] = "mix",
- },
- ["Emergency"] = {
- ["alias"] = { "Alert" },
- ["priority"] = 99,
- ["action.default"] = "cork",
- ["action.Emergency"] = "mix",
- },
- },
-}
-
--- Session item factories, building blocks for the session management graph
--- Do not disable these unless you really know what you are doing
-load_module("si-node")
-load_module("si-audio-adapter")
-load_module("si-standard-link")
-load_module("si-audio-endpoint")
-
--- API to access default nodes from scripts
-load_module("default-nodes-api")
-
--- API to access mixer controls, needed for volume ducking
-load_module("mixer-api")
-
--- Create endpoints statically at startup
-load_script("static-endpoints.lua", policy_config.endpoints)
-
--- Create session items for nodes that appear in the graph
-load_script("create-item.lua", policy_config.policy)
-
--- Link nodes to each other to make media flow in the graph
-load_script("policy-node.lua", policy_config.policy)
-
--- Link client nodes with endpoints to make media flow in the graph
-load_script("policy-endpoint-client.lua", policy_config.policy)
-load_script("policy-endpoint-client-links.lua", policy_config.policy)
-
--- Link endpoints with device nodes to make media flow in the graph
-load_script("policy-endpoint-device.lua", policy_config.policy)