meta-pipewire: update wireplumber to 0.5.6 43/30243/4
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>
Wed, 4 Sep 2024 13:11:54 +0000 (16:11 +0300)
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>
Fri, 6 Sep 2024 14:11:58 +0000 (14:11 +0000)
- 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>
23 files changed:
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-functions.lua [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/20-AGL-log.conf [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/20-AGL-profiles.conf [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-AGL-alsa.conf [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/30-AGL-bluetooth.conf [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/50-AGL-pw-ic-ipc.conf [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.conf [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.lua.d/30-bluez-monitor.lua [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/30-alsa-monitor.lua [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/30-v4l2-monitor.lua [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/40-device-defaults.lua [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/90-enable-all.lua [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl_git.bb
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/00-functions.lua [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/50-AGL-equalizer.conf [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/50-AGL-media-role-nodes.conf [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.conf [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.lua.d/10-default-policy.lua [deleted file]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl_git.bb
meta-pipewire/recipes-multimedia/wireplumber/wireplumber_%.bbappend [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber_0.5.6.bb [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb [deleted file]

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 (file)
index 7e1794d..0000000
+++ /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 (file)
index 0000000..7dc8938
--- /dev/null
@@ -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 (file)
index 0000000..d029887
--- /dev/null
@@ -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 (file)
index 0000000..fc03ceb
--- /dev/null
@@ -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 (file)
index 0000000..db5b20d
--- /dev/null
@@ -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 (file)
index 0000000..9368750
--- /dev/null
@@ -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 (file)
index 9077e3f..0000000
+++ /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 (file)
index 530f4cc..0000000
+++ /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 (file)
index d07f7ab..0000000
+++ /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 (file)
index a4eb58a..0000000
+++ /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 (file)
index e0d3324..0000000
+++ /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 (file)
index ecb7da4..0000000
+++ /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 (file)
index 46ad113..0000000
+++ /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 }
-]
index 22ffe5b..db2c67d 100644 (file)
@@ -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 (file)
index 7e1794d..0000000
+++ /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 (file)
index 0000000..061eae9
--- /dev/null
@@ -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 (file)
index 0000000..4e4f332
--- /dev/null
@@ -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 (file)
index 42f7148..0000000
+++ /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 (file)
index 6814fce..0000000
+++ /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)
index 1a03116..7973a0a 100644 (file)
@@ -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 (file)
index 0000000..16d3817
--- /dev/null
@@ -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 (file)
index 0000000..d7fecd1
--- /dev/null
@@ -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 (file)
index a04f115..0000000
+++ /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
-}