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 | |
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
23 files changed, 617 insertions, 924 deletions
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 deleted file mode 100644 index 7e1794df0..000000000 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-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-config-agl/20-AGL-log.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/20-AGL-log.conf new file mode 100644 index 000000000..7dc8938fc --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/20-AGL-log.conf @@ -0,0 +1,5 @@ +context.properties = { + # F=fatal, E=critical, W=warning, N=notice, I=info, D=debug, T=trace + # See https://pipewire.pages.freedesktop.org/wireplumber/daemon/logging.html + log.level = "N" +} diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/20-AGL-profiles.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/20-AGL-profiles.conf new file mode 100644 index 000000000..d029887df --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/20-AGL-profiles.conf @@ -0,0 +1,29 @@ +# This configuration fragment sets up the split-instance profiles to include +# the standard "embedded" configuration of running systemwide without +# maintaining user state across reboots. +# In addition, runtime settings support is disabled on the device monitor +# instances, as it depends on the "sm-settings" metadata, which lives on the +# policy instance. In containerized setups (such as the IC demo), the policy +# instance runs in a container and the device monitors should not wait for it +# or depend on it in any other way. + +wireplumber.profiles = { + policy = { + inherits = [ mixin.systemwide-session, mixin.stateless ] + } + + audio = { + inherits = [ mixin.systemwide-session, mixin.stateless ] + support.settings = disabled + } + + bluetooth = { + inherits = [ mixin.systemwide-session, mixin.stateless ] + support.settings = disabled + } + + video-capture = { + inherits = [ mixin.systemwide-session, mixin.stateless ] + support.settings = disabled + } +} diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-AGL-alsa.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-AGL-alsa.conf new file mode 100644 index 000000000..fc03ceb38 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-AGL-alsa.conf @@ -0,0 +1,101 @@ +# Default AGL WirePlumber ALSA monitor configuration + +monitor.alsa.rules = [ + # + # Bump priority of well-known output devices + # Higher priority means it gets selected as the default if it's present + # + + # USB output + { + matches = [ + { + node.name = "~alsa_output.*" + api.alsa.card.driver = "USB-Audio" + } + ] + actions = { + update-props = { + priority.driver = 1300 + priority.session = 1300 + } + } + } + + # USB input + { + matches = [ + { + node.name = "~alsa_input.*" + api.alsa.card.driver = "USB-Audio" + } + ] + actions = { + update-props = { + priority.driver = 2300 + priority.session = 2300 + } + } + } + + # well-known internal output devices + { + matches = [ + # ak4613 + { + node.name = "~alsa_output.*" + api.alsa.card.id = "ak4613" + api.alsa.pcm.device = "0" + } + # imx8mq + { + node.name = "~alsa_output.*" + api.alsa.card.id = "wm8524audio" + } + # rcarsound + { + node.name = "~alsa_output.*" + api.alsa.card.id = "rcarsound" + api.alsa.pcm.device = "0" + } + # rpi3 + { + node.name = "~alsa_output.*" + api.alsa.pcm.name = "bcm2835 ALSA" + } + ] + actions = { + update-props = { + priority.driver = 1100 + priority.session = 1100 + } + } + } + + # well-known internal input devices + { + matches = [ + # ak4613 + { + node.name = "~alsa_input.*" + api.alsa.card.id = "ak4613" + } + # imx8mq + { + node.name = "~alsa_input.*" + api.alsa.card.id = "wm8524audio" + } + # rcarsound + { + node.name = "~alsa_input.*" + api.alsa.card.id = "rcarsound" + } + ] + actions = { + update-props = { + priority.driver = 2100 + priority.session = 2100 + } + } + } +] diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-AGL-bluetooth.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-AGL-bluetooth.conf new file mode 100644 index 000000000..db5b20dc2 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-AGL-bluetooth.conf @@ -0,0 +1,41 @@ +# Default AGL WirePlumber Bluetooth monitor configuration + +monitor.bluez.properties = { + ## HFP/HSP backend (default: native). + ## Available values: any, none, hsphfpd, ofono, native + bluez5.hfphsp-backend = "ofono" +} + +monitor.bluez.rules = [ + { + matches = [ + { + ## This matches all bluetooth devices. + device.name = "~bluez_card.*" + } + ] + actions = { + update-props = { + ## Auto-connect as headset/sink on start up or when only partial + ## profiles have connected. + bluez5.auto-connect = [ hfp_hf hsp_hs a2dp_sink ] + } + } + } + + # Make output a2dp stream nodes go through the Multimedia sink + # We cannot match on "media.class" here because this property + # is not known before the node is created + { + matches = [ + { + api.bluez5.profile = "a2dp-source" + } + ] + actions = { + update-props = { + media.role = "Multimedia" + } + } + } +] diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/50-AGL-pw-ic-ipc.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/50-AGL-pw-ic-ipc.conf new file mode 100644 index 000000000..93687501c --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/50-AGL-pw-ic-ipc.conf @@ -0,0 +1,15 @@ +wireplumber.profiles = { + # Run on the "audio" instance, which runs the ALSA monitor on the host + audio = { + agl.script.pipewire-ic-ipc.alsa-suspend = required + } +} + +wireplumber.components = [ + # Mutes ALSA sinks when requested by pipewire-ic-ipc + { + name = alsa-suspend.lua, type = script/lua + provides = agl.script.pipewire-ic-ipc.alsa-suspend + requires = [ api.mixer ] + } +] diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.conf deleted file mode 100644 index 9077e3f45..000000000 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.conf +++ /dev/null @@ -1,74 +0,0 @@ -# WirePlumber daemon context configuration # - -context.properties = { - ## Properties to configure the PipeWire context and some modules - - application.name = "WirePlumber Bluetooth" - log.level = 2 - wireplumber.script-engine = lua-scripting - wireplumber.export-core = true - - #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. - # - api.bluez5.* = bluez5/libspa-bluez5 - 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 = bluetooth.lua, type = config/lua } -] diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.lua.d/30-bluez-monitor.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.lua.d/30-bluez-monitor.lua deleted file mode 100644 index 530f4cc62..000000000 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.lua.d/30-bluez-monitor.lua +++ /dev/null @@ -1,110 +0,0 @@ --- Bluez monitor config file -- - -bluez_monitor = {} - -bluez_monitor.properties = { - -- These features do not work on all headsets, so they are enabled - -- by default based on the hardware database. They can also be - -- forced on/off for all devices by the following options: - - --["bluez5.enable-sbc-xq"] = true, - --["bluez5.enable-msbc"] = true, - --["bluez5.enable-hw-volume"] = true, - - -- See bluez-hardware.conf for the hardware database. - - -- 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 sbc_xq aac ldac aptx aptx_hd aptx_ll aptx_ll_duplex faststream faststream_duplex ]", - - -- HFP/HSP backend (default: native). - -- Available values: any, none, hsphfpd, ofono, native - ["bluez5.hfphsp-backend"] = "ofono", - - -- 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 ]", - - -- 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", - }, - }, -} - -load_monitor("bluez", { - properties = bluez_monitor.properties, - rules = bluez_monitor.rules, -}) diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/30-alsa-monitor.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/30-alsa-monitor.lua deleted file mode 100644 index d07f7ab85..000000000 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/30-alsa-monitor.lua +++ /dev/null @@ -1,151 +0,0 @@ --- ALSA monitor config file -- - -alsa_monitor = {} - -alsa_monitor.properties = { - ["alsa.jack-device"] = false, - ["alsa.reserve"] = false, -} - -alsa_monitor.rules = { - -- enable ACP (PulseAudio-like profiles) - { - matches = { - { - { "device.name", "matches", "alsa_card.*" }, - }, - }, - apply_properties = { - ["api.alsa.use-acp"] = true, - }, - }, - - -- - -- 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" }, - }, - { - -- 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" }, - }, - { - -- 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/host.lua.d/30-v4l2-monitor.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/30-v4l2-monitor.lua deleted file mode 100644 index a4eb58ac8..000000000 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/30-v4l2-monitor.lua +++ /dev/null @@ -1,48 +0,0 @@ --- V4L2 monitor config file -- - -v4l2_monitor = {} -v4l2_monitor.properties = {} - -v4l2_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", "v4l2_device.*" }, - }, - }, - -- Apply properties on the matched object. - apply_properties = { - -- ["device.nick"] = "My Device", - }, - }, - { - matches = { - { - -- Matches all sources. - { "node.name", "matches", "v4l2_input.*" }, - }, - { - -- Matches all sinks. - { "node.name", "matches", "v4l2_output.*" }, - }, - }, - apply_properties = { - --["node.nick"] = "My Node", - --["priority.driver"] = 100, - --["priority.session"] = 100, - --["node.pause-on-idle"] = false, - }, - }, -} - -function v4l2_monitor.enable() - load_monitor("v4l2", { - properties = v4l2_monitor.properties, - rules = v4l2_monitor.rules, - }) -end diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/40-device-defaults.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/40-device-defaults.lua deleted file mode 100644 index e0d332422..000000000 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/40-device-defaults.lua +++ /dev/null @@ -1,26 +0,0 @@ -device_defaults = {} - -device_defaults.properties = { - -- store preferences to the file system and restore them at startup; - -- when set to false, default nodes and routes are selected based on - -- their priorities and any runtime changes do not persist after restart - ["use-persistent-storage"] = false, -} - -function device_defaults.enable() - -- Selects appropriate default nodes and enables saving and restoring them - load_module("default-nodes", device_defaults.properties) - - -- Selects appropriate default routes ("ports" in pulseaudio terminology) - -- and enables saving and restoring them together with - -- their properties (per-route/port volume levels, channel maps, etc) - load_script("policy-device-routes.lua", device_defaults.properties) - - if device_defaults.properties["use-persistent-storage"] then - -- Enables functionality to save and restore default device profiles - load_module("default-profile") - - -- Save and restore stream-specific properties - load_script("restore-stream.lua") - end -end diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/90-enable-all.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/90-enable-all.lua deleted file mode 100644 index ecb7da476..000000000 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/90-enable-all.lua +++ /dev/null @@ -1,20 +0,0 @@ --- Provide the "default" pw_metadata, which stores --- dynamic properties of pipewire objects in RAM -load_module("metadata") - --- Load devices -alsa_monitor.enable() -v4l2_monitor.enable() - --- Track/store/restore user choices about devices -device_defaults.enable() - --- Automatically suspends idle nodes after 3 seconds -load_script("suspend-node.lua") - --- Automatically sets device profiles to 'On' -load_script("policy-device-profile.lua") - --- Mute ALSA sinks when requested by pipewire-ic-ipc -load_module("mixer-api") -load_script("alsa-suspend.lua") diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf deleted file mode 100644 index 46ad11302..000000000 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf +++ /dev/null @@ -1,115 +0,0 @@ -# WirePlumber daemon context configuration # - -context.properties = { - ## Properties to configure the PipeWire context and some modules - - # 1=error/critical/warning, 2=message, 3=info, 4=debug, 5=trace - log.level = 2 - - wireplumber.script-engine = lua-scripting -} - -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. - # - 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 = <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 } - - { name = libpipewire-module-filter-chain - args = { - 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" - media.class = Audio/Sink - # select the endpoint to which the node is attached - target.endpoint = "endpoint.multimedia" - node.passive = true - } - playback.props = { - node.name = "eq-output-stream" - node.passive = true - } - } - } -] - -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(s) - # Other components are loaded from there - { name = host.lua, type = config/lua } -] diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl_git.bb b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl_git.bb index 22ffe5bf3..db2c67dcf 100644 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl_git.bb +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl_git.bb @@ -6,12 +6,12 @@ SECTION = "multimedia" LICENSE = "MIT" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" SRC_URI = "\ - file://bluetooth.lua.d/ \ - file://host.lua.d/ \ - file://00-functions.lua \ + file://20-AGL-log.conf \ + file://20-AGL-profiles.conf \ + file://30-AGL-alsa.conf \ + file://30-AGL-bluetooth.conf \ + file://50-AGL-pw-ic-ipc.conf \ file://alsa-suspend.lua \ - file://bluetooth.conf \ - file://wireplumber.conf \ file://wireplumber-bluetooth.conf \ " PACKAGE_ARCH = "${MACHINE_ARCH}" @@ -19,27 +19,20 @@ PACKAGE_ARCH = "${MACHINE_ARCH}" do_configure[noexec] = "1" do_compile[noexec] = "1" do_install:append() { - config_dir="${D}${sysconfdir}/wireplumber/" + config_dir="${D}${sysconfdir}/wireplumber/wireplumber.conf.d/" scripts_dir="${D}${datadir}/wireplumber/scripts/" dbus_config_dir="${D}${sysconfdir}/dbus-1/system.d/" systemd_dir="${D}${sysconfdir}/systemd/system/pipewire.service.wants/" + # install the configuration fragments install -d ${config_dir} - install -m 0644 ${WORKDIR}/00-functions.lua ${config_dir} + install -m 0644 ${WORKDIR}/20-AGL-log.conf ${config_dir} + install -m 0644 ${WORKDIR}/20-AGL-profiles.conf ${config_dir} + install -m 0644 ${WORKDIR}/30-AGL-alsa.conf ${config_dir} + install -m 0644 ${WORKDIR}/30-AGL-bluetooth.conf ${config_dir} + install -m 0644 ${WORKDIR}/50-AGL-pw-ic-ipc.conf ${config_dir} - # config of the main (host) instance - install -d ${config_dir}/host.lua.d/ - ln -s ../00-functions.lua ${config_dir}/host.lua.d/00-functions.lua - install -m 0644 ${WORKDIR}/host.lua.d/*.lua ${config_dir}/host.lua.d/ - install -m 0644 ${WORKDIR}/wireplumber.conf ${config_dir} - - # config of the bluetooth instance - install -d ${config_dir}/bluetooth.lua.d/ - ln -s ../00-functions.lua ${config_dir}/bluetooth.lua.d/00-functions.lua - install -m 0644 ${WORKDIR}/bluetooth.lua.d/*.lua ${config_dir}/bluetooth.lua.d/ - install -m 0644 ${WORKDIR}/bluetooth.conf ${config_dir} - - # install the alsa-suspend script, loaded by the main instance + # install the alsa-suspend script, loaded by the audio instance install -d ${scripts_dir} install -m 0644 ${WORKDIR}/alsa-suspend.lua ${scripts_dir} @@ -49,6 +42,8 @@ do_install:append() { # enable additional systemd services install -d ${systemd_dir} + ln -s ${systemd_system_unitdir}/wireplumber@.service ${systemd_dir}/wireplumber@audio.service + ln -s ${systemd_system_unitdir}/wireplumber@.service ${systemd_dir}/wireplumber@video-capture.service ln -s ${systemd_system_unitdir}/wireplumber@.service ${systemd_dir}/wireplumber@bluetooth.service } 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) diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl_git.bb b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl_git.bb index 1a031160e..7973a0a33 100644 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl_git.bb +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl_git.bb @@ -6,26 +6,20 @@ SECTION = "multimedia" LICENSE = "MIT" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" SRC_URI = "\ - file://policy.lua.d \ - file://00-functions.lua \ - file://policy.conf \ + file://50-AGL-equalizer.conf \ + file://50-AGL-media-role-nodes.conf \ " PACKAGE_ARCH = "${MACHINE_ARCH}" do_configure[noexec] = "1" do_compile[noexec] = "1" do_install:append() { - config_dir="${D}${sysconfdir}/wireplumber/" + config_dir="${D}${sysconfdir}/wireplumber/wireplumber.conf.d/" systemd_dir="${D}${sysconfdir}/systemd/system/pipewire.service.wants" install -d ${config_dir} - install -m 0644 ${WORKDIR}/00-functions.lua ${config_dir} - - # config of the policy instance - install -d ${config_dir}/policy.lua.d/ - ln -s ../00-functions.lua ${config_dir}/policy.lua.d/00-functions.lua - install -m 0644 ${WORKDIR}/policy.lua.d/*.lua ${config_dir}/policy.lua.d/ - install -m 0644 ${WORKDIR}/policy.conf ${config_dir} + install -m 0644 ${WORKDIR}/50-AGL-equalizer.conf ${config_dir} + install -m 0644 ${WORKDIR}/50-AGL-media-role-nodes.conf ${config_dir} # enable additional systemd services install -d ${systemd_dir} diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_%.bbappend b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_%.bbappend new file mode 100644 index 000000000..16d3817cd --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_%.bbappend @@ -0,0 +1,9 @@ +do_install:append() { + systemd_dir="${D}${sysconfdir}/systemd/system/" + + # mask the main service, to enable split-instance configuration + # accomodated by the services installed in wireplumber-config-agl + # and wireplumber-policy-config-agl + install -d ${systemd_dir} + ln -s /dev/null ${systemd_dir}/wireplumber.service +} diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_0.5.6.bb b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_0.5.6.bb new file mode 100644 index 000000000..d7fecd18b --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_0.5.6.bb @@ -0,0 +1,138 @@ +SUMMARY = "Session / policy manager implementation for PipeWire" +HOMEPAGE = "https://gitlab.freedesktop.org/pipewire/wireplumber" +BUGTRACKER = "https://gitlab.freedesktop.org/pipewire/wireplumber/issues" +SECTION = "multimedia" + +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=17d1fe479cdec331eecbc65d26bc7e77" + +DEPENDS = "glib-2.0 glib-2.0-native lua pipewire \ + ${@bb.utils.contains("DISTRO_FEATURES", "gobject-introspection-data", "python3-native python3-lxml-native doxygen-native", "", d)} \ +" + +SRCREV = "141b2d5d3f793e20f94421c554d8d9c51143ce0d" +SRC_URI = " \ + git://gitlab.freedesktop.org/pipewire/wireplumber.git;branch=master;protocol=https \ +" + +S = "${WORKDIR}/git" + +inherit meson pkgconfig gobject-introspection systemd + +GIR_MESON_ENABLE_FLAG = 'enabled' +GIR_MESON_DISABLE_FLAG = 'disabled' + +# Enable system-lua to let wireplumber use OE's lua. +# Documentation needs python-sphinx, which is not in oe-core or meta-python2 for now. +# elogind is not (yet) available in OE, so disable support. +EXTRA_OEMESON += " \ + -Ddoc=disabled \ + -Dsystem-lua=true \ + -Delogind=disabled \ + -Dsystemd-system-unit-dir=${systemd_system_unitdir} \ + -Dsystemd-user-unit-dir=${systemd_user_unitdir} \ + -Dtests=false \ +" + +PACKAGECONFIG ??= " dbus \ + ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd systemd-system-service systemd-user-service', '', d)} \ +" + +PACKAGECONFIG[systemd] = "-Dsystemd=enabled,-Dsystemd=disabled,systemd" +PACKAGECONFIG[systemd-system-service] = "-Dsystemd-system-service=true,-Dsystemd-system-service=false,systemd" +# "systemd-user-service" packageconfig will only install service +# files to rootfs but not enable them as systemd.bbclass +# currently lacks the feature of enabling user services. +PACKAGECONFIG[systemd-user-service] = "-Dsystemd-user-service=true,-Dsystemd-user-service=false,systemd" +PACKAGECONFIG[dbus] = "" + +PACKAGESPLITFUNCS:prepend = " split_dynamic_packages " +PACKAGESPLITFUNCS:append = " set_dynamic_metapkg_rdepends " + +WP_MODULE_SUBDIR = "wireplumber-0.5" + +python split_dynamic_packages () { + # Create packages for each WirePlumber module. + wp_module_libdir = d.expand('${libdir}/${WP_MODULE_SUBDIR}') + do_split_packages(d, wp_module_libdir, r'^libwireplumber-module-(.*)\.so$', d.expand('${PN}-modules-%s'), 'WirePlumber %s module', extra_depends='', recursive=False) +} + +python set_dynamic_metapkg_rdepends () { + import os + import oe.utils + + # Go through all generated WirePlumber module packages + # (excluding the main package and the -meta package itself) + # and add them to the -meta package as RDEPENDS. + + base_pn = d.getVar('PN') + + wp_module_pn = base_pn + '-modules' + wp_module_metapkg = wp_module_pn + '-meta' + + d.setVar('ALLOW_EMPTY:' + wp_module_metapkg, "1") + d.setVar('FILES:' + wp_module_metapkg, "") + + blacklist = [ wp_module_pn, wp_module_metapkg ] + wp_module_metapkg_rdepends = [] + pkgdest = d.getVar('PKGDEST') + + for pkg in oe.utils.packages_filter_out_system(d): + if pkg in blacklist: + continue + + is_wp_module_pkg = pkg.startswith(wp_module_pn) + if not is_wp_module_pkg: + continue + + if pkg in wp_module_metapkg_rdepends: + continue + + # See if the package is empty by looking at the contents of its + # PKGDEST subdirectory. If this subdirectory is empty, then then + # package is empty as well. Empty packages do not get added to + # the meta package's RDEPENDS. + pkgdir = os.path.join(pkgdest, pkg) + if os.path.exists(pkgdir): + dir_contents = os.listdir(pkgdir) or [] + else: + dir_contents = [] + is_empty = len(dir_contents) == 0 + if not is_empty: + if is_wp_module_pkg: + wp_module_metapkg_rdepends.append(pkg) + + d.setVar('RDEPENDS:' + wp_module_metapkg, ' '.join(wp_module_metapkg_rdepends)) + d.setVar('DESCRIPTION:' + wp_module_metapkg, wp_module_pn + ' meta package') +} + +PACKAGES =+ "\ + libwireplumber \ + ${PN}-default-config \ + ${PN}-scripts \ + ${PN}-modules \ + ${PN}-modules-meta \ +" + +PACKAGES_DYNAMIC = "^${PN}-modules.*" + +CONFFILES:${PN} += " \ + ${datadir}/wireplumber/wireplumber.conf \ + ${datadir}/wireplumber/wireplumber.conf.d/*.conf \ +" +# Add pipewire to RRECOMMENDS, since WirePlumber expects a PipeWire daemon to +# be present. While in theory any application that uses libpipewire can configure +# itself to become a daemon, in practice, the PipeWire daemon is used. +RRECOMMENDS:${PN} += "pipewire ${PN}-scripts ${PN}-modules-meta" + +FILES:${PN} += "${systemd_user_unitdir} ${systemd_system_unitdir} ${datadir}/zsh" + +FILES:libwireplumber = " \ + ${libdir}/libwireplumber-*.so.* \ +" + +FILES:${PN}-scripts += "${datadir}/wireplumber/scripts/*" + +# Dynamic packages (see set_dynamic_metapkg_rdepends). +FILES:${PN}-modules = "" +RRECOMMENDS:${PN}-modules += "${PN}-modules-meta" diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb deleted file mode 100644 index a04f115c3..000000000 --- a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb +++ /dev/null @@ -1,85 +0,0 @@ -SUMMARY = "Session / Policy Manager for PipeWire" -HOMEPAGE = "https://gitlab.freedesktop.org/pipewire/wireplumber" -BUGTRACKER = "https://gitlab.freedesktop.org/pipewire/wireplumber/issues" -AUTHOR = "George Kiagiadakis <george.kiagiadakis@collabora.com>" -SECTION = "multimedia" - -LICENSE = "MIT" -LIC_FILES_CHKSUM = "file://LICENSE;beginline=3;md5=e8ad01a5182f2c1b3a2640e9ea268264" - -inherit meson pkgconfig systemd - -DEPENDS = "glib-2.0 glib-2.0-native pipewire lua" - -SRC_URI = "\ - git://gitlab.freedesktop.org/pipewire/wireplumber.git;protocol=https;branch=master \ -" -# v0.4.17 -SRCREV = "d3eb77b292655cef333a8f4cab4e861415bc37c2" - -# patches to be able to compile with lower version of meson that is available in AGL. -SRC_URI += "\ -" - -PV = "0.4.17" -S = "${WORKDIR}/git" - -WPAPI="0.4" - -# use shared lua from the system instead of the static bundled one -EXTRA_OEMESON += "-Dsystem-lua=true" - -# introspection in practice is only used for generating API docs -# API docs are available on the website and we don't need to build them -# (plus they depend on hotdoc which is not available here) -EXTRA_OEMESON += "-Dintrospection=disabled -Ddoc=disabled" - -PACKAGECONFIG = "\ - ${@bb.utils.filter('DISTRO_FEATURES', 'systemd', d)} \ -" - -PACKAGECONFIG[systemd] = "-Dsystemd=enabled -Dsystemd-system-service=true -Dsystemd-user-service=false,-Dsystemd=disabled -Dsystemd-system-service=false -Dsystemd-user-service=false,systemd" - -do_configure:prepend() { - # relax meson version requirement - # we only need 0.54 when building with -Dsystem-lua=false - sed "s/meson_version : '>= 0.56.0'/meson_version : '>= 0.53.2'/" ${S}/meson.build > ${S}/tmp.build - mv -f ${S}/tmp.build ${S}/meson.build -} - -PACKAGES =+ "\ - lib${PN}-${WPAPI} \ - ${PN}-config \ -" - -SYSTEMD_SERVICE:${PN} = "wireplumber.service" -FILES:${PN} = "\ - ${bindir}/wireplumber \ - ${bindir}/wpctl \ - ${bindir}/wpexec \ - ${libdir}/wireplumber-${WPAPI}/* \ - ${datadir}/wireplumber/scripts/* \ - ${datadir}/zsh/* \ - ${systemd_system_unitdir}/* \ -" - -FILES:lib${PN}-${WPAPI} = "\ - ${libdir}/libwireplumber-${WPAPI}.so.* \ -" - -FILES:${PN}-config += "\ - ${sysconfdir}/wireplumber/* \ - ${datadir}/wireplumber/*conf \ - ${datadir}/wireplumber/common/* \ - ${datadir}/wireplumber/main.lua.d/* \ - ${datadir}/wireplumber/bluetooth.lua.d/* \ - ${datadir}/wireplumber/policy.lua.d/* \ -" -do_install:append() { - rm -rf ${D}${sysconfdir}/wireplumber/ - rm -f ${D}${datadir}/wireplumber/*conf - rm -rf ${D}${datadir}/wireplumber/common - rm -rf ${D}${datadir}/wireplumber/main.lua.d - rm -rf ${D}${datadir}/wireplumber/bluetooth.lua.d - rm -rf ${D}${datadir}/wireplumber/policy.lua.d -} |