Commit 4f79bccb authored by George Kiagiadakis's avatar George Kiagiadakis
Browse files

policy-endpoint: implement volume ducking

parent 07a8b503
......@@ -24,6 +24,9 @@ function default_policy.enable()
-- 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 sessions statically at startup
load_script("static-sessions.lua", default_policy.sessions)
......
......@@ -6,7 +6,7 @@ default_policy.policy.roles = {
},
["Notification"] = {
["priority"] = 20,
["action.default"] = "cork",
["action.default"] = "duck",
["action.Notification"] = "mix",
},
["Alert"] = {
......
......@@ -39,7 +39,7 @@ default_policy.policy = {
},
["Notification"] = {
["priority"] = 20,
["action.default"] = "cork",
["action.default"] = "duck",
["action.Notification"] = "mix",
},
["Alert"] = {
......@@ -59,6 +59,12 @@ function default_policy.enable()
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 sessions statically at startup
load_script("static-sessions.lua", default_policy.sessions)
......
......@@ -7,6 +7,7 @@
local config = ...
config.roles = config.roles or {}
config["duck.level"] = config["duck.level"] or 0.3
function findRole(role)
if role and not config.roles[role] then
......@@ -40,6 +41,38 @@ function getAction(dominant_role, other_role)
or "mix"
end
function restoreVolume(role, media_class)
if not mixer_api then return end
local ep = endpoints_om:lookup {
Constraint { "media.role", "=", role, type = "pw" },
Constraint { "media.class", "=", media_class, type = "pw" },
}
if ep and ep.properties["node.id"] then
Log.debug(ep, "restore role " .. role)
mixer_api:call("set-volume", ep.properties["node.id"], {
monitorVolume = 1.0,
})
end
end
function duck(role, media_class)
if not mixer_api then return end
local ep = endpoints_om:lookup {
Constraint { "media.role", "=", role, type = "pw" },
Constraint { "media.class", "=", media_class, type = "pw" },
}
if ep and ep.properties["node.id"] then
Log.debug(ep, "duck role " .. role)
mixer_api:call("set-volume", ep.properties["node.id"], {
monitorVolume = config["duck.level"],
})
end
end
function rescan()
local links = {
["Audio/Source"] = {},
......@@ -73,7 +106,7 @@ function rescan()
((l1.priority == l2.priority) and (l1.plugged > l2.plugged))
end
for k, v in pairs(links) do
for media_class, v in pairs(links) do
-- sort on priority and stream creation time
table.sort(v, compareLinks)
......@@ -90,8 +123,12 @@ function rescan()
if not v[i].active then
v[i].silink:activate(Feature.SessionItem.ACTIVE, pendingOperation())
end
-- elseif action == "duck" then
-- TODO
restoreVolume(v[i].role, media_class)
elseif action == "duck" then
if not v[i].active then
v[i].silink:activate(Feature.SessionItem.ACTIVE, pendingOperation())
end
duck(v[i].role, media_class)
else
Log.warning("Unknown action: " .. action)
end
......@@ -100,6 +137,7 @@ function rescan()
if not first_link.active then
first_link.silink:activate(Feature.SessionItem.ACTIVE, pendingOperation())
end
restoreVolume(first_link.role, media_class)
end
end
end
......@@ -134,3 +172,12 @@ silinks_om = ObjectManager {
}
silinks_om:connect("objects-changed", maybeRescan)
silinks_om:activate()
-- enable ducking if mixer-api is loaded
mixer_api = Plugin("mixer-api")
if mixer_api then
endpoints_om = ObjectManager {
Interest { type = "endpoint" },
}
endpoints_om:activate()
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment