Initial commit

This commit is contained in:
2026-07-02 15:56:21 +02:00
commit 4529a3c472
92 changed files with 13593 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
monitor.alsa.rules = [
{
# Sets pro audio profile for RME Fireface
matches = [
{
device.name = "alsa_card.usb-RME_Fireface_802__24240739__3A179EAE2137208-00"
}
]
actions = {
update-props = {
device.profile = "pro-audio"
}
}
}
]
@@ -0,0 +1,196 @@
-- As explained on: https://bennett.dev/auto-link-pipewire-ports-wireplumber/
--
-- This script keeps my stereo-null-sink connected to whatever output I'm currently using.
-- I do this so Pulseaudio (and Wine) always sees a stereo output plus I can swap the output
-- without needing to reconnect everything.
-- Link two ports together
function link_port(output_port, input_port)
if not input_port or not output_port then
return nil
end
local link_args = {
["link.input.node"] = input_port.properties["node.id"],
["link.input.port"] = input_port.properties["object.id"],
["link.output.node"] = output_port.properties["node.id"],
["link.output.port"] = output_port.properties["object.id"],
-- The node never got created if it didn't have this field set to something
["object.id"] = nil,
-- I was running into issues when I didn't have this set
["object.linger"] = true,
["node.description"] = "Link created by auto_connect_ports"
}
local link = Link("link-factory", link_args)
link:activate(1)
return link
end
-- Automatically link ports together by their specific audio channels.
--
-- ┌──────────────────┐ ┌───────────────────┐
-- │ │ │ │
-- │ FL ├────────►│ AUX0 │
-- │ OUTPUT │ │ │
-- │ FR ├────────►│ AUX1 INPUT │
-- │ │ │ │
-- └──────────────────┘ │ AUX2 │
-- │ │
-- └───────────────────┘
--
-- -- Call this method inside a script in global scope
--
-- auto_connect_ports {
--
-- -- A constraint for all the required ports of the output device
-- output = Constraint { "node.name"}
--
-- -- A constraint for all the required ports of the input device
-- input = Constraint { .. }
--
-- -- A mapping of output audio channels to input audio channels
--
-- connections = {
-- ["FL"] = "AUX0"
-- ["FR"] = "AUX1"
-- }
--
-- }
--
function auto_connect_ports(args)
local output_om = ObjectManager {
Interest {
type = "port",
args["output"],
Constraint { "port.direction", "equals", "out" }
}
}
local links = {}
local input_om = ObjectManager {
Interest {
type = "port",
args["input"],
Constraint { "port.direction", "equals", "in" }
}
}
local all_links = ObjectManager {
Interest {
type = "link",
}
}
local unless = nil
if args["unless"] then
unless = ObjectManager {
Interest {
type = "port",
args["unless"],
Constraint { "port.direction", "equals", "in" }
}
}
end
function _connect()
local delete_links = unless and unless:get_n_objects() > 0
if delete_links then
for _i, link in pairs(links) do
link:request_destroy()
end
links = {}
return
end
for output_name, input_names in pairs(args.connect) do
local input_names = input_names[1] == nil and { input_names } or input_names
if delete_links then
else
-- Iterate through all the output ports with the correct channel name
for output in output_om:iterate { Constraint { "audio.channel", "equals", output_name } } do
for _i, input_name in pairs(input_names) do
-- Iterate through all the input ports with the correct channel name
for input in input_om:iterate { Constraint { "audio.channel", "equals", input_name } } do
-- Link all the nodes
local link = link_port(output, input)
if link then
table.insert(links, link)
end
end
end
end
end
end
end
output_om:connect("object-added", _connect)
input_om:connect("object-added", _connect)
all_links:connect("object-added", _connect)
output_om:activate()
input_om:activate()
all_links:activate()
if unless then
unless:connect("object-added", _connect)
unless:connect("object-removed", _connect)
unless:activate()
end
end
-- Auto connect the stereo null sink to the first two channels of the RME Fireface
auto_connect_ports {
output = Constraint { "object.path", "matches", "rme-nullsink:*" },
input = Constraint { "port.alias", "matches", "Fireface 802 (24240739):*" },
connect = {
["FL"] = "AUX12",
["FR"] = "AUX13"
}
}
-- Auto connect the stereo null sink to the jack_sink for when the jack server gets started
auto_connect_ports {
output = Constraint { "object.path", "matches", "rme-nullsink:*" },
input = Constraint { "object.path", "matches", "jack_sink:*" },
connect = {
["FL"] = "FL",
["FR"] = "FR"
}
}
auto_connect_ports {
output = Constraint { "object.path", "matches", "rme-nullsink:*" },
input = Constraint { "object.path", "matches", "alsa:*" },
connect = {
["FL"] = "FL",
["FR"] = "FR"
},
-- Don't connect to speakers if there are bluetooth headphones plugged in
-- unless = Constraint { "object.path", "matches", "bluez_output.*" }
}
-- Auto connect the stereo null sink to bluetooth headphones
-- auto_connect_ports {
-- output = Constraint { "object.path", "matches", "rme-nullsink:*" },
-- input = Constraint { "object.path", "matches", "bluez_output.*" },
-- connect = {
-- -- Connect to the correct channel or "MONO" if the output is in "headset" mode
-- ["FL"] = { "FL", "MONO" },
-- ["FR"] = { "FR", "MONO" }
-- }
--}
@@ -0,0 +1,14 @@
context.objects = [
{ factory = adapter
args = {
factory.name = support.null-audio-sink
node.name = "rme-nullsink"
node.description = "RME Nullsink"
media.class = Audio/Sink
object.linger = true
audio.position = [ FL FR ]
monitor.channel-volumes = true
monitor.passthrough = true
}
}
]