|
#!/usr/bin/wpexec |
|
-- .config/wireplumber/scripts/policy-obs.lua |
|
|
|
|
|
-- Table of devices, and the outgoing links to other devices. |
|
-- All links are listed twice becuase we can't guarantee the order that devices will appear. |
|
-- I have an Elgato HD60 S+ that I use as an input (first item) and output to a Corsair USB headset. Update this table |
|
-- as required. |
|
node_map = { |
|
["alsa_input.usb-Elgato_Game_Capture_HD60_S__0005C0D38A000-03.iec958-stereo"] = { |
|
["capture_FL"] = { "Game:playback_FL" }, |
|
["capture_FR"] = { "Game:playback_FR" }, |
|
}, |
|
["Game"] = { |
|
["playback_FL"] = { "alsa_input.usb-Elgato_Game_Capture_HD60_S__0005C0D38A000-03.iec958-stereo:capture_FL" }, |
|
["playback_FR"] = { "alsa_input.usb-Elgato_Game_Capture_HD60_S__0005C0D38A000-03.iec958-stereo:capture_FR" }, |
|
["monitor_FL"] = { "alsa_output.usb-Corsair_CORSAIR_HS70_Pro_Wireless_Gaming_Headset-00.iec958-stereo:playback_FL" }, |
|
["monitor_FR"] = { "alsa_output.usb-Corsair_CORSAIR_HS70_Pro_Wireless_Gaming_Headset-00.iec958-stereo:playback_FR" }, |
|
}, |
|
["Chat"] = { |
|
["monitor_FL"] = { "alsa_output.usb-Corsair_CORSAIR_HS70_Pro_Wireless_Gaming_Headset-00.iec958-stereo:playback_FL" }, |
|
["monitor_FR"] = { "alsa_output.usb-Corsair_CORSAIR_HS70_Pro_Wireless_Gaming_Headset-00.iec958-stereo:playback_FR" }, |
|
}, |
|
["alsa_output.usb-Corsair_CORSAIR_HS70_Pro_Wireless_Gaming_Headset-00.iec958-stereo"] = { |
|
["playback_FL"] = { "Game:monitor_FL", "Chat:monitor_FL" }, |
|
["playback_FR"] = { "Game:monitor_FR", "Chat:monitor_FR" }, |
|
}, |
|
} |
|
|
|
-- Local table of port names to port IDs for linking |
|
ports = {} |
|
-- Table of managers to keep them alive |
|
managers = {} |
|
|
|
-- Iterate over the map |
|
for node_name, node_data in pairs(node_map) do |
|
-- Create an object manager for this node |
|
local manager = ObjectManager { |
|
Interest { |
|
type = "node", |
|
Constraint { "node.name", "equals", node_name }, |
|
}, |
|
} |
|
|
|
managers[node_name] = manager |
|
|
|
-- Add a handler for when the device is connected |
|
manager:connect("object-added", function (om, node) |
|
print("Device " .. node_name .. " found!") |
|
|
|
-- Iterate over the port list in the node_map table for this node |
|
for port_name, targets in pairs(node_data) do |
|
-- Set up the name we'll use for indexing in the ports table |
|
local port_key = node_name .. ":" .. port_name |
|
-- Create an object manager for this port |
|
local port_om = ObjectManager { |
|
Interest { |
|
type = "port", |
|
Constraint { "node.id", "equals", node.properties["object.id"] }, |
|
Constraint { "port.name", "equals", port_name }, |
|
}, |
|
} |
|
|
|
managers[port_key] = port_om |
|
|
|
print("Adding handler for port " .. port_key) |
|
|
|
-- Set up a handler for when the ports become active |
|
port_om:connect("object-added", function(om, port) |
|
print("Adding port " .. port_key .. " with ID " .. port["bound-id"]) |
|
-- Save the port ID in the table |
|
ports[port_key] = port["bound-id"] |
|
|
|
-- Iterate of the targets for this port and create the links |
|
for i, target in pairs(targets) do |
|
local target_port = ports[target] |
|
-- The remote port might not have been discovered yet |
|
if target_port then |
|
|
|
print("Linking port " .. port_key .. " to " .. target) |
|
|
|
-- Try adding the link both ways as we might be coming from the destination device. Anything incorrect will silently fail. |
|
link = Link("link-factory", { |
|
["link.output.port"] = target_port, |
|
["link.input.port"] = port["bound-id"], |
|
["object.linger"] = 1, |
|
}) |
|
link:activate(Features.ALL) |
|
|
|
link = Link("link-factory", { |
|
["link.output.port"] = port["bound-id"], |
|
["link.input.port"] = target_port, |
|
["object.linger"] = 1, |
|
}) |
|
link:activate(Features.ALL) |
|
|
|
else |
|
print("Target port " .. target .. " not found") |
|
end |
|
end |
|
end) |
|
|
|
port_om:activate() |
|
end |
|
end) |
|
|
|
manager:activate() |
|
end |