diff --git a/0001-default-nodes-handle-nodes-without-Routes.patch b/0001-default-nodes-handle-nodes-without-Routes.patch new file mode 100644 index 0000000..457c6e1 --- /dev/null +++ b/0001-default-nodes-handle-nodes-without-Routes.patch @@ -0,0 +1,47 @@ +From 211f1e6b6cd4898121e4c2b821fae4dea6cc3317 Mon Sep 17 00:00:00 2001 +From: Wim Taymans +Date: Fri, 14 Jan 2022 16:28:48 +0100 +Subject: [PATCH] default-nodes: handle nodes without Routes + +When a node has not part of any EnumRoute, we must assume it is +available. + +Fixes selection of Pro Audio nodes as default nodes. +--- + modules/module-default-nodes.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/modules/module-default-nodes.c b/modules/module-default-nodes.c +index 32b2725b..15aadeaa 100644 +--- a/modules/module-default-nodes.c ++++ b/modules/module-default-nodes.c +@@ -108,6 +108,7 @@ node_has_available_routes (WpDefaultNodes * self, WpNode *node) + gint dev_id = dev_id_str ? atoi (dev_id_str) : -1; + gint cpd = cpd_str ? atoi (cpd_str) : -1; + g_autoptr (WpDevice) device = NULL; ++ gint found = 0; + + if (dev_id == -1 || cpd == -1) + return TRUE; +@@ -168,6 +169,7 @@ node_has_available_routes (WpDefaultNodes * self, WpNode *node) + for (; wp_iterator_next (it, &v); g_value_unset (&v)) { + gint32 *d = (gint32 *)g_value_get_pointer (&v); + if (d && *d == cpd) { ++ found++; + if (route_avail != SPA_PARAM_AVAILABILITY_no) + return TRUE; + } +@@ -175,6 +177,10 @@ node_has_available_routes (WpDefaultNodes * self, WpNode *node) + } + } + } ++ /* The node is part of a profile without routes so we assume it ++ * is available. This can happen for Pro Audio profiles */ ++ if (found == 0) ++ return TRUE; + + return FALSE; + } +-- +GitLab + diff --git a/0001-policy-node-fix-typo-when-finding-best-target.patch b/0001-policy-node-fix-typo-when-finding-best-target.patch deleted file mode 100644 index 53da886..0000000 --- a/0001-policy-node-fix-typo-when-finding-best-target.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 23fc4d21a9cfad492f8d3a367e438115197dff4a Mon Sep 17 00:00:00 2001 -From: Julian Bouzas -Date: Fri, 7 Jan 2022 10:12:04 -0500 -Subject: [PATCH 01/14] policy-node: fix typo when finding best target - ---- - src/scripts/policy-node.lua | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/scripts/policy-node.lua b/src/scripts/policy-node.lua -index 0d716c1..8ca5a69 100644 ---- a/src/scripts/policy-node.lua -+++ b/src/scripts/policy-node.lua -@@ -482,7 +482,7 @@ function findUndefinedTarget (si) - if default_nodes ~= nil then - return findDefaultlinkable (si) - else -- return findBestlinkable (si) -+ return findBestLinkable (si) - end - end - --- -2.34.1 - diff --git a/0002-policy-node-schedule-a-rescan-without-timeout-if-def.patch b/0002-policy-node-schedule-a-rescan-without-timeout-if-def.patch deleted file mode 100644 index 0e27499..0000000 --- a/0002-policy-node-schedule-a-rescan-without-timeout-if-def.patch +++ /dev/null @@ -1,48 +0,0 @@ -From afe71d7e48c28b0ae5cbd9327433e3c55c103fcb Mon Sep 17 00:00:00 2001 -From: Julian Bouzas -Date: Thu, 6 Jan 2022 10:53:38 -0500 -Subject: [PATCH 02/14] policy-node: schedule a rescan without timeout if - defined target is not found - -Fixes #146 ---- - src/scripts/policy-node.lua | 17 ++++------------- - 1 file changed, 4 insertions(+), 13 deletions(-) - -diff --git a/src/scripts/policy-node.lua b/src/scripts/policy-node.lua -index 8ca5a69..c273c1f 100644 ---- a/src/scripts/policy-node.lua -+++ b/src/scripts/policy-node.lua -@@ -552,25 +552,16 @@ function handleLinkable (si) - si_target = nil - end - -- -- wait up to 2 seconds for the requested target to become available -- -- this is because the client may have already "seen" a target that we haven't -- -- yet prepared, which leads to a race condition -+ -- if the client has seen a target that we haven't yet prepared, schedule -+ -- a rescan one more time and hope for the best - local si_id = si.id - if si_props["node.target"] and si_props["node.target"] ~= "-1" - and not si_target - and not si_flags[si_id].was_handled - and not si_flags[si_id].done_waiting then -- if not si_flags[si_id].timeout_source then -- si_flags[si_id].timeout_source = Core.timeout_add(2000, function() -- if si_flags[si_id] then -- si_flags[si_id].done_waiting = true -- si_flags[si_id].timeout_source = nil -- scheduleRescan() -- end -- return false -- end) -- end - Log.info (si, "... waiting for target") -+ si_flags[si_id].done_waiting = true -+ scheduleRescan() - return - end - --- -2.34.1 - diff --git a/0003-policy-node-find-best-linkable-if-default-one-cannot.patch b/0003-policy-node-find-best-linkable-if-default-one-cannot.patch deleted file mode 100644 index f7a241a..0000000 --- a/0003-policy-node-find-best-linkable-if-default-one-cannot.patch +++ /dev/null @@ -1,46 +0,0 @@ -From bee9827ae376b75feceea926b0afc727fecca51b Mon Sep 17 00:00:00 2001 -From: Julian Bouzas -Date: Fri, 7 Jan 2022 15:35:10 -0500 -Subject: [PATCH 03/14] policy-node: find best linkable if default one cannot - be linked - -Fixes issue with echo cancellation pipewire module. ---- - src/scripts/policy-node.lua | 19 ++++++++++++++----- - 1 file changed, 14 insertions(+), 5 deletions(-) - -diff --git a/src/scripts/policy-node.lua b/src/scripts/policy-node.lua -index c273c1f..9df5007 100644 ---- a/src/scripts/policy-node.lua -+++ b/src/scripts/policy-node.lua -@@ -477,13 +477,22 @@ function findBestLinkable (si) - end - - function findUndefinedTarget (si) -- -- Find the default linkable if the default nodes module is loaded, otherwise -- -- just find the best linkable based on priority and routes -- if default_nodes ~= nil then -- return findDefaultlinkable (si) -- else -+ -- Just find the best linkable if default nodes module is not loaded -+ if default_nodes == nil then - return findBestLinkable (si) - end -+ -+ -- Otherwise find the default linkable. If the default linkabke cannot link, -+ -- we find the best one instead. We return nil if default does not exist. -+ local si_target, can_passthrough = findDefaultlinkable (si) -+ if si_target then -+ if canLink (si.properties, si_target) then -+ return si_target, can_passthrough -+ else -+ return findBestLinkable (si) -+ end -+ end -+ return nil, nil - end - - function lookupLink (si_id, si_target_id) --- -2.34.1 - diff --git a/0004-spa-pod-fix-different-architecture-errors-for-boolea.patch b/0004-spa-pod-fix-different-architecture-errors-for-boolea.patch deleted file mode 100644 index e13619a..0000000 --- a/0004-spa-pod-fix-different-architecture-errors-for-boolea.patch +++ /dev/null @@ -1,39 +0,0 @@ -From bc76cb7d74a1eac20cabd99ebb27f749d447d6ca Mon Sep 17 00:00:00 2001 -From: Julian Bouzas -Date: Mon, 13 Dec 2021 12:01:52 -0500 -Subject: [PATCH 04/14] spa-pod: fix different architecture errors for boolean - values - ---- - lib/wp/spa-pod.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/lib/wp/spa-pod.c b/lib/wp/spa-pod.c -index c1c2257..bd7b887 100644 ---- a/lib/wp/spa-pod.c -+++ b/lib/wp/spa-pod.c -@@ -2332,6 +2332,10 @@ wp_spa_pod_builder_add_valist (WpSpaPodBuilder *self, va_list args) - } - break; - } -+ case 'b': -+ spa_pod_builder_bool(&self->builder, -+ va_arg(args, gboolean) ? true : false); -+ break; - default: - SPA_POD_BUILDER_COLLECT(&self->builder, *format, args); - break; -@@ -2778,6 +2782,10 @@ wp_spa_pod_parser_get_valist (WpSpaPodParser *self, va_list args) - } - break; - } -+ case 'b': -+ *va_arg(args, gboolean*) = -+ SPA_POD_VALUE(struct spa_pod_bool, pod) ? TRUE : FALSE; -+ break; - default: - SPA_POD_PARSER_COLLECT (pod, *format, args); - break; --- -2.34.1 - diff --git a/0005-config-update-the-endpoints-config.patch b/0005-config-update-the-endpoints-config.patch deleted file mode 100644 index aeb75d7..0000000 --- a/0005-config-update-the-endpoints-config.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 99dfa7d38a66943fc04181a2b82fe6da91402c4f Mon Sep 17 00:00:00 2001 -From: Ashok Sidipotu -Date: Tue, 11 Jan 2022 15:30:30 +0530 -Subject: [PATCH 05/14] config: update the endpoints config - --Sync endpoints config from AGL. --Add a capture endpoint. ---- - .../policy.lua.d/50-endpoints-config.lua | 84 +++++++++++++++---- - 1 file changed, 70 insertions(+), 14 deletions(-) - -diff --git a/src/config/policy.lua.d/50-endpoints-config.lua b/src/config/policy.lua.d/50-endpoints-config.lua -index 4bdf82a..6241509 100644 ---- a/src/config/policy.lua.d/50-endpoints-config.lua -+++ b/src/config/policy.lua.d/50-endpoints-config.lua -@@ -4,36 +4,92 @@ - --[[ - - default_policy.policy.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"] = 10, -- ["action.default"] = "mix", -+ ["priority"] = 25, -+ ["action.default"] = "cork", -+ }, -+ ["Speech-Low"] = { -+ ["priority"] = 30, -+ ["action.default"] = "cork", -+ ["action.Speech-Low"] = "mix", -+ }, -+ ["Custom-Low"] = { -+ ["priority"] = 35, -+ ["action.default"] = "cork", -+ ["action.Custom-Low"] = "mix", - }, -- ["Notification"] = { -- ["priority"] = 20, -+ ["Navigation"] = { -+ ["priority"] = 50, - ["action.default"] = "duck", -- ["action.Notification"] = "mix", -+ ["action.Navigation"] = "mix", - }, -- ["Alert"] = { -- ["priority"] = 30, -+ ["Speech-High"] = { -+ ["priority"] = 60, -+ ["action.default"] = "cork", -+ ["action.Speech-High"] = "mix", -+ }, -+ ["Custom-High"] = { -+ ["priority"] = 65, - ["action.default"] = "cork", -- ["action.Alert"] = "mix", -+ ["action.Custom-High"] = "mix", -+ }, -+ ["Communication"] = { -+ ["priority"] = 75, -+ ["action.default"] = "cork", -+ ["action.Communication"] = "mix", -+ }, -+ ["Emergency"] = { -+ ["alias"] = { "Alert" }, -+ ["priority"] = 99, -+ ["action.default"] = "cork", -+ ["action.Emergency"] = "mix", - }, - } - - default_policy.endpoints = { -+ ["endpoint.capture"] = { -+ ["media.class"] = "Audio/Source", -+ ["role"] = "Capture", -+ }, - ["endpoint.multimedia"] = { - ["media.class"] = "Audio/Sink", - ["role"] = "Multimedia", - }, -- ["endpoint.notifications"] = { -+ ["endpoint.speech_low"] = { -+ ["media.class"] = "Audio/Sink", -+ ["role"] = "Speech-Low", -+ }, -+ ["endpoint.custom_low"] = { - ["media.class"] = "Audio/Sink", -- ["role"] = "Notification", -+ ["role"] = "Custom-Low", - }, -- ["endpoint.alert"] = { -+ ["endpoint.navigation"] = { - ["media.class"] = "Audio/Sink", -- ["role"] = "Alert", -+ ["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", - }, - } -- --]]-- -+]]-- -\ No newline at end of file --- -2.34.1 - diff --git a/0006-policy-endpoint-client.lua-fix-record-with-endpoints.patch b/0006-policy-endpoint-client.lua-fix-record-with-endpoints.patch deleted file mode 100644 index 57e2aae..0000000 --- a/0006-policy-endpoint-client.lua-fix-record-with-endpoints.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 2e23d827793e56655ffd6be39b377578cef21661 Mon Sep 17 00:00:00 2001 -From: Ashok Sidipotu -Date: Tue, 11 Jan 2022 15:31:40 +0530 -Subject: [PATCH 06/14] policy-endpoint-client.lua: fix record with endpoints - -The Role traversal of config data to take notice of the -media class as well so that source and sink roles dont -overstep on each other and pick up unexpected endpoints. ---- - src/scripts/policy-endpoint-client.lua | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/src/scripts/policy-endpoint-client.lua b/src/scripts/policy-endpoint-client.lua -index 6b96edf..e898e35 100644 ---- a/src/scripts/policy-endpoint-client.lua -+++ b/src/scripts/policy-endpoint-client.lua -@@ -37,10 +37,12 @@ function scheduleRescan () - end - end - --function findRole(role) -+function findRole(role, tmc) - if role and not config.roles[role] then - for r, p in pairs(config.roles) do -- if type(p.alias) == "table" then -+ -- default media class can be overridden in the role config data -+ mc = p["media.class"] or "Audio/Sink" -+ if (type(p.alias) == "table" and tmc == mc) then - for i = 1, #(p.alias), 1 do - if role == p.alias[i] then - return r -@@ -69,7 +71,7 @@ function findTargetEndpoint (node, media_class) - end - - -- find highest priority endpoint by role -- media_role = findRole(node.properties["media.role"]) -+ media_role = findRole(node.properties["media.role"], target_media_class) - for si_target_ep in endpoints_om:iterate { - Constraint { "role", "=", media_role, type = "pw-global" }, - Constraint { "media.class", "=", target_media_class, type = "pw-global" }, --- -2.34.1 - diff --git a/0007-default-nodes-check-if-the-ports-exist-in-rescan_om.patch b/0007-default-nodes-check-if-the-ports-exist-in-rescan_om.patch deleted file mode 100644 index 0ac2311..0000000 --- a/0007-default-nodes-check-if-the-ports-exist-in-rescan_om.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 07a0a5b4043ab5982a82311e031ddfd6feb80da1 Mon Sep 17 00:00:00 2001 -From: Julian Bouzas -Date: Tue, 11 Jan 2022 07:50:15 -0500 -Subject: [PATCH 07/14] default-nodes: check if the ports exist in rescan_om - -Ports might not be ready in the node's port object manager yet. - -Fixes #153 and #150 ---- - modules/module-default-nodes.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/modules/module-default-nodes.c b/modules/module-default-nodes.c -index 31eafcf..c45be2d 100644 ---- a/modules/module-default-nodes.c -+++ b/modules/module-default-nodes.c -@@ -307,7 +307,12 @@ nodes_ready (WpDefaultNodes * self) - PW_KEY_DEVICE_ID, "=i", device_id, NULL); - for (; wp_iterator_next (node_it, &node_val); g_value_unset (&node_val)) { - WpPipewireObject *node = g_value_get_object (&node_val); -- if (wp_node_get_n_ports (WP_NODE (node)) > 0) -+ g_autoptr (WpPort) port = -+ wp_object_manager_lookup (self->rescan_om, -+ WP_TYPE_PORT, WP_CONSTRAINT_TYPE_PW_PROPERTY, -+ PW_KEY_NODE_ID, "=u", wp_proxy_get_bound_id (WP_PROXY (node)), -+ NULL); -+ if (port) - ready_nodes++; - } - -@@ -327,7 +332,12 @@ nodes_ready (WpDefaultNodes * self) - WpPipewireObject *node = g_value_get_object (&node_val); - const gchar *media_class = wp_pipewire_object_get_property ( - WP_PIPEWIRE_OBJECT (node), PW_KEY_MEDIA_CLASS); -- if (wp_node_get_n_ports (WP_NODE (node)) == 0 && -+ g_autoptr (WpPort) port = -+ wp_object_manager_lookup (self->rescan_om, -+ WP_TYPE_PORT, WP_CONSTRAINT_TYPE_PW_PROPERTY, -+ PW_KEY_NODE_ID, "=u", wp_proxy_get_bound_id (WP_PROXY (node)), -+ NULL); -+ if (!port && - (g_strcmp0 ("Audio/Source/Virtual", media_class) == 0 || - g_strcmp0 ("Video/Source/Virtual", media_class) == 0)) - return FALSE; --- -2.34.1 - diff --git a/0008-scripts-monitors-log-warning-if-spa-devices-were-not.patch b/0008-scripts-monitors-log-warning-if-spa-devices-were-not.patch deleted file mode 100644 index 421e112..0000000 --- a/0008-scripts-monitors-log-warning-if-spa-devices-were-not.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 40b16974cf800ce728c7f084fbdd8b30b7a9f03c Mon Sep 17 00:00:00 2001 -From: Julian Bouzas -Date: Tue, 11 Jan 2022 11:27:33 -0500 -Subject: [PATCH 08/14] scripts: monitors: log warning if spa devices were not - created successfully - -Can happen if the user does not have the specific spa pluging installed. ---- - src/scripts/monitors/alsa.lua | 10 +++++++--- - src/scripts/monitors/bluez.lua | 9 +++++++-- - src/scripts/monitors/libcamera.lua | 10 +++++++--- - src/scripts/monitors/v4l2.lua | 10 +++++++--- - 4 files changed, 28 insertions(+), 11 deletions(-) - -diff --git a/src/scripts/monitors/alsa.lua b/src/scripts/monitors/alsa.lua -index be4648e..8d297c1 100644 ---- a/src/scripts/monitors/alsa.lua -+++ b/src/scripts/monitors/alsa.lua -@@ -177,9 +177,13 @@ end - - function createDevice(parent, id, factory, properties) - local device = SpaDevice(factory, properties) -- device:connect("create-object", createNode) -- device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND) -- parent:store_managed_object(id, device) -+ if device then -+ device:connect("create-object", createNode) -+ device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND) -+ parent:store_managed_object(id, device) -+ else -+ Log.warning ("Failed to create '" .. factory .. "' device") -+ end - end - - function prepareDevice(parent, id, type, factory, properties) -diff --git a/src/scripts/monitors/bluez.lua b/src/scripts/monitors/bluez.lua -index 172e013..4a54a7b 100644 ---- a/src/scripts/monitors/bluez.lua -+++ b/src/scripts/monitors/bluez.lua -@@ -109,8 +109,13 @@ function createDevice(parent, id, type, factory, properties) - - -- create the device - device = SpaDevice(factory, properties) -- device:connect("create-object", createNode) -- parent:store_managed_object(id, device) -+ if device then -+ device:connect("create-object", createNode) -+ parent:store_managed_object(id, device) -+ else -+ Log.warning ("Failed to create '" .. factory .. "' device") -+ return -+ end - end - - Log.info(parent, string.format("%d, %s (%s): %s", -diff --git a/src/scripts/monitors/libcamera.lua b/src/scripts/monitors/libcamera.lua -index e6e3ed9..27c7459 100644 ---- a/src/scripts/monitors/libcamera.lua -+++ b/src/scripts/monitors/libcamera.lua -@@ -125,9 +125,13 @@ function createDevice(parent, id, type, factory, properties) - - -- create the device - local device = SpaDevice(factory, properties) -- device:connect("create-object", createNode) -- device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND) -- parent:store_managed_object(id, device) -+ if device then -+ device:connect("create-object", createNode) -+ device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND) -+ parent:store_managed_object(id, device) -+ else -+ Log.warning ("Failed to create '" .. factory .. "' device") -+ end - end - - monitor = SpaDevice("api.libcamera.enum.manager", config.properties or {}) -diff --git a/src/scripts/monitors/v4l2.lua b/src/scripts/monitors/v4l2.lua -index fd9a20d..102eb81 100644 ---- a/src/scripts/monitors/v4l2.lua -+++ b/src/scripts/monitors/v4l2.lua -@@ -125,9 +125,13 @@ function createDevice(parent, id, type, factory, properties) - - -- create the device - local device = SpaDevice(factory, properties) -- device:connect("create-object", createNode) -- device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND) -- parent:store_managed_object(id, device) -+ if device then -+ device:connect("create-object", createNode) -+ device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND) -+ parent:store_managed_object(id, device) -+ else -+ Log.warning ("Failed to create '" .. factory .. "' device") -+ end - end - - monitor = SpaDevice("api.v4l2.enum.udev", config.properties or {}) --- -2.34.1 - diff --git a/0009-default-nodes-check-if-default-node-has-available-ro.patch b/0009-default-nodes-check-if-default-node-has-available-ro.patch deleted file mode 100644 index 105fe2d..0000000 --- a/0009-default-nodes-check-if-default-node-has-available-ro.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 75281d86817a090147a15711266709114b15aefa Mon Sep 17 00:00:00 2001 -From: Julian Bouzas -Date: Tue, 11 Jan 2022 13:59:58 -0500 -Subject: [PATCH 09/14] default-nodes: check if default node has available - route - -Fixes #145 ---- - modules/module-default-nodes.c | 85 ++++++++++++++++++++++++++++++++++ - 1 file changed, 85 insertions(+) - -diff --git a/modules/module-default-nodes.c b/modules/module-default-nodes.c -index c45be2d..354c474 100644 ---- a/modules/module-default-nodes.c -+++ b/modules/module-default-nodes.c -@@ -8,6 +8,7 @@ - - #include - #include -+#include - #include - - #define COMPILING_MODULE_DEFAULT_NODES 1 -@@ -97,6 +98,87 @@ timer_start (WpDefaultNodes *self) - } - } - -+static gboolean -+node_has_available_routes (WpDefaultNodes * self, WpNode *node) -+{ -+ const gchar *dev_id_str = wp_pipewire_object_get_property ( -+ WP_PIPEWIRE_OBJECT (node), PW_KEY_DEVICE_ID); -+ const gchar *cpd_str = wp_pipewire_object_get_property ( -+ WP_PIPEWIRE_OBJECT (node), "card.profile.device"); -+ gint dev_id = dev_id_str ? atoi (dev_id_str) : -1; -+ gint cpd = cpd_str ? atoi (cpd_str) : -1; -+ g_autoptr (WpDevice) device = NULL; -+ -+ if (dev_id == -1 || cpd == -1) -+ return TRUE; -+ -+ /* Get the device */ -+ device = wp_object_manager_lookup (self->rescan_om, WP_TYPE_DEVICE, -+ WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=i", dev_id, NULL); -+ if (!device) -+ return TRUE; -+ -+ /* Check if the current device route supports the node card device profile */ -+ { -+ g_autoptr (WpIterator) routes = NULL; -+ g_auto (GValue) val = G_VALUE_INIT; -+ routes = wp_pipewire_object_enum_params_sync (WP_PIPEWIRE_OBJECT (device), -+ "Route", NULL); -+ for (; wp_iterator_next (routes, &val); g_value_unset (&val)) { -+ WpSpaPod *route = g_value_get_boxed (&val); -+ gint route_device = -1; -+ guint32 route_avail = SPA_PARAM_AVAILABILITY_unknown; -+ -+ if (!wp_spa_pod_get_object (route, NULL, -+ "device", "i", &route_device, -+ "available", "?I", &route_avail, -+ NULL)) -+ continue; -+ -+ if (route_device != cpd) -+ continue; -+ -+ if (route_avail == SPA_PARAM_AVAILABILITY_no) -+ return FALSE; -+ -+ return TRUE; -+ } -+ } -+ -+ /* Check if available routes support the node card device profile */ -+ { -+ g_autoptr (WpIterator) routes = NULL; -+ g_auto (GValue) val = G_VALUE_INIT; -+ routes = wp_pipewire_object_enum_params_sync (WP_PIPEWIRE_OBJECT (device), -+ "EnumRoute", NULL); -+ for (; wp_iterator_next (routes, &val); g_value_unset (&val)) { -+ WpSpaPod *route = g_value_get_boxed (&val); -+ guint32 route_avail = SPA_PARAM_AVAILABILITY_unknown; -+ g_autoptr (WpSpaPod) route_devices = NULL; -+ -+ if (!wp_spa_pod_get_object (route, NULL, -+ "available", "?I", &route_avail, -+ "devices", "?P", &route_devices, -+ NULL)) -+ continue; -+ -+ { -+ g_autoptr (WpIterator) it = wp_spa_pod_new_iterator (route_devices); -+ g_auto (GValue) v = G_VALUE_INIT; -+ for (; wp_iterator_next (it, &v); g_value_unset (&v)) { -+ gint32 *d = (gint32 *)g_value_get_pointer (&v); -+ if (d && *d == cpd) { -+ if (route_avail != SPA_PARAM_AVAILABILITY_no) -+ return TRUE; -+ } -+ } -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ - static WpNode * - find_best_media_class_node (WpDefaultNodes * self, const gchar *media_class, - const gchar *node_name, WpDirection direction, gint *priority) -@@ -124,6 +206,9 @@ find_best_media_class_node (WpDefaultNodes * self, const gchar *media_class, - WP_PIPEWIRE_OBJECT (node), PW_KEY_PRIORITY_SESSION); - gint prio = prio_str ? atoi (prio_str) : -1; - -+ if (!node_has_available_routes (self, node)) -+ continue; -+ - if (name && node_name && g_strcmp0 (name, node_name) == 0) - prio += 10000; - --- -2.34.1 - diff --git a/0010-added-support-for-disabling-nodes-and-devices-throug.patch b/0010-added-support-for-disabling-nodes-and-devices-throug.patch deleted file mode 100644 index 21eb9c3..0000000 --- a/0010-added-support-for-disabling-nodes-and-devices-throug.patch +++ /dev/null @@ -1,62 +0,0 @@ -From bbd23fa3e3a4e13c86bf37b36e7d19d8dcaff771 Mon Sep 17 00:00:00 2001 -From: mazunki -Date: Wed, 12 Jan 2022 12:13:08 +0100 -Subject: [PATCH 10/14] added support for disabling nodes and devices through - conf - ---- - src/config/main.lua.d/50-alsa-config.lua | 13 +++++++++++++ - src/scripts/monitors/alsa.lua | 6 ++++++ - 2 files changed, 19 insertions(+) - -diff --git a/src/config/main.lua.d/50-alsa-config.lua b/src/config/main.lua.d/50-alsa-config.lua -index 9259cf5..23f8ca1 100644 ---- a/src/config/main.lua.d/50-alsa-config.lua -+++ b/src/config/main.lua.d/50-alsa-config.lua -@@ -17,6 +17,19 @@ alsa_monitor.properties = { - - alsa_monitor.rules = { - -- An array of matches/actions to evaluate. -+ -- -+ -- If you want to disable some devices or nodes, you can apply properties per device as the following example. -+ -- The name can be found by running pw-cli ls Device, or pw-cli dump Device -+ --{ -+ -- matches = { -+ -- { -+ -- { "device.name", "matches", "name_of_some_disabled_card" }, -+ -- }, -+ -- }, -+ -- apply_properties = { -+ -- ["device.disabled"] = true, -+ -- }, -+ --} - { - -- Rules for matching a device or node. It is an array of - -- properties that all need to match the regexp. If any of the -diff --git a/src/scripts/monitors/alsa.lua b/src/scripts/monitors/alsa.lua -index 8d297c1..c917a5c 100644 ---- a/src/scripts/monitors/alsa.lua -+++ b/src/scripts/monitors/alsa.lua -@@ -168,6 +168,9 @@ function createNode(parent, id, type, factory, properties) - - -- apply properties from config.rules - rulesApplyProperties(properties) -+ if properties["node.disabled"] then -+ return -+ end - - -- create the node - local node = Node("adapter", properties) -@@ -254,6 +257,9 @@ function prepareDevice(parent, id, type, factory, properties) - - -- apply properties from config.rules - rulesApplyProperties(properties) -+ if properties["device.disabled"] then -+ return -+ end - - -- override the device factory to use ACP - if properties["api.alsa.use-acp"] then --- -2.34.1 - diff --git a/0011-default-nodes-add-more-logs.patch b/0011-default-nodes-add-more-logs.patch deleted file mode 100644 index 357c4f9..0000000 --- a/0011-default-nodes-add-more-logs.patch +++ /dev/null @@ -1,53 +0,0 @@ -From b4245d64c5117015fa293148273f86bdfbeb494f Mon Sep 17 00:00:00 2001 -From: Julian Bouzas -Date: Wed, 12 Jan 2022 13:39:57 -0500 -Subject: [PATCH 11/14] default-nodes: add more logs - ---- - modules/module-default-nodes.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/modules/module-default-nodes.c b/modules/module-default-nodes.c -index 354c474..ac9a87b 100644 ---- a/modules/module-default-nodes.c -+++ b/modules/module-default-nodes.c -@@ -401,8 +401,13 @@ nodes_ready (WpDefaultNodes * self) - ready_nodes++; - } - -- if (ready_nodes < total_nodes) -+ if (ready_nodes < total_nodes) { -+ const gchar *device_name = wp_pipewire_object_get_property ( -+ WP_PIPEWIRE_OBJECT (device), PW_KEY_DEVICE_NAME); -+ wp_debug_object (self, "device '%s' is not ready (%d/%d)", device_name, -+ ready_nodes, total_nodes); - return FALSE; -+ } - } - } - -@@ -424,8 +429,12 @@ nodes_ready (WpDefaultNodes * self) - NULL); - if (!port && - (g_strcmp0 ("Audio/Source/Virtual", media_class) == 0 || -- g_strcmp0 ("Video/Source/Virtual", media_class) == 0)) -+ g_strcmp0 ("Video/Source/Virtual", media_class) == 0)) { -+ const gchar *node_name = wp_pipewire_object_get_property ( -+ WP_PIPEWIRE_OBJECT (node), PW_KEY_NODE_NAME); -+ wp_debug_object (self, "virtual node '%s' is not ready", node_name); - return FALSE; -+ } - } - } - -@@ -465,6 +474,7 @@ schedule_rescan (WpDefaultNodes * self) - g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self)); - g_return_if_fail (core); - -+ wp_debug_object (self, "scheduling default nodes rescan"); - wp_core_sync_closure (core, NULL, g_cclosure_new_object ( - G_CALLBACK (sync_rescan), G_OBJECT (self))); - } --- -2.34.1 - diff --git a/0012-device-activation-show-device-name-in-logs.patch b/0012-device-activation-show-device-name-in-logs.patch deleted file mode 100644 index d08804b..0000000 --- a/0012-device-activation-show-device-name-in-logs.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 8844cfb0743f3ce1b447120f4c012cfdae9c2aec Mon Sep 17 00:00:00 2001 -From: Julian Bouzas -Date: Wed, 12 Jan 2022 14:07:59 -0500 -Subject: [PATCH 12/14] device-activation: show device name in logs - ---- - modules/module-device-activation.c | 29 +++++++++++++++++------------ - 1 file changed, 17 insertions(+), 12 deletions(-) - -diff --git a/modules/module-device-activation.c b/modules/module-device-activation.c -index a28f2ea..98978a2 100644 ---- a/modules/module-device-activation.c -+++ b/modules/module-device-activation.c -@@ -31,6 +31,7 @@ G_DEFINE_TYPE (WpDeviceActivation, wp_device_activation, WP_TYPE_PLUGIN) - static void - set_device_profile (WpDeviceActivation *self, WpPipewireObject *device, gint index) - { -+ const gchar *dn = wp_pipewire_object_get_property (device, PW_KEY_DEVICE_NAME); - gpointer active_ptr = NULL; - - g_return_if_fail (device); -@@ -38,7 +39,7 @@ set_device_profile (WpDeviceActivation *self, WpPipewireObject *device, gint ind - /* Make sure the profile we want to set is not active */ - active_ptr = g_object_get_qdata (G_OBJECT (device), active_profile_quark ()); - if (active_ptr && GPOINTER_TO_INT (active_ptr) - 1 == index) { -- wp_info_object (self, "profile %d is already active", index); -+ wp_info_object (self, "profile %d is already active in %s", index, dn); - return; - } - -@@ -49,8 +50,7 @@ set_device_profile (WpDeviceActivation *self, WpPipewireObject *device, gint ind - "index", "i", index, - NULL)); - -- wp_info_object (self, "profile %d set on device " WP_OBJECT_FORMAT, index, -- WP_OBJECT_ARGS (device)); -+ wp_info_object (self, "profile %d set on device %s", index, dn); - } - - static gint -@@ -184,6 +184,7 @@ static gint - handle_active_profile (WpDeviceActivation *self, WpPipewireObject *proxy, - WpIterator *profiles, gboolean *changed, gboolean *off) - { -+ const gchar *dn = wp_pipewire_object_get_property (proxy, PW_KEY_DEVICE_NAME); - gpointer active_ptr = NULL; - gint new_active = -1; - gint local_changed = FALSE; -@@ -191,7 +192,7 @@ handle_active_profile (WpDeviceActivation *self, WpPipewireObject *proxy, - /* Find the new active profile */ - new_active = find_active_profile (proxy, off); - if (new_active < 0) { -- wp_info_object (self, "cannot find active profile"); -+ wp_info_object (self, "cannot find active profile in %s", dn); - return new_active; - } - -@@ -199,7 +200,7 @@ handle_active_profile (WpDeviceActivation *self, WpPipewireObject *proxy, - active_ptr = g_object_get_qdata (G_OBJECT (proxy), active_profile_quark ()); - local_changed = !active_ptr || GPOINTER_TO_INT (active_ptr) - 1 != new_active; - if (local_changed) { -- wp_info_object (self, "active profile changed to: %d", new_active); -+ wp_info_object (self, "active profile changed to %d in %s", new_active, dn); - g_object_set_qdata (G_OBJECT (proxy), active_profile_quark (), - GINT_TO_POINTER (new_active + 1)); - } -@@ -214,6 +215,7 @@ static gint - handle_best_profile (WpDeviceActivation *self, WpPipewireObject *proxy, - WpIterator *profiles, gboolean *changed) - { -+ const gchar *dn = wp_pipewire_object_get_property (proxy, PW_KEY_DEVICE_NAME); - gpointer best_ptr = NULL; - gint new_best = -1; - gboolean local_changed = FALSE; -@@ -221,7 +223,7 @@ handle_best_profile (WpDeviceActivation *self, WpPipewireObject *proxy, - /* Get the new best profile index */ - new_best = find_best_profile (profiles); - if (new_best < 0) { -- wp_info_object (self, "cannot find best profile"); -+ wp_info_object (self, "cannot find best profile in %s", dn); - return new_best; - } - -@@ -229,7 +231,7 @@ handle_best_profile (WpDeviceActivation *self, WpPipewireObject *proxy, - best_ptr = g_object_get_qdata (G_OBJECT (proxy), best_profile_quark ()); - local_changed = !best_ptr || GPOINTER_TO_INT (best_ptr) - 1 != new_best; - if (local_changed) { -- wp_info_object (self, "found new best profile: %d", new_best); -+ wp_info_object (self, "best profile changed to %d in %s", new_best, dn); - g_object_set_qdata (G_OBJECT (proxy), best_profile_quark (), - GINT_TO_POINTER (new_best + 1)); - } -@@ -244,6 +246,7 @@ static void - handle_enum_profiles (WpDeviceActivation *self, WpPipewireObject *proxy, - WpIterator *profiles) - { -+ const gchar *dn = wp_pipewire_object_get_property (proxy, PW_KEY_DEVICE_NAME); - gint active_idx = FALSE, best_idx = FALSE; - gboolean active_changed = FALSE, best_changed = FALSE, active_off = FALSE; - -@@ -256,14 +259,16 @@ handle_enum_profiles (WpDeviceActivation *self, WpPipewireObject *proxy, - default_idx = find_default_profile (self, proxy, profiles, &default_avail); - if (default_idx >= 0) { - if (default_avail == SPA_PARAM_AVAILABILITY_no) { -- wp_info_object (self, "default profile %d unavailable", default_idx); -+ wp_info_object (self, "default profile %d unavailable for %s", -+ default_idx, dn); - } else { -- wp_info_object (self, "found default profile: %d", default_idx); -+ wp_info_object (self, "found default profile %d for %s", default_idx, -+ dn); - set_device_profile (self, proxy, default_idx); - return; - } - } else { -- wp_info_object (self, "cannot find default profile"); -+ wp_info_object (self, "cannot find default profile for %s", dn); - } - } - -@@ -272,9 +277,9 @@ handle_enum_profiles (WpDeviceActivation *self, WpPipewireObject *proxy, - if (best_idx >= 0 && best_changed) - set_device_profile (self, proxy, best_idx); - else if (best_idx >= 0) -- wp_info_object (self, "best profile already set: %d", best_idx); -+ wp_info_object (self, "best profile %d already set in %s", best_idx, dn); - else -- wp_info_object (self, "best profile not found"); -+ wp_info_object (self, "best profile not found in %s", dn); - } - - static void --- -2.34.1 - diff --git a/0013-scripts-fallback-to-empty-config-table-if-args-were-.patch b/0013-scripts-fallback-to-empty-config-table-if-args-were-.patch deleted file mode 100644 index c82b6ae..0000000 --- a/0013-scripts-fallback-to-empty-config-table-if-args-were-.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 18bc3d3596a1fac8ab21361160ac4e9c6ec37c89 Mon Sep 17 00:00:00 2001 -From: George Kiagiadakis -Date: Thu, 13 Jan 2022 11:08:34 +0200 -Subject: [PATCH 13/14] scripts: fallback to empty config table if args were - not passed from the config files - -Fixes #158 ---- - src/scripts/access/access-default.lua | 2 +- - src/scripts/create-item.lua | 2 +- - src/scripts/default-routes.lua | 2 +- - src/scripts/monitors/alsa-midi.lua | 2 +- - src/scripts/monitors/alsa.lua | 2 +- - src/scripts/policy-endpoint-client-links.lua | 2 +- - src/scripts/policy-endpoint-client.lua | 2 +- - src/scripts/policy-endpoint-device.lua | 2 +- - src/scripts/policy-node.lua | 2 +- - 9 files changed, 9 insertions(+), 9 deletions(-) - -diff --git a/src/scripts/access/access-default.lua b/src/scripts/access/access-default.lua -index 3c27e90..0fac87b 100644 ---- a/src/scripts/access/access-default.lua -+++ b/src/scripts/access/access-default.lua -@@ -5,7 +5,7 @@ - -- - -- SPDX-License-Identifier: MIT - --local config = ... -+local config = ... or {} - - -- preprocess rules and create Interest objects - for _, r in ipairs(config.rules or {}) do -diff --git a/src/scripts/create-item.lua b/src/scripts/create-item.lua -index ad4a6f6..f2c7562 100644 ---- a/src/scripts/create-item.lua -+++ b/src/scripts/create-item.lua -@@ -6,7 +6,7 @@ - -- SPDX-License-Identifier: MIT - - -- Receive script arguments from config.lua --local config = ... -+local config = ... or {} - - items = {} - -diff --git a/src/scripts/default-routes.lua b/src/scripts/default-routes.lua -index 953cba3..075f5d6 100644 ---- a/src/scripts/default-routes.lua -+++ b/src/scripts/default-routes.lua -@@ -8,7 +8,7 @@ - -- - -- SPDX-License-Identifier: MIT - --local config = ... -+local config = ... or {} - - -- whether to store state on the file system - use_persistent_storage = config["use-persistent-storage"] or false -diff --git a/src/scripts/monitors/alsa-midi.lua b/src/scripts/monitors/alsa-midi.lua -index bf4fde4..0efee34 100644 ---- a/src/scripts/monitors/alsa-midi.lua -+++ b/src/scripts/monitors/alsa-midi.lua -@@ -6,7 +6,7 @@ - -- SPDX-License-Identifier: MIT - - -- Receive script arguments from config.lua --local config = ... -+local config = ... or {} - - -- ensure config.properties is not nil - config.properties = config.properties or {} -diff --git a/src/scripts/monitors/alsa.lua b/src/scripts/monitors/alsa.lua -index c917a5c..3e8eda8 100644 ---- a/src/scripts/monitors/alsa.lua -+++ b/src/scripts/monitors/alsa.lua -@@ -6,7 +6,7 @@ - -- SPDX-License-Identifier: MIT - - -- Receive script arguments from config.lua --local config = ... -+local config = ... or {} - - -- ensure config.properties is not nil - config.properties = config.properties or {} -diff --git a/src/scripts/policy-endpoint-client-links.lua b/src/scripts/policy-endpoint-client-links.lua -index 1a93294..eaa1c08 100644 ---- a/src/scripts/policy-endpoint-client-links.lua -+++ b/src/scripts/policy-endpoint-client-links.lua -@@ -5,7 +5,7 @@ - -- - -- SPDX-License-Identifier: MIT - --local config = ... -+local config = ... or {} - config.roles = config.roles or {} - config["duck.level"] = config["duck.level"] or 0.3 - -diff --git a/src/scripts/policy-endpoint-client.lua b/src/scripts/policy-endpoint-client.lua -index e898e35..487d4b4 100644 ---- a/src/scripts/policy-endpoint-client.lua -+++ b/src/scripts/policy-endpoint-client.lua -@@ -6,7 +6,7 @@ - -- SPDX-License-Identifier: MIT - - -- Receive script arguments from config.lua --local config = ... -+local config = ... or {} - config.roles = config.roles or {} - - local self = {} -diff --git a/src/scripts/policy-endpoint-device.lua b/src/scripts/policy-endpoint-device.lua -index b726cb3..71f7772 100644 ---- a/src/scripts/policy-endpoint-device.lua -+++ b/src/scripts/policy-endpoint-device.lua -@@ -6,7 +6,7 @@ - -- SPDX-License-Identifier: MIT - - -- Receive script arguments from config.lua --local config = ... -+local config = ... or {} - - -- ensure config.move and config.follow are not nil - config.move = config.move or false -diff --git a/src/scripts/policy-node.lua b/src/scripts/policy-node.lua -index 9df5007..51a5549 100644 ---- a/src/scripts/policy-node.lua -+++ b/src/scripts/policy-node.lua -@@ -6,7 +6,7 @@ - -- SPDX-License-Identifier: MIT - - -- Receive script arguments from config.lua --local config = ... -+local config = ... or {} - - -- ensure config.move and config.follow are not nil - config.move = config.move or false --- -2.34.1 - diff --git a/_service b/_service index 41a4530..69e3b07 100644 --- a/_service +++ b/_service @@ -4,7 +4,7 @@ git https://gitlab.freedesktop.org/pipewire/wireplumber.git enable - 0.4.6 + 0.4.7 @PARENT_TAG@