From fc722f8aea13246ce7779acbb3a59681b64131a6 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Thu, 11 Feb 2021 14:13:55 +0200 Subject: meta-pipewire: backport pipewire updates from master Bug-AGL: SPEC-3844 Bug-AGL: SPEC-3900 Bug-AGL: SPEC-3909 Signed-off-by: George Kiagiadakis Change-Id: I3c32d0083f31f94b49e33c3dd546515d39df7867 Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl/+/26360 Reviewed-by: Jan-Simon Moeller Tested-by: Jan-Simon Moeller --- .../wireplumber-config-agl/00-functions.lua | 27 ++++ .../wireplumber-config-agl/00-spa-libs.lua | 10 ++ .../wireplumber-config-agl/10-default-policy.lua | 124 ++++++++++++++++ .../wireplumber-config-agl/30-alsa-monitor.lua | 161 +++++++++++++++++++++ .../wireplumber-config-agl/30-bluez-monitor.lua | 109 ++++++++++++++ .../wireplumber-config-agl/99-load-modules.lua | 22 +++ .../wireplumber-bluetooth.conf | 13 ++ .../wireplumber-config-agl/wireplumber.conf | 74 ++++++++++ 8 files changed, 540 insertions(+) create mode 100644 meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-functions.lua create mode 100644 meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-spa-libs.lua create mode 100644 meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/10-default-policy.lua create mode 100644 meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-alsa-monitor.lua create mode 100644 meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-bluez-monitor.lua create mode 100644 meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/99-load-modules.lua create mode 100644 meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber-bluetooth.conf create mode 100644 meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf (limited to 'meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl') diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-functions.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-functions.lua new file mode 100644 index 000000000..7e1794df0 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-functions.lua @@ -0,0 +1,27 @@ +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-config-agl/00-spa-libs.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-spa-libs.lua new file mode 100644 index 000000000..f284b92e7 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-spa-libs.lua @@ -0,0 +1,10 @@ +-- [""] = "" +-- +-- used to find spa factory names. It maps a spa factory name +-- regular expression to a library name that should contain that factory. +-- +spa_libs = { + ["api.alsa.*"] = "alsa/libspa-alsa", + ["api.v4l2.*"] = "v4l2/libspa-v4l2", + ["api.bluez5.*"] = "bluez5/libspa-bluez5", +} diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/10-default-policy.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/10-default-policy.lua new file mode 100644 index 000000000..3c04652f0 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/10-default-policy.lua @@ -0,0 +1,124 @@ +-- Default policy config file -- + +default_policy = {} + +default_policy.sessions = { + -- [session name] = { session properties } + ["audio"] = { ["media.type"] = "Audio" }, + --["video"] = { ["media.type"] = "Video" }, +} + +default_policy.endpoints = { + -- [endpoint name] = { endpoint properties } + + ["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", + }, +} + +default_policy.policy = { + ["move"] = false, -- moves session items when metadata target.node changes + ["follow"] = true, -- moves session items to the default device when it has changed + + ["roles"] = { + ["Multimedia"] = { + ["alias"] = { "Movie", "Music", "Game" }, + ["priority"] = 25, + ["action.default"] = "cork", + }, + ["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"] = "cork", + ["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", + }, + }, +} + +function default_policy.enable() + -- 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") + + -- Create sessions statically at startup + load_script("static-sessions.lua", default_policy.sessions) + + + -- Create endpoints statically at startup + load_script("static-endpoints.lua", default_policy.endpoints) + + -- Create session items for nodes that appear in the graph + load_script("create-item.lua") + + -- Link nodes to each other to make media flow in the graph + load_script("policy-node.lua", default_policy.policy) + + -- Link client nodes with endpoints to make media flow in the graph + load_script("policy-endpoint-client.lua", default_policy.policy) + load_script("policy-endpoint-client-links.lua", default_policy.policy) + + -- Link endpoints with device nodes to make media flow in the graph + load_script("policy-endpoint-device.lua", default_policy.policy) +end diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-alsa-monitor.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-alsa-monitor.lua new file mode 100644 index 000000000..fd6b7ecb5 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-alsa-monitor.lua @@ -0,0 +1,161 @@ +-- ALSA monitor config file -- + +alsa_monitor = {} + +alsa_monitor.properties = { + ["alsa.jack-device"] = false, + ["alsa.reserve"] = false, +} + +alsa_monitor.rules = { + -- disable ACP (PulseAudio-like profiles) + { + matches = { + { + { "device.name", "matches", "alsa_card.*" }, + }, + }, + apply_properties = { + ["api.alsa.use-acp"] = false, + }, + }, + + -- + -- Bump priority of well-known output devices + -- Higher priority means it gets selected as the default if it's present + -- + + -- USB card + { + matches = { + { + { "node.name", "matches", "alsa_output.*" }, + { "api.alsa.card.driver", "=", "USB-Audio" }, + }, + }, + apply_properties = { + ["priority.driver"] = 1300, + ["priority.session"] = 1300, + } + }, + + -- fiberdyne amp + { + matches = { + { + { "node.name", "matches", "alsa_output.*" }, + { "api.alsa.card.id", "=", "ep016ch" }, + }, + }, + apply_properties = { + ["priority.driver"] = 1200, + ["priority.session"] = 1200, + } + }, + + -- well-known internal devices + { + matches = { + { + -- ak4613 + { "node.name", "matches", "alsa_output.*" }, + { "api.alsa.card.id", "=", "ak4613" }, + { "api.alsa.pcm.device", "=", "0" }, + }, + { + -- dra7xx + { "node.name", "matches", "alsa_output.*" }, + { "api.alsa.card.id", "=", "DRA7xx-EVM" }, + }, + { + -- imx8mq + { "node.name", "matches", "alsa_output.*" }, + { "api.alsa.card.id", "=", "wm8524audio" }, + }, + { + -- rcarsound + { "node.name", "matches", "alsa_output.*" }, + { "api.alsa.card.id", "=", "rcarsound" }, + { "api.alsa.pcm.device", "=", "0" }, + }, + { + -- rpi3 + { "node.name", "matches", "alsa_output.*" }, + { "api.alsa.pcm.name", "=", "bcm2835 ALSA" }, + }, + }, + apply_properties = { + ["priority.driver"] = 1100, + ["priority.session"] = 1100, + } + }, + + -- + -- Same for input devices + -- + + -- USB card + { + matches = { + { + { "node.name", "matches", "alsa_input.*" }, + { "api.alsa.card.driver", "=", "USB-Audio" }, + }, + }, + apply_properties = { + ["priority.driver"] = 2300, + ["priority.session"] = 2300, + } + }, + + -- microchip mic + { + matches = { + { + { "node.name", "matches", "alsa_input.*" }, + { "api.alsa.card.id", "=", "ep811ch" }, + }, + }, + apply_properties = { + ["priority.driver"] = 2200, + ["priority.session"] = 2200, + } + }, + + -- well-known internal devices + { + matches = { + { + -- ak4613 + { "node.name", "matches", "alsa_input.*" }, + { "api.alsa.card.id", "=", "ak4613" }, + }, + { + -- dra7xx + { "node.name", "matches", "alsa_input.*" }, + { "api.alsa.card.id", "=", "DRA7xx-EVM" }, + }, + { + -- imx8mq + { "node.name", "matches", "alsa_input.*" }, + { "api.alsa.card.id", "=", "wm8524audio" }, + }, + { + -- rcarsound + { "node.name", "matches", "alsa_input.*" }, + { "api.alsa.card.id", "=", "rcarsound" }, + }, + }, + apply_properties = { + ["priority.driver"] = 2100, + ["priority.session"] = 2100, + } + }, +} + +function alsa_monitor.enable() + load_monitor("alsa", { + properties = alsa_monitor.properties, + rules = alsa_monitor.rules, + }) +end diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-bluez-monitor.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-bluez-monitor.lua new file mode 100644 index 000000000..fab9ac0e4 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-bluez-monitor.lua @@ -0,0 +1,109 @@ +-- Bluez monitor config file -- + +bluez_monitor = {} + +bluez_monitor.properties = { + -- Enable mSBC support, disabled by default. Be aware that + -- mSBC is not expected to work on all headset + adapter combinations. + -- This can be overloaded for a specific device and native backend + -- in rules section. + --["bluez5.msbc-support"] = false, + + --["bluez5.sbc-xq-support"] = true, + + -- Enabled headset roles (default: [ hsp_hs hfp_ag ]), this + -- property only applies to native backend. Currently some headsets + -- (Sony WH-1000XM3) are not working with both hsp_ag and hfp_ag + -- enabled, disable either hsp_ag or hfp_ag to work around it. + -- + -- Supported headset roles: hsp_hs (HSP Headset), + -- hsp_ag (HSP Audio Gateway), + -- hfp_hf (HFP Hands-Free), + -- hfp_ag (HFP Audio Gateway) + ["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]", + + -- Enabled A2DP codecs (default: all). + --["bluez5.codecs"] = "[ sbc aac ldac aptx aptx_hd ]", + + -- Properties for the A2DP codec configuration + --["bluez5.default.rate"] = 48000, + --["bluez5.default.channels"] = 2, +} + +bluez_monitor.rules = { + -- An array of matches/actions to evaluate. + { + -- Rules for matching a device or node. It is an array of + -- properties that all need to match the regexp. If any of the + -- matches work, the actions are executed for the object. + matches = { + { + -- This matches all cards. + { "device.name", "matches", "bluez_card.*" }, + }, + }, + -- Apply properties on the matched object. + apply_properties = { + -- Auto-connect device profiles on start up or when only partial + -- profiles have connected. Disabled by default if the property + -- is not specified. + --["bluez5.auto-connect"] = "[ hfp_hf hsp_hs a2dp_sink hfp_ag hsp_ag a2dp_source ]", + ["bluez5.auto-connect"] = "[ hfp_hf hsp_hs a2dp_sink ]", + + -- Overload mSBC support for native backend and a specific device. + --["bluez5.msbc-support"] = false, + + -- Hardware volume control (default: [ hfp_ag hsp_ag a2dp_source ]) + --["bluez5.hw-volume"] = "[ hfp_hf hsp_hs a2dp_sink hfp_ag hsp_ag a2dp_source ]", + + -- LDAC encoding quality + -- Available values: auto (Adaptive Bitrate, default) + -- hq (High Quality, 990/909kbps) + -- sq (Standard Quality, 660/606kbps) + -- mq (Mobile use Quality, 330/303kbps) + --["bluez5.a2dp.ldac.quality"] = "auto", + + -- AAC variable bitrate mode + -- Available values: 0 (cbr, default), 1-5 (quality level) + --["bluez5.a2dp.aac.bitratemode"] = 0, + + -- Profile connected first + -- Available values: a2dp-sink (default), headset-head-unit + --["device.profile"] = "a2dp-sink", + }, + }, + { + -- Make output hsp/hfp stream nodes go through the Communication endpoint + -- Unfortunately we cannot match on "media.class" because this property + -- is not known before the node is created + matches = { + { + { "api.bluez5.profile", "equals", "headset-audio-gateway" }, + { "factory.name", "matches", "*source*" }, + }, + }, + apply_properties = { + ["media.role"] = "Communication", + }, + }, + { + -- Make output a2dp stream nodes go through the Multimedia endpoint + -- Unfortunately we cannot match on "media.class" because this property + -- is not known before the node is created + matches = { + { + { "api.bluez5.profile", "equals", "a2dp-source" }, + }, + }, + apply_properties = { + ["media.role"] = "Multimedia", + }, + }, +} + +function bluez_monitor.enable() + load_monitor("bluez", { + properties = bluez_monitor.properties, + rules = bluez_monitor.rules, + }) +end diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/99-load-modules.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/99-load-modules.lua new file mode 100644 index 000000000..3e2c28a3a --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/99-load-modules.lua @@ -0,0 +1,22 @@ +-- Enable local & bluetooth audio devices +alsa_monitor.enable() +bluez_monitor.enable() + +-- Load policy +default_policy.enable() + +-- Implements storing metadata about objects in RAM +load_module("metadata") + +-- Keeps track of the "default" sources and sinks +load_module("default-nodes", { + -- do not store runtime user changes in $HOME + ["use-persistent-storage"] = false, +}) +load_module("default-nodes-api") + +-- Automatically suspends idle nodes after 3 seconds +load_script("suspend-node.lua") + +-- Automatically sets device profiles to 'On' +load_module("device-activation") diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber-bluetooth.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber-bluetooth.conf new file mode 100644 index 000000000..950e6a5d2 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber-bluetooth.conf @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf new file mode 100644 index 000000000..6f9b0b186 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf @@ -0,0 +1,74 @@ +# WirePlumber daemon context configuration # + +context.properties = { + ## Properties to configure the PipeWire context and some modules + + # 1=error/critical, 2=warning, 3=info, 4=debug, 5=trace + log.level = 2 + + wireplumber.script-engine = lua-scripting +} + +context.spa-libs = { + # = + # + # Used to find spa factory names. It maps an spa factory name + # regular expression to a library name that should contain + # that factory. + # + api.alsa.* = alsa/libspa-alsa + api.bluez5.* = bluez5/libspa-bluez5 + api.v4l2.* = v4l2/libspa-v4l2 + api.libcamera.* = libcamera/libspa-libcamera + audio.convert.* = audioconvert/libspa-audioconvert + support.* = support/libspa-support +} + +context.modules = [ + #{ name = + # [ args = { = ... } ] + # [ 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 = , type = } + # + # WirePlumber components to load + # + + # The lua scripting engine + { name = libwireplumber-module-lua-scripting, type = module } + + # The lua configuration file(s) + # Other components are loaded from there + { name = config.lua, type = config/lua } +] -- cgit 1.2.3-korg