diff options
author | George Kiagiadakis <george.kiagiadakis@collabora.com> | 2024-09-04 16:11:54 +0300 |
---|---|---|
committer | Jan-Simon Moeller <jsmoeller@linuxfoundation.org> | 2024-09-09 14:37:48 +0000 |
commit | b0db8f5e35a65ac44fa8931cfbc8386e3db85cf1 (patch) | |
tree | 90f4e2ce1838ceed6c61e1ad844ecb59018ed5a4 /meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl | |
parent | 7b8a17be6743d4e585392eb61a569a63c9ba4f4b (diff) |
meta-pipewire: update wireplumber to 0.5.6
- use the wireplumber recipe from meta-openembedded (albeit copied
here with the version changed, because 0.5.6 is not available in
meta-openembedded)
- rewrite configuration files as needed for 0.5.x
- configure wireplumber with the main service masked, using only the
template service files for a split-instance configuration.
split-instance facilitates the multi-container setup that is used
in the instrument cluster images.
Bug-AGL: SPEC-4934
Change-Id: Ica83f869cdc9527a9edce25e63918a2ba97a4766
Signed-off-by: George Kiagiadakis <george.kiagiadakis@collabora.com>
Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl/+/30243
Reviewed-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org>
Tested-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org>
(cherry picked from commit 5dd43491b6e44664ad1d2e2fb596b6cb248c88fb)
Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl/+/30209
Diffstat (limited to 'meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl')
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) |