HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //usr/share/wireplumber/scripts/intended-roles.lua
-- WirePlumber
--
-- Copyright © 2021 Asymptotic
--    @author Arun Raghavan <arun@asymptotic.io>
--
-- SPDX-License-Identifier: MIT
--
-- Route streams of a given role (media.role property) to devices that are
-- intended for that role (device.intended-roles property)

metadata_om = ObjectManager {
  Interest {
    type = "metadata",
    Constraint { "metadata.name", "=", "default" },
  }
}

devices_om = ObjectManager {
  Interest {
    type = "node",
    Constraint { "media.class", "matches", "Audio/*", type = "pw-global" },
    Constraint { "device.intended-roles", "is-present", type = "pw" },
  }
}

streams_om = ObjectManager {
  Interest {
    type = "node",
    Constraint { "media.class", "matches", "Stream/*/Audio", type = "pw-global" },
    Constraint { "media.role", "is-present", type = "pw-global" }
  }
}

local function routeUsingIntendedRole(stream, dev)
  local stream_role = stream.properties["media.role"]
  local is_input = stream.properties["media.class"]:find("Input") ~= nil

  local is_source = dev.properties["media.class"]:find("Source") ~= nil
  local dev_roles = dev.properties["device.intended-roles"]

  -- Make sure the stream and device direction match
  if is_input ~= is_source then
    return
  end

  for role in dev_roles:gmatch("(%a+)") do
    if role == stream_role then
      Log.info(stream,
        string.format("Routing stream '%s' (%d) with role '%s' to '%s' (%d)",
          stream.properties["node.name"], stream["bound-id"], stream_role,
          dev.properties["node.name"], dev["bound-id"])
      )

      local metadata = metadata_om:lookup()
      metadata:set(stream["bound-id"], "target.node", "Spa:Id", dev["bound-id"])
    end
  end
end

streams_om:connect("object-added", function (streams_om, stream)
  for dev in devices_om:iterate() do
    routeUsingIntendedRole(stream, dev)
  end
end)

devices_om:connect("object-added", function (devices_om, dev)
  for stream in streams_om:iterate() do
    routeUsingIntendedRole(stream, dev)
  end
end)

metadata_om:activate()
devices_om:activate()
streams_om:activate()