diff options
Diffstat (limited to 'meta-pipewire/recipes-multimedia')
19 files changed, 1442 insertions, 0 deletions
diff --git a/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-systemd-Do-not-override-rootprefix.patch b/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-systemd-Do-not-override-rootprefix.patch new file mode 100644 index 000000000..45d09e6b0 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-systemd-Do-not-override-rootprefix.patch @@ -0,0 +1,35 @@ +From 2501972518a67b1710998452d164cd077a4370f1 Mon Sep 17 00:00:00 2001 +From: Scott Murray <scott.murray@konsulko.com> +Date: Thu, 17 Mar 2022 10:44:00 -0400 +Subject: [PATCH] systemd: Do not override rootprefix + +Do not override rootprefix with the value of prefix when querying +systemdsystemunitdir from the systemd pkgconfig, as doing so forces +the assumption that the system is running with usrmerge, which may +not be the case. Instead, rely on the systemd.pc correctly +representing the desired install locations. + +Reworked version of change in: + +https://git.automotivelinux.org/AGL/meta-agl/tree/meta-pipewire/recipes-multimedia/pipewire/pipewire/0012-Miscellanous-changes-to-account-for-lower-version-of.patch + +Upstream-Status: Pending + +Signed-off-by: Scott Murray <scott.murray@konsulko.com> +--- + src/daemon/systemd/system/meson.build | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/daemon/systemd/system/meson.build b/src/daemon/systemd/system/meson.build +index 84ca0b068..6956f2be3 100644 +--- a/src/daemon/systemd/system/meson.build ++++ b/src/daemon/systemd/system/meson.build +@@ -1,4 +1,4 @@ +-systemd_system_services_dir = systemd.get_variable('systemdsystemunitdir', pkgconfig_define : [ 'rootprefix', prefix]) ++systemd_system_services_dir = systemd.get_variable('systemdsystemunitdir') + if get_option('systemd-system-unit-dir') != '' + systemd_system_services_dir = get_option('systemd-system-unit-dir') + endif +-- +2.35.1 + diff --git a/meta-pipewire/recipes-multimedia/pipewire/pipewire_1.0.0.bb b/meta-pipewire/recipes-multimedia/pipewire/pipewire_1.0.0.bb new file mode 100644 index 000000000..6fa851caa --- /dev/null +++ b/meta-pipewire/recipes-multimedia/pipewire/pipewire_1.0.0.bb @@ -0,0 +1,329 @@ +# This recipe was written by Carlos Rafael Giani <crg7475@mailbox.org> +# for meta-oe +# +# The intention is to keep this synced with meta-oe and remove it when we +# can depend on meta-oe to provide this recipe for us +# +# AGL-specific overrides and configuration should go in the .bbappend file +# +SUMMARY = "Multimedia processing server for Linux" +DESCRIPTION = "Linux server for handling and routing audio and video streams between applications and multimedia I/O devices" +HOMEPAGE = "https://pipewire.org/" +BUGTRACKER = "https://gitlab.freedesktop.org/pipewire/pipewire/issues" +LICENSE = "MIT & GPL-2.0-only & LGPL-2.1-or-later" + +LIC_FILES_CHKSUM = " \ + file://LICENSE;md5=2158739e172e58dc9ab1bdd2d6ec9c72 \ + file://COPYING;md5=97be96ca4fab23e9657ffa590b931c1a \ +" +SECTION = "multimedia" + +DEPENDS = "dbus" + +# v1.0.0(El Presidente) +SRCREV = "4debdcd40b055b3eaa83a8f4443aa990ea566bfe" +SRC_URI = "git://gitlab.freedesktop.org/pipewire/pipewire.git;branch=master;protocol=https" + +S = "${WORKDIR}/git" + +inherit meson pkgconfig systemd manpages gettext useradd + +USERADD_PACKAGES = "${PN}" + +GROUPADD_PARAM:${PN} = "--system pipewire" + +USERADD_PARAM:${PN} = "--system --home / --no-create-home \ + --comment 'PipeWire multimedia daemon' \ + --gid pipewire --groups audio,video \ + pipewire" + +# For "EVL", look up https://evlproject.org/ . It involves +# a specially prepared kernel, and is currently unavailable +# in Yocto. +# +# FFmpeg and Vulkan aren't really supported - at the current +# stage (version 0.3.22), these are just experiments, not +# actual features. +# +# libcamera support currently does not build successfully. +# +# systemd user service files are disabled because per-user +# PipeWire instances aren't really something that makes +# much sense in an embedded environment. A system-wide +# instance does. +# +# manpage generation requires xmltoman, which is not available. +# +# Dont build any session managers along with pipewire +# wireplumber is the session manger used in AGL and it will +# be build in a different recipe +# +EXTRA_OEMESON += " \ + -Daudiotestsrc=enabled \ + -Devl=disabled \ + -Dsystemd-user-service=disabled \ + -Dtests=disabled \ + -Dudevrulesdir=${nonarch_base_libdir}/udev/rules.d/ \ + -Dvideotestsrc=enabled \ + -Dffmpeg=disabled \ + -Dvulkan=disabled \ + -Dlibcamera=disabled \ + -Dman=disabled \ + -Dsession-managers=[] \ +" + +PACKAGECONFIG ??= "\ + ${@bb.utils.contains('DISTRO_FEATURES', 'bluetooth', 'bluez', '', d)} \ + ${@bb.utils.filter('DISTRO_FEATURES', 'alsa systemd', d)} \ + gstreamer jack v4l2 \ +" + +# "jack" and "pipewire-jack" packageconfigs cannot be both enabled, +# since "jack" imports libjack, and "pipewire-jack" generates +# libjack.so* files, thus colliding with the libpack package. This +# is why these two are marked in their respective packageconfigs +# as being in conflict. + +PACKAGECONFIG[alsa] = "-Dalsa=enabled,-Dalsa=disabled,alsa-lib udev,,pipewire-alsa-card-profile" +PACKAGECONFIG[bluez] = "-Dbluez5=enabled,-Dbluez5=disabled,bluez5 sbc" +PACKAGECONFIG[docs] = "-Ddocs=enabled,-Ddocs=disabled,doxygen-native" +PACKAGECONFIG[gstreamer] = "-Dgstreamer=enabled,-Dgstreamer=disabled,glib-2.0 gstreamer1.0 gstreamer1.0-plugins-base" +PACKAGECONFIG[jack] = "-Djack=enabled,-Djack=disabled,jack,,,pipewire-jack" +PACKAGECONFIG[sdl2] = "-Dsdl2=enabled,-Dsdl2=disabled,virtual/libsdl2" +PACKAGECONFIG[sndfile] = "-Dsndfile=enabled,-Dsndfile=disabled,libsndfile1" +PACKAGECONFIG[systemd] = "-Dsystemd=enabled -Dsystemd-system-service=enabled ,-Dsystemd=disabled -Dsystemd-system-service=disabled,systemd" +PACKAGECONFIG[v4l2] = "-Dv4l2=enabled,-Dv4l2=disabled,udev" +PACKAGECONFIG[pipewire-alsa] = "-Dpipewire-alsa=enabled,-Dpipewire-alsa=disabled,alsa-lib" +PACKAGECONFIG[pipewire-jack] = "-Dpipewire-jack=enabled -Dlibjack-path=${libdir}/${PW_MODULE_SUBDIR}/jack,-Dpipewire-jack=disabled,jack,,,jack" +PACKAGECONFIG[pipewire-v4l2] = "-Dpipewire-v4l2=enabled -Dpipewire-v4l2=${libdir}/${PW_MODULE_SUBDIR}/v4l2,-Dpipewire-v4l2=disabled,v4l2" + +PACKAGESPLITFUNCS:prepend = " split_dynamic_packages " +PACKAGESPLITFUNCS:append = " set_dynamic_metapkg_rdepends " +PACKAGESPLITFUNCS:append = " fixup_dynamic_pkg_licenses " + +SPA_SUBDIR = "spa-0.2" +PW_MODULE_SUBDIR = "pipewire-0.3" + +remove_unused_installed_files() { + # jack.conf is used by pipewire-jack (not the JACK SPA plugin). + # Remove it if pipewire-jack is not built to avoid creating the + # pipewire-jack package. + if ${@bb.utils.contains('PACKAGECONFIG', 'pipewire-jack', 'false', 'true', d)}; then + rm -f "${D}${datadir}/pipewire/jack.conf" + fi +} + +do_install[postfuncs] += "remove_unused_installed_files" + +python fixup_dynamic_pkg_licenses () { + #dynamic packages inherit currently whatever is specified in LICENSE (thus multiple) + packages = (d.getVar('PACKAGES') or "").split() + + for pkg in packages: + # we manually assign the LICENSES here to cover all packages (even dynamically created ones) + d.setVar("LICENSE:" + pkg ,"MIT") + + # next handle special cases + # ==> LICENSE:${PN}-spa-plugins-alsa = "LGPL-2.1-or-later" + if "pipewire-spa-plugins-alsa" in pkg: + d.setVar("LICENSE:pipewire-spa-plugins-alsa", "LGPL-2.1-or-later") + # ==> LICENSE:${PN}-alsa-card-profile = "LGPL-2.1-or-later" + if "pipewire-alsa-card-profile" in pkg: + d.setVar("LICENSE:pipewire-alsa-card-profile", "LGPL-2.1-or-later") + # ==> LICENSE:${PN}-jack = "GPL-2.0-only" + if "pipewire-jack" in pkg: + d.setVar("LICENSE:pipewire-jack", "GPL-2.0-only") +} + +python split_dynamic_packages () { + # Create packages for each SPA plugin. These plugins are located + # in individual subdirectories, so a recursive search is needed. + spa_libdir = d.expand('${libdir}/${SPA_SUBDIR}') + do_split_packages(d, spa_libdir, r'^libspa-(.*)\.so$', d.expand('${PN}-spa-plugins-%s'), 'PipeWire SPA plugin for %s', extra_depends='', recursive=True) + + # Create packages for each PipeWire module. + pw_module_libdir = d.expand('${libdir}/${PW_MODULE_SUBDIR}') + do_split_packages(d, pw_module_libdir, r'^libpipewire-module-(.*)\.so$', d.expand('${PN}-modules-%s'), 'PipeWire %s module', extra_depends='', recursive=False) +} + +python set_dynamic_metapkg_rdepends () { + import os + import oe.utils + + # Go through all generated SPA plugin and PipeWire 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') + + spa_pn = base_pn + '-spa-plugins' + spa_metapkg = spa_pn + '-meta' + + pw_module_pn = base_pn + '-modules' + pw_module_metapkg = pw_module_pn + '-meta' + + d.setVar('ALLOW_EMPTY:' + spa_metapkg, "1") + d.setVar('FILES:' + spa_metapkg, "") + + d.setVar('ALLOW_EMPTY:' + pw_module_metapkg, "1") + d.setVar('FILES:' + pw_module_metapkg, "") + + blacklist = [ spa_pn, spa_metapkg, pw_module_pn, pw_module_metapkg ] + spa_metapkg_rdepends = [] + pw_module_metapkg_rdepends = [] + pkgdest = d.getVar('PKGDEST') + + for pkg in oe.utils.packages_filter_out_system(d): + if pkg in blacklist: + continue + + is_spa_pkg = pkg.startswith(spa_pn) + is_pw_module_pkg = pkg.startswith(pw_module_pn) + if not is_spa_pkg and not is_pw_module_pkg: + continue + + if pkg in spa_metapkg_rdepends or pkg in pw_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_spa_pkg: + spa_metapkg_rdepends.append(pkg) + if is_pw_module_pkg: + pw_module_metapkg_rdepends.append(pkg) + + d.setVar('RDEPENDS:' + spa_metapkg, ' '.join(spa_metapkg_rdepends)) + d.setVar('DESCRIPTION:' + spa_metapkg, spa_pn + ' meta package') + + d.setVar('RDEPENDS:' + pw_module_metapkg, ' '.join(pw_module_metapkg_rdepends)) + d.setVar('DESCRIPTION:' + pw_module_metapkg, pw_module_pn + ' meta package') +} + +PACKAGES =+ "\ + libpipewire \ + ${PN}-tools \ + ${PN}-pulse \ + ${PN}-alsa \ + ${PN}-jack \ + ${PN}-v4l2 \ + ${PN}-spa-plugins \ + ${PN}-spa-plugins-meta \ + ${PN}-spa-tools \ + ${PN}-modules \ + ${PN}-modules-meta \ + ${PN}-alsa-card-profile \ + gstreamer1.0-pipewire \ +" + +PACKAGES_DYNAMIC = "^${PN}-spa-plugins.* ^${PN}-modules.*" + +SYSTEMD_SERVICE:${PN} = "pipewire.service" +CONFFILES:${PN} += "${datadir}/pipewire/pipewire.conf" +FILES:${PN} = " \ + ${datadir}/pipewire/pipewire.conf \ + ${datadir}/pipewire/filter-chain.conf \ + ${datadir}/pipewire/filter-chain \ + ${systemd_user_unitdir}/pipewire.* \ + ${systemd_system_unitdir}/pipewire* \ + ${bindir}/pipewire \ + ${datadir}/pipewire/pipewire-avb.conf \ + ${bindir}/pipewire-avb \ + ${datadir}/pipewire/pipewire-aes67.conf \ + ${bindir}/pipewire-aes67 \ + ${datadir}/pipewire/pipewire.conf.avail \ + ${datadir}/pipewire/pipewire-pulse.conf.avail \ + ${datadir}/pipewire/client-rt.conf.avail \ + ${datadir}/pipewire/client.conf.avail \ + ${sysconfdir}/security/limits.d \ +" + +FILES:${PN}-dev += " \ + ${libdir}/${PW_MODULE_SUBDIR}/jack/libjack*.so \ +" + +CONFFILES:libpipewire += "${datadir}/pipewire/client.conf" +FILES:libpipewire = " \ + ${datadir}/pipewire/client.conf \ + ${datadir}/pipewire/client-rt.conf \ + ${datadir}/pipewire/minimal.conf \ + ${libdir}/libpipewire-*.so.* \ +" +# Add the bare minimum modules and plugins required to be able +# to use libpipewire. Without these, it is essentially unusable. +RDEPENDS:libpipewire += " \ + ${PN}-modules-client-node \ + ${PN}-modules-protocol-native \ + ${PN}-spa-plugins-support \ +" + +FILES:${PN}-tools = " \ + ${bindir}/pw-* \ +" + +# This is a shim daemon that is intended to be used as a +# drop-in PulseAudio replacement, providing a pulseaudio-compatible +# socket that can be used by applications that use libpulse. +CONFFILES:${PN}-pulse += "${datadir}/pipewire/pipewire-pulse.conf" + +FILES:${PN}-pulse = " \ + ${datadir}/pipewire/pipewire-pulse.conf \ + ${systemd_user_unitdir}/pipewire-pulse.* \ + ${bindir}/pipewire-pulse \ +" +RDEPENDS:${PN}-pulse += " \ + ${PN}-modules-protocol-pulse \ +" + +# alsa plugin to redirect audio to pipewire +FILES:${PN}-alsa = "\ + ${libdir}/alsa-lib/* \ + ${datadir}/alsa/alsa.conf.d/* \ +" + +#lib to emulate v4l2 system calls on top of PipeWire +FILES:${PN}-v4l2 = "\ + ${libdir}/${PW_MODULE_SUBDIR}/v4l2/libpw-v4l2.so \ +" + +# jack drop-in libraries to redirect audio to pipewire +CONFFILES:${PN}-jack = "${datadir}/pipewire/jack.conf" +FILES:${PN}-jack = "\ + ${datadir}/pipewire/jack.conf \ + ${libdir}/${PW_MODULE_SUBDIR}/jack/libjack*.so.* \ +" +# Dynamic packages (see set_dynamic_metapkg_rdepends). +FILES:${PN}-spa-plugins-bluez5 += " \ + ${datadir}/${SPA_SUBDIR}/bluez5/bluez-hardware.conf \ +" +RRECOMMENDS:${PN}-spa-plugins += "${PN}-spa-plugins-meta" + +FILES:${PN}-spa-tools = " \ + ${bindir}/spa-* \ +" + +# Dynamic packages (see set_dynamic_metapkg_rdepends). +FILES:${PN}-modules = "" +RRECOMMENDS:${PN}-modules += "${PN}-modules-meta" + +CONFFILES:${PN}-modules-rtkit = "${datadir}/pipewire/client-rt.conf" +FILES:${PN}-modules-rtkit += " \ + ${datadir}/pipewire/client-rt.conf \ + " + +FILES:${PN}-alsa-card-profile = " \ + ${datadir}/alsa-card-profile/* \ + ${nonarch_base_libdir}/udev/rules.d/90-pipewire-alsa.rules \ +" + +FILES:gstreamer1.0-pipewire = " \ + ${libdir}/gstreamer-1.0/* \ +" diff --git a/meta-pipewire/recipes-multimedia/pipewire/pipewire_1.0.0.bbappend b/meta-pipewire/recipes-multimedia/pipewire/pipewire_1.0.0.bbappend new file mode 100644 index 000000000..beb7c0817 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/pipewire/pipewire_1.0.0.bbappend @@ -0,0 +1,25 @@ +SRC_URI += "\ + file://0001-systemd-Do-not-override-rootprefix.patch \ +" + +PACKAGECONFIG = "\ + ${@bb.utils.contains('DISTRO_FEATURES', 'bluez5', 'bluez', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'alsa', 'alsa pipewire-alsa', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', 'sndfile', '', d)} \ + ${@bb.utils.filter('DISTRO_FEATURES', 'systemd', d)} \ + gstreamer v4l2 \ +" + +do_install:append() { + # install symlinks to alsalib configuration files + for i in 50-pipewire.conf 99-pipewire-default.conf; do + if [ -f ${D}${datadir}/alsa/alsa.conf.d/${i} ]; then + install -d ${D}${sysconfdir}/alsa/conf.d + ln -s ${datadir}/alsa/alsa.conf.d/${i} ${D}${sysconfdir}/alsa/conf.d/${i} + fi + done +} + +FILES:${PN}-alsa:append = "\ + ${sysconfdir}/alsa/conf.d/* \ +" diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-functions.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-functions.lua new file mode 100644 index 000000000..7e1794df0 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/00-functions.lua @@ -0,0 +1,27 @@ +components = {} + +function load_module(m) + if not components[m] then + components[m] = { "libwireplumber-module-" .. m, type = "module" } + end +end + +function load_pw_module(m) + if not components[m] then + components[m] = { "libpipewire-module-" .. m, type = "pw_module" } + end +end + +function load_script(s, a) + if not components[s] then + components[s] = { s, type = "script/lua", args = a } + end +end + +function load_monitor(s, a) + load_script("monitors/" .. s .. ".lua", a) +end + +function load_access(s, a) + load_script("access/access-" .. s .. ".lua", a) +end diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/alsa-suspend.lua b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/alsa-suspend.lua new file mode 100644 index 000000000..55edd12cf --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/alsa-suspend.lua @@ -0,0 +1,45 @@ +-- WirePlumber +-- +-- This script mutes all ALSA sinks when the "suspend.playback" metadata +-- key is set to 1; compliments pipewire-ic-ipc and the respective support +-- for handling "suspend.playback" in the policy scripts +-- +-- Copyright © 2021 Collabora Ltd. +-- @author George Kiagiadakis <george.kiagiadakis@collabora.com> +-- +-- SPDX-License-Identifier: MIT + +mixer_api = Plugin.find("mixer-api") + +nodes_om = ObjectManager { + Interest { type = "node", + Constraint { "media.class", "matches", "Audio/Sink" }, + Constraint { "object.path", "matches", "alsa:pcm:*" }, + }, +} + +metadata_om = ObjectManager { + Interest { type = "metadata", + Constraint { "metadata.name", "=", "default" }, + } +} + +metadata_om:connect("object-added", function (om, metadata) + metadata:connect("changed", function (m, subject, key, t, value) + if key == "suspend.playback" then + local suspended = (value == "1") + + Log.info(string.format("%s ALSA nodes for IC sound", + suspended and "muting" or "unmuting")) + + for n in nodes_om:iterate() do + mixer_api:call("set-volume", n["bound-id"], { + ["mute"] = suspended, + }) + end + end + end) +end) + +nodes_om:activate() +metadata_om:activate() diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.conf new file mode 100644 index 000000000..9077e3f45 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.conf @@ -0,0 +1,74 @@ +# 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 new file mode 100644 index 000000000..530f4cc62 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/bluetooth.lua.d/30-bluez-monitor.lua @@ -0,0 +1,110 @@ +-- 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 new file mode 100644 index 000000000..d07f7ab85 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/30-alsa-monitor.lua @@ -0,0 +1,151 @@ +-- 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 new file mode 100644 index 000000000..a4eb58ac8 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/30-v4l2-monitor.lua @@ -0,0 +1,48 @@ +-- 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 new file mode 100644 index 000000000..e0d332422 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/40-device-defaults.lua @@ -0,0 +1,26 @@ +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 new file mode 100644 index 000000000..ecb7da476 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/host.lua.d/90-enable-all.lua @@ -0,0 +1,20 @@ +-- 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-bluetooth.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber-bluetooth.conf new file mode 100644 index 000000000..950e6a5d2 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber-bluetooth.conf @@ -0,0 +1,13 @@ +<!-- This configuration file specifies the required security policies + for wireplumber to talk to system bluetooth-related services. --> + +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + + <policy user="pipewire"> + <allow send_destination="org.bluez"/> + <allow send_destination="org.ofono"/> + </policy> + +</busconfig> diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf new file mode 100644 index 000000000..46ad11302 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl/wireplumber.conf @@ -0,0 +1,115 @@ +# 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 new file mode 100644 index 000000000..22ffe5bf3 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-config-agl_git.bb @@ -0,0 +1,61 @@ +SUMMARY = "AGL configuration file for wireplumber" +HOMEPAGE = "https://gitlab.freedesktop.org/gkiagia/wireplumber" +BUGTRACKER = "https://jira.automotivelinux.org" +AUTHOR = "George Kiagiadakis <george.kiagiadakis@collabora.com>" +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://alsa-suspend.lua \ + file://bluetooth.conf \ + file://wireplumber.conf \ + file://wireplumber-bluetooth.conf \ +" +PACKAGE_ARCH = "${MACHINE_ARCH}" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" +do_install:append() { + config_dir="${D}${sysconfdir}/wireplumber/" + 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 -d ${config_dir} + install -m 0644 ${WORKDIR}/00-functions.lua ${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 -d ${scripts_dir} + install -m 0644 ${WORKDIR}/alsa-suspend.lua ${scripts_dir} + + # install dbus daemon configuration + install -d ${dbus_config_dir} + install -m 0644 ${WORKDIR}/wireplumber-bluetooth.conf ${dbus_config_dir} + + # enable additional systemd services + install -d ${systemd_dir} + ln -s ${systemd_system_unitdir}/wireplumber@.service ${systemd_dir}/wireplumber@bluetooth.service +} + +FILES:${PN} += "\ + ${sysconfdir}/* \ + ${datadir}/wireplumber/* \ +" +CONFFILES:${PN} += "\ + ${sysconfdir}/* \ +" 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 new file mode 100644 index 000000000..7e1794df0 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/00-functions.lua @@ -0,0 +1,27 @@ +components = {} + +function load_module(m) + if not components[m] then + components[m] = { "libwireplumber-module-" .. m, type = "module" } + end +end + +function load_pw_module(m) + if not components[m] then + components[m] = { "libpipewire-module-" .. m, type = "pw_module" } + end +end + +function load_script(s, a) + if not components[s] then + components[s] = { s, type = "script/lua", args = a } + end +end + +function load_monitor(s, a) + load_script("monitors/" .. s .. ".lua", a) +end + +function load_access(s, a) + load_script("access/access-" .. s .. ".lua", a) +end diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.conf b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.conf new file mode 100644 index 000000000..42f714849 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.conf @@ -0,0 +1,73 @@ +# 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 new file mode 100644 index 000000000..6814fce4d --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl/policy.lua.d/10-default-policy.lua @@ -0,0 +1,137 @@ +-- 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 new file mode 100644 index 000000000..1a031160e --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-policy-config-agl_git.bb @@ -0,0 +1,41 @@ +SUMMARY = "AGL configuration file for wireplumber policy" +HOMEPAGE = "https://gitlab.freedesktop.org/gkiagia/wireplumber" +BUGTRACKER = "https://jira.automotivelinux.org" +AUTHOR = "Ashok Sidipotu <ashok.sidipotu@collabora.com>" +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 \ +" +PACKAGE_ARCH = "${MACHINE_ARCH}" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" +do_install:append() { + config_dir="${D}${sysconfdir}/wireplumber/" + 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} + + # enable additional systemd services + install -d ${systemd_dir} + ln -s ${systemd_system_unitdir}/wireplumber@.service ${systemd_dir}/wireplumber@policy.service +} + +FILES:${PN} += "\ + ${sysconfdir}/* \ + ${datadir}/wireplumber/* \ +" +CONFFILES:${PN} += "\ + ${sysconfdir}/* \ +" diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb new file mode 100644 index 000000000..a04f115c3 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb @@ -0,0 +1,85 @@ +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 +} |