From 9ab7c024f8dfd7158e9dcfc9895a3e1cef3c4041 Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Wed, 27 Mar 2024 19:12:10 +1000 Subject: [PATCH] node/software-dsp: get match rules from conf.d This allows DSP rules to be specified in a wireplumber.conf.d file under the node.software-dsp.rules section. Properties are specified in the software-dsp action. Signed-off-by: James Calligeros --- src/scripts/node/software-dsp.lua | 69 +++++++++++-------------------- 1 file changed, 24 insertions(+), 45 deletions(-) diff --git a/src/scripts/node/software-dsp.lua b/src/scripts/node/software-dsp.lua index 1e64dd97..cf22fcdb 100644 --- a/src/scripts/node/software-dsp.lua +++ b/src/scripts/node/software-dsp.lua @@ -5,25 +5,12 @@ -- -- SPDX-License-Identifier: MIT -local config = ... or {} -config.rules = config.rules or {} +log = Log.open_topic("s-node") -for _, r in ipairs(config.rules) do - r.interests = {} - for _, i in ipairs(r.matches) do - local interest_desc = { type = "properties" } +config = {} +config.rules = Conf.get_section_as_json("node.software-dsp.rules", Json.Array{}) - for _, c in ipairs(i) do - c.type = "pw" - table.insert(interest_desc, Constraint(c)) - end - - local interest = Interest(interest_desc) - table.insert(r.interests, interest) - end -end - --- TODO: only check for hotplug of nodes with known DSP rules +-- TODO: port from Obj Manager to Hooks nodes_om = ObjectManager { Interest { type = "node" }, } @@ -32,45 +19,37 @@ clients_om = ObjectManager { Interest { type = "client" } } -filter_chains = {} +filter_nodes = {} hidden_nodes = {} nodes_om:connect("object-added", function (om, node) - for _, r in ipairs(config.rules or {}) do - for _, interest in ipairs(r.interests) do - if interest:matches(node.properties) then - local id = node.properties["object.id"] + JsonUtils.match_rules (config.rules, node.properties, function (action, value) + if action == "create-filter" then + log:debug("DSP rule found for " .. node.properties["node.name"]) + local props = value:parse (1) - if r.filter_chain then - if filter_chains[id] then - Log.warning("Sink " .. id .. " has been plugged now, but has a filter chain loaded. Skipping") - else - filter_chains[id] = LocalModule("libpipewire-module-filter-chain", r.filter_chain, {}, true) + if props["filter-graph"] then + log:debug("Loading filter graph for " .. node.properties["node.name"]) + filter_nodes[node.properties["object.id"]] = LocalModule("libpipewire-module-filter-chain", props["filter-graph"], {}) + end + + if props["hide-parent"] then + log:debug("Setting permissions to '-' on " .. node.properties["node.name"] .. " for open clients") + for client in clients_om:iterate{ type = "client" } do + if not client["properties"]["wireplumber.daemon"] then + client:update_permissions{ [node["bound-id"]] = "-" } end end - - if r.hide_parent then - Log.debug("Hiding node " .. node["bound-id"] .. " from clients") - for client in clients_om:iterate { type = "client" } do - if not client["properties"]["wireplumber.daemon"] then - client:update_permissions { [node["bound-id"]] = "-" } - end - end - hidden_nodes[node["bound-id"]] = id - end - + hidden_nodes[node["bound-id"]] = node.properties["object.id"] end end - end + end) end) nodes_om:connect("object-removed", function (om, node) - local id = node.properties["object.id"] - if filter_chains[id] then - Log.debug("Unloading filter chain associated with sink " .. id) - filter_chains[id] = nil - else - Log.debug("Disconnected sink " .. id .. " does not have any filters to be removed") + if filter_nodes[node.properties["object.id"]] then + log:debug("Freeing filter graph on disconnected node " .. node.properties["node.name"]) + filter_nodes[node.properties["object.id"]] = nil end end)