From 5fb25536c716da153ba07598a0862d7ce00ed901 Mon Sep 17 00:00:00 2001
From: j1nx
Date: Sat, 3 Feb 2024 19:27:41 +0000
Subject: [PATCH] [All] Revert certain pipewire tweaks (let's start over)
---
.../etc/pipewire/client-rt.conf | 7 +-
.../rootfs-overlay/etc/pipewire/client.conf | 6 +-
.../etc/pipewire/filter-chain.conf | 63 -
.../etc/pipewire/filter-chain/demonic.conf | 64 --
.../filter-chain/sink-dolby-surround.conf | 47 -
.../etc/pipewire/filter-chain/sink-eq6.conf | 70 --
.../pipewire/filter-chain/sink-make-LFE.conf | 56 -
.../filter-chain/sink-matrix-spatialiser.conf | 42 -
.../pipewire/filter-chain/sink-mix-FL-FR.conf | 40 -
.../sink-virtual-surround-5.1-kemar.conf | 180 ---
.../sink-virtual-surround-7.1-hesuvi.conf | 104 --
.../filter-chain/source-duplicate-FL.conf | 52 -
.../pipewire/filter-chain/source-rnnoise.conf | 44 -
.../rootfs-overlay/etc/pipewire/jack.conf | 133 ---
.../rootfs-overlay/etc/pipewire/minimal.conf | 363 ------
.../etc/pipewire/pipewire-aes67.conf | 129 ---
.../etc/pipewire/pipewire-avb.conf | 73 --
.../etc/pipewire/pipewire-pulse.conf | 19 +-
.../rootfs-overlay/etc/pipewire/pipewire.conf | 76 +-
.../pipewire.conf.d/90-input-denoising.conf | 3 +-
.../etc/wireplumber/bluetooth.conf | 91 --
.../bluetooth.lua.d/00-functions.lua | 36 -
.../bluetooth.lua.d/30-bluez-midi-monitor.lua | 18 -
.../bluetooth.lua.d/30-bluez-monitor.lua | 18 -
.../bluetooth.lua.d/90-enable-all.lua | 2 -
.../etc/wireplumber/common/00-functions.lua | 36 -
.../rootfs-overlay/etc/wireplumber/main.conf | 74 --
.../wireplumber/main.lua.d/00-functions.lua | 36 -
.../main.lua.d/20-default-access.lua | 19 -
.../main.lua.d/30-alsa-monitor.lua | 29 -
.../main.lua.d/30-libcamera-monitor.lua | 14 -
.../main.lua.d/30-v4l2-monitor.lua | 14 -
.../main.lua.d/40-device-defaults.lua | 85 --
.../main.lua.d/40-stream-defaults.lua | 42 -
.../wireplumber/main.lua.d/50-alsa-config.lua | 4 +-
.../main.lua.d/50-default-access-config.lua | 36 -
.../main.lua.d/50-libcamera-config.lua | 38 -
.../wireplumber/main.lua.d/50-v4l2-config.lua | 38 -
.../wireplumber/main.lua.d/90-enable-all.lua | 26 -
.../etc/wireplumber/policy.conf | 73 --
.../wireplumber/policy.lua.d/00-functions.lua | 36 -
.../policy.lua.d/10-default-policy.lua | 98 --
.../policy.lua.d/50-endpoints-config.lua | 95 --
.../policy.lua.d/90-enable-all.lua | 1 -
.../scripts/access/access-default.lua | 53 -
.../scripts/access/access-portal.lua | 141 ---
.../etc/wireplumber/scripts/create-item.lua | 130 ---
.../etc/wireplumber/scripts/fallback-sink.lua | 93 --
.../wireplumber/scripts/intended-roles.lua | 74 --
.../scripts/monitors/alsa-midi.lua | 68 --
.../etc/wireplumber/scripts/monitors/alsa.lua | 427 -------
.../scripts/monitors/bluez-midi.lua | 187 ---
.../wireplumber/scripts/monitors/bluez.lua | 428 -------
.../scripts/monitors/libcamera.lua | 174 ---
.../etc/wireplumber/scripts/monitors/v4l2.lua | 165 ---
.../wireplumber/scripts/policy-bluetooth.lua | 398 -------
.../scripts/policy-device-profile.lua | 246 ----
.../scripts/policy-device-routes.lua | 487 --------
.../etc/wireplumber/scripts/policy-dsp.lua | 86 --
.../scripts/policy-endpoint-client-links.lua | 218 ----
.../scripts/policy-endpoint-client.lua | 261 -----
.../scripts/policy-endpoint-device.lua | 285 -----
.../etc/wireplumber/scripts/policy-node.lua | 1012 -----------------
.../wireplumber/scripts/restore-stream.lua | 499 --------
.../etc/wireplumber/scripts/sm-objects.lua | 103 --
.../wireplumber/scripts/static-endpoints.lua | 36 -
.../etc/wireplumber/scripts/suspend-node.lua | 59 -
67 files changed, 66 insertions(+), 8094 deletions(-)
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/demonic.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-dolby-surround.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-eq6.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-make-LFE.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-matrix-spatialiser.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-mix-FL-FR.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-virtual-surround-5.1-kemar.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-virtual-surround-7.1-hesuvi.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/source-duplicate-FL.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/source-rnnoise.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/jack.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/minimal.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/pipewire-aes67.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/pipewire/pipewire-avb.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/00-functions.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/30-bluez-midi-monitor.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/30-bluez-monitor.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/90-enable-all.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/common/00-functions.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/00-functions.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/20-default-access.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-alsa-monitor.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-libcamera-monitor.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-v4l2-monitor.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/40-device-defaults.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/40-stream-defaults.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-default-access-config.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-libcamera-config.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-v4l2-config.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/90-enable-all.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/policy.conf
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/00-functions.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/10-default-policy.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/50-endpoints-config.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/90-enable-all.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/access/access-default.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/access/access-portal.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/create-item.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/fallback-sink.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/intended-roles.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/alsa-midi.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/alsa.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/bluez-midi.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/bluez.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/libcamera.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/v4l2.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-bluetooth.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-device-profile.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-device-routes.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-dsp.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-client-links.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-client.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-device.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-node.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/restore-stream.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/sm-objects.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/static-endpoints.lua
delete mode 100644 buildroot-external/rootfs-overlay/etc/wireplumber/scripts/suspend-node.lua
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/client-rt.conf b/buildroot-external/rootfs-overlay/etc/pipewire/client-rt.conf
index 40ae8994..f327178e 100644
--- a/buildroot-external/rootfs-overlay/etc/pipewire/client-rt.conf
+++ b/buildroot-external/rootfs-overlay/etc/pipewire/client-rt.conf
@@ -1,4 +1,4 @@
-# Real-time Client config file for PipeWire version "0.3.81" #
+# Real-time Client config file for PipeWire version "1.0.0" #
#
# Copy and edit this file in /etc/pipewire for system-wide changes
# or in ~/.config/pipewire for local changes.
@@ -75,11 +75,11 @@ context.modules = [
]
filter.properties = {
- node.latency = 256/48000
+ #node.latency = 1024/48000
}
stream.properties = {
- node.latency = 256/48000
+ #node.latency = 1024/48000
#node.autoconnect = true
#resample.quality = 4
#channelmix.normalize = false
@@ -111,6 +111,7 @@ stream.rules = [
]
alsa.properties = {
+ #alsa.deny = false
# ALSA params take a single value, an array [] of values
# or a range { min=.. max=... }
#alsa.access = [ MMAP_INTERLEAVED MMAP_NONINTERLEAVED RW_INTERLEAVED RW_NONINTERLEAVED ]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/client.conf b/buildroot-external/rootfs-overlay/etc/pipewire/client.conf
index 1625a39e..c9d273d6 100644
--- a/buildroot-external/rootfs-overlay/etc/pipewire/client.conf
+++ b/buildroot-external/rootfs-overlay/etc/pipewire/client.conf
@@ -1,4 +1,4 @@
-# Client config file for PipeWire version "0.3.78" #
+# Client config file for PipeWire version "1.0.0" #
#
# Copy and edit this file in /etc/pipewire for system-wide changes
# or in ~/.config/pipewire for local changes.
@@ -66,11 +66,11 @@ context.modules = [
]
filter.properties = {
- node.latency = 256/48000
+ #node.latency = 1024/48000
}
stream.properties = {
- node.latency = 256/48000
+ #node.latency = 1024/48000
#node.autoconnect = true
#resample.quality = 4
#channelmix.normalize = false
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain.conf
deleted file mode 100644
index 5681a237..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain.conf
+++ /dev/null
@@ -1,63 +0,0 @@
-# Filter-chain config file for PipeWire version "0.3.81" #
-#
-# This is a base config file for running filters.
-#
-# Place filter fragments in /etc/pipewire/filter-chain.conf.d/
-# for system-wide changes or in ~/.config/pipewire/filter-chain.conf.d/
-# for local changes.
-#
-# Run the filters with pipewire -c filter-chain.conf
-#
-
-context.properties = {
- ## Configure properties in the system.
- #mem.warn-mlock = false
- #mem.allow-mlock = true
- #mem.mlock-all = false
- log.level = 0
-}
-
-context.spa-libs = {
- # =
- #
- # Used to find spa factory names. It maps an spa factory name
- # regular expression to a library name that should contain
- # that factory.
- #
- audio.convert.* = audioconvert/libspa-audioconvert
- support.* = support/libspa-support
-}
-
-context.modules = [
- #{ name =
- # ( args = { = ... } )
- # ( flags = [ ( ifexists ) ( nofail ) ] )
- # ( condition = [ { = ... } ... ] )
- #}
- #
- # Loads a module with the given parameters.
- # If ifexists is given, the module is ignored when it is not found.
- # If nofail is given, module initialization failures are ignored.
- #
- # Uses realtime scheduling to boost the audio thread priorities
- { name = libpipewire-module-rt
- args = {
- #rt.prio = 88
- #rt.time.soft = -1
- #rt.time.hard = -1
- }
- flags = [ ifexists nofail ]
- }
-
- # The native communication protocol.
- { name = libpipewire-module-protocol-native }
-
- # Allows creating nodes that run in the context of the
- # client. Is used by all clients that want to provide
- # data to PipeWire.
- { name = libpipewire-module-client-node }
-
- # Makes a factory for wrapping nodes in an adapter with a
- # converter and resampler.
- { name = libpipewire-module-adapter }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/demonic.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/demonic.conf
deleted file mode 100644
index 328085f2..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/demonic.conf
+++ /dev/null
@@ -1,64 +0,0 @@
-# filter-chain example config file for PipeWire version "0.3.81" #
-#
-# Copy this file into a conf.d/ directory such as
-# ~/.config/pipewire/filter-chain.conf.d/
-#
-context.modules = [
- { name = libpipewire-module-filter-chain
- flags = [ nofail ]
- args = {
- #audio.format = F32
- #audio.rate = 48000
- audio.channels = 2
- audio.position = [ FL FR ]
- node.description = "Demonic example"
- media.name = "Demonic example"
- filter.graph = {
- nodes = [
- {
- name = rev
- type = ladspa
- plugin = revdelay_1605
- label = revdelay
- control = {
- "Delay Time (s)" = 2.0
- }
- }
- {
- name = pitch
- type = ladspa
- plugin = am_pitchshift_1433
- label = amPitchshift
- control = {
- "Pitch shift" = 0.6
- }
- }
- {
- name = rev2
- type = ladspa
- plugin = g2reverb
- label = G2reverb
- control = {
- "Reverb tail" = 0.5
- "Damping" = 0.9
- }
- }
- ]
- links = [
- { output = "rev:Output" input = "pitch:Input" }
- { output = "pitch:Output" input = "rev2:In L" }
- ]
- inputs = [ "rev:Input" ]
- outputs = [ "rev2:Out L" ]
- }
- capture.props = {
- node.name = "effect_input.filter-chain-demonic"
- #media.class = Audio/Sink
- }
- playback.props = {
- node.name = "effect_output.filter-chain-demonic"
- #media.class = Audio/Source
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-dolby-surround.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-dolby-surround.conf
deleted file mode 100644
index f5139580..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-dolby-surround.conf
+++ /dev/null
@@ -1,47 +0,0 @@
-# Dolby Surround encoder sink
-#
-# Copy this file into a conf.d/ directory such as
-# ~/.config/pipewire/filter-chain.conf.d/
-#
-context.modules = [
- { name = libpipewire-module-filter-chain
- flags = [ nofail ]
- args = {
- node.description = "Dolby Surround Sink"
- media.name = "Dolby Surround Sink"
- filter.graph = {
- nodes = [
- {
- type = builtin
- name = mixer
- label = mixer
- control = { "Gain 1" = 0.5 "Gain 2" = 0.5 }
- }
- {
- type = ladspa
- name = enc
- plugin = surround_encoder_1401
- label = surroundEncoder
- }
- ]
- links = [
- { output = "mixer:Out" input = "enc:S" }
- ]
- inputs = [ "enc:L" "enc:R" "enc:C" null "mixer:In 1" "mixer:In 2" ]
- outputs = [ "enc:Lt" "enc:Rt" ]
- }
- capture.props = {
- node.name = "effect_input.dolby_surround"
- media.class = Audio/Sink
- audio.channels = 6
- audio.position = [ FL FR FC LFE SL SR ]
- }
- playback.props = {
- node.name = "effect_output.dolby_surround"
- node.passive = true
- audio.channels = 2
- audio.position = [ FL FR ]
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-eq6.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-eq6.conf
deleted file mode 100644
index 4cdf21b8..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-eq6.conf
+++ /dev/null
@@ -1,70 +0,0 @@
-# 6 band sink equalizer
-#
-# Copy this file into a conf.d/ directory such as
-# ~/.config/pipewire/filter-chain.conf.d/
-#
-context.modules = [
- { name = libpipewire-module-filter-chain
- args = {
- node.description = "Equalizer Sink"
- media.name = "Equalizer Sink"
- filter.graph = {
- nodes = [
- {
- type = builtin
- name = eq_band_1
- label = bq_lowshelf
- control = { "Freq" = 100.0 "Q" = 1.0 "Gain" = 0.0 }
- }
- {
- type = builtin
- name = eq_band_2
- label = bq_peaking
- control = { "Freq" = 100.0 "Q" = 1.0 "Gain" = 0.0 }
- }
- {
- type = builtin
- name = eq_band_3
- label = bq_peaking
- control = { "Freq" = 500.0 "Q" = 1.0 "Gain" = 0.0 }
- }
- {
- type = builtin
- name = eq_band_4
- label = bq_peaking
- control = { "Freq" = 2000.0 "Q" = 1.0 "Gain" = 0.0 }
- }
- {
- type = builtin
- name = eq_band_5
- label = bq_peaking
- control = { "Freq" = 5000.0 "Q" = 1.0 "Gain" = 0.0 }
- }
- {
- type = builtin
- name = eq_band_6
- label = bq_highshelf
- control = { "Freq" = 5000.0 "Q" = 1.0 "Gain" = 0.0 }
- }
- ]
- links = [
- { output = "eq_band_1:Out" input = "eq_band_2:In" }
- { output = "eq_band_2:Out" input = "eq_band_3:In" }
- { output = "eq_band_3:Out" input = "eq_band_4:In" }
- { output = "eq_band_4:Out" input = "eq_band_5:In" }
- { output = "eq_band_5:Out" input = "eq_band_6:In" }
- ]
- }
- audio.channels = 2
- audio.position = [ FL FR ]
- capture.props = {
- node.name = "effect_input.eq6"
- media.class = Audio/Sink
- }
- playback.props = {
- node.name = "effect_output.eq6"
- node.passive = true
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-make-LFE.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-make-LFE.conf
deleted file mode 100644
index 4ab770e3..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-make-LFE.conf
+++ /dev/null
@@ -1,56 +0,0 @@
-# An example filter chain that makes a stereo sink that mixes
-# the FL and FR channels to FL, FR, LFE
-#
-# Copy this file into a conf.d/ directory
-#
-context.modules = [
- { name = libpipewire-module-filter-chain
- args = {
- node.description = "LFE example"
- media.name = "LFE example"
- filter.graph = {
- nodes = [
- { name = copyIL type = builtin label = copy }
- { name = copyOL type = builtin label = copy }
- { name = copyIR type = builtin label = copy }
- { name = copyOR type = builtin label = copy }
- {
- name = mix
- type = builtin
- label = mixer
- control = {
- "Gain 1" = 0.5
- "Gain 2" = 0.5
- }
- }
- {
- type = builtin
- name = lpLFE
- label = bq_lowpass
- control = { "Freq" = 150.0 }
- }
- ]
- links = [
- { output = "copyIL:Out" input = "copyOL:In" }
- { output = "copyIR:Out" input = "copyOR:In" }
- { output = "copyIL:Out" input = "mix:In 1" }
- { output = "copyIR:Out" input = "mix:In 2" }
- { output = "mix:Out" input = "lpLFE:In" }
- ]
- inputs = [ "copyIL:In" "copyIR:In" ]
- outputs = [ "copyOL:Out" "copyOR:Out" "lpLFE:Out"]
- }
- capture.props = {
- node.name = "input_lfe"
- audio.position = [ FL FR ]
- media.class = "Audio/Sink"
- }
- playback.props = {
- node.name = "output_lfe"
- audio.position = [ FL FR LFE ]
- stream.dont-remix = true
- node.passive = true
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-matrix-spatialiser.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-matrix-spatialiser.conf
deleted file mode 100644
index b2b66eb7..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-matrix-spatialiser.conf
+++ /dev/null
@@ -1,42 +0,0 @@
-# Matrix Spatialiser sink
-#
-# Copy this file into a conf.d/ directory such as
-# ~/.config/pipewire/filter-chain.conf.d/
-#
-# ( Jean-Philippe Guillemin )
-#
-
-context.modules = [
- { name = libpipewire-module-filter-chain
- flags = [ nofail ]
- args = {
- node.description = "Matrix Spatialiser"
- media.name = "Matrix Spatialiser"
- filter.graph = {
- nodes = [
- {
- type = ladspa
- name = matrix
- plugin = matrix_spatialiser_1422
- label = matrixSpatialiser
- control = {
- "Width" = 80
- }
- }
- ]
- inputs = [ "matrix:Input L" "matrix:Input R" ]
- outputs = [ "matrix:Output L" "matrix:Output R" ]
- }
- audio.channels = 2
- audio.position = [ FL FR ]
- capture.props = {
- node.name = "effect_input.matrix_spatialiser"
- media.class = Audio/Sink
- }
- playback.props = {
- node.name = "effect_output.matrix_spatialiser"
- node.passive = true
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-mix-FL-FR.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-mix-FL-FR.conf
deleted file mode 100644
index 8288fad5..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-mix-FL-FR.conf
+++ /dev/null
@@ -1,40 +0,0 @@
-# An example filter chain that makes a stereo sink that mixes
-# the FL and FR channels to a single FL channel
-#
-# Copy this file into a conf.d/ directory such as
-# ~/.config/pipewire/filter-chain.conf.d/
-#
-context.modules = [
- { name = libpipewire-module-filter-chain
- args = {
- node.description = "Mix example"
- media.name = "Mix example"
- filter.graph = {
- nodes = [
- {
- name = mix
- type = builtin
- label = mixer
- control = {
- "Gain 1" = 0.5
- "Gain 2" = 0.5
- }
- }
- ]
- inputs = [ "mix:In 1" "mix:In 2" ]
- outputs = [ "mix:Out" ]
- }
- capture.props = {
- node.name = "mix_input.mix-FL-FR-to-FL"
- audio.position = [ FL FR ]
- media.class = "Audio/Sink"
- }
- playback.props = {
- node.name = "mix_output.mix-FL-FR-to-FL"
- audio.position = [ FL ]
- stream.dont-remix = true
- node.passive = true
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-virtual-surround-5.1-kemar.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-virtual-surround-5.1-kemar.conf
deleted file mode 100644
index ee3333d4..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-virtual-surround-5.1-kemar.conf
+++ /dev/null
@@ -1,180 +0,0 @@
-# Convolver sink
-#
-# Copy this file into a conf.d/ directory such as
-# ~/.config/pipewire/filter-chain.conf.d/
-#
-# Adjust the paths to the convolver files to match your system
-#
-context.modules = [
- { name = libpipewire-module-filter-chain
- flags = [ nofail ]
- args = {
- node.description = "Virtual Surround Sink"
- media.name = "Virtual Surround Sink"
- filter.graph = {
- nodes = [
- {
- type = builtin
- label = convolver
- name = convFL_L
- config = {
- filename = "hrir_kemar/hrir-kemar.wav"
- channel = 0
- }
- }
- {
- type = builtin
- label = convolver
- name = convFL_R
- config = {
- filename = "hrir_kemar/hrir-kemar.wav"
- channel = 1
- }
- }
- {
- type = builtin
- label = convolver
- name = convFR_L
- config = {
- filename = "hrir_kemar/hrir-kemar.wav"
- channel = 1
- }
- }
- {
- type = builtin
- label = convolver
- name = convFR_R
- config = {
- filename = "hrir_kemar/hrir-kemar.wav"
- channel = 0
- }
- }
- {
- type = builtin
- label = convolver
- name = convFC
- config = {
- filename = "hrir_kemar/hrir-kemar.wav"
- channel = 2
- }
- }
- {
- type = builtin
- label = convolver
- name = convLFE
- config = {
- filename = "hrir_kemar/hrir-kemar.wav"
- channel = 3
- }
- }
- {
- type = builtin
- label = convolver
- name = convSL_L
- config = {
- filename = "hrir_kemar/hrir-kemar.wav"
- channel = 4
- }
- }
- {
- type = builtin
- label = convolver
- name = convSL_R
- config = {
- filename = "hrir_kemar/hrir-kemar.wav"
- channel = 5
- }
- }
- {
- type = builtin
- label = convolver
- name = convSR_L
- config = {
- filename = "hrir_kemar/hrir-kemar.wav"
- channel = 5
- }
- }
- {
- type = builtin
- label = convolver
- name = convSR_R
- config = {
- filename = "hrir_kemar/hrir-kemar.wav"
- channel = 4
- }
- }
- {
- type = builtin
- label = mixer
- name = mixL
- }
- {
- type = builtin
- label = mixer
- name = mixR
- }
- {
- type = builtin
- label = copy
- name = copyFL
- }
- {
- type = builtin
- label = copy
- name = copyFR
- }
- {
- type = builtin
- label = copy
- name = copySL
- }
- {
- type = builtin
- label = copy
- name = copySR
- }
- ]
- links = [
- { output = "copyFL:Out" input = "convFL_L:In" }
- { output = "copyFL:Out" input = "convFL_R:In" }
- { output = "copyFR:Out" input = "convFR_R:In" }
- { output = "copyFR:Out" input = "convFR_L:In" }
-
- { output = "copySL:Out" input = "convSL_L:In" }
- { output = "copySL:Out" input = "convSL_R:In" }
- { output = "copySR:Out" input = "convSR_R:In" }
- { output = "copySR:Out" input = "convSR_L:In" }
-
- { output = "convFL_L:Out" input = "mixL:In 1" }
- { output = "convFR_L:Out" input = "mixL:In 2" }
- { output = "convFC:Out" input = "mixL:In 3" }
- { output = "convLFE:Out" input = "mixL:In 4" }
- { output = "convSL_L:Out" input = "mixL:In 5" }
- { output = "convSR_L:Out" input = "mixL:In 6" }
-
- { output = "convFL_R:Out" input = "mixR:In 1" }
- { output = "convFR_R:Out" input = "mixR:In 2" }
- { output = "convFC:Out" input = "mixR:In 3" }
- { output = "convLFE:Out" input = "mixR:In 4" }
- { output = "convSL_R:Out" input = "mixR:In 5" }
- { output = "convSR_R:Out" input = "mixR:In 6" }
- ]
- inputs = [ "copyFL:In" "copyFR:In" "convFC:In" "convLFE:In" "copySL:In" "copySR:In" ]
- outputs = [ "mixL:Out" "mixR:Out" ]
-
- }
- capture.props = {
- node.name = "effect_input.virtual-surround-5.1-kemar"
- media.class = Audio/Sink
- audio.channels = 6
- audio.position = [ FL FR FC LFE SL SR]
- }
- playback.props = {
- node.name = "effect_output.virtual-surround-5.1-kemar"
- node.passive = true
- audio.channels = 2
- audio.position = [ FL FR ]
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-virtual-surround-7.1-hesuvi.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-virtual-surround-7.1-hesuvi.conf
deleted file mode 100644
index 3630c23a..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/sink-virtual-surround-7.1-hesuvi.conf
+++ /dev/null
@@ -1,104 +0,0 @@
-# Convolver sink
-#
-# Copy this file into a conf.d/ directory such as
-# ~/.config/pipewire/filter-chain.conf.d/
-#
-# Adjust the paths to the convolver files to match your system
-#
-context.modules = [
- { name = libpipewire-module-filter-chain
- flags = [ nofail ]
- args = {
- node.description = "Virtual Surround Sink"
- media.name = "Virtual Surround Sink"
- filter.graph = {
- nodes = [
- # duplicate inputs
- { type = builtin label = copy name = copyFL }
- { type = builtin label = copy name = copyFR }
- { type = builtin label = copy name = copyFC }
- { type = builtin label = copy name = copyRL }
- { type = builtin label = copy name = copyRR }
- { type = builtin label = copy name = copySL }
- { type = builtin label = copy name = copySR }
- { type = builtin label = copy name = copyLFE }
-
- # apply hrir - HeSuVi 14-channel WAV (not the *-.wav variants) (note: */44/* in HeSuVi are the same, but resampled to 44100)
- { type = builtin label = convolver name = convFL_L config = { filename = "hrir_hesuvi/hrir.wav" channel = 0 } }
- { type = builtin label = convolver name = convFL_R config = { filename = "hrir_hesuvi/hrir.wav" channel = 1 } }
- { type = builtin label = convolver name = convSL_L config = { filename = "hrir_hesuvi/hrir.wav" channel = 2 } }
- { type = builtin label = convolver name = convSL_R config = { filename = "hrir_hesuvi/hrir.wav" channel = 3 } }
- { type = builtin label = convolver name = convRL_L config = { filename = "hrir_hesuvi/hrir.wav" channel = 4 } }
- { type = builtin label = convolver name = convRL_R config = { filename = "hrir_hesuvi/hrir.wav" channel = 5 } }
- { type = builtin label = convolver name = convFC_L config = { filename = "hrir_hesuvi/hrir.wav" channel = 6 } }
- { type = builtin label = convolver name = convFR_R config = { filename = "hrir_hesuvi/hrir.wav" channel = 7 } }
- { type = builtin label = convolver name = convFR_L config = { filename = "hrir_hesuvi/hrir.wav" channel = 8 } }
- { type = builtin label = convolver name = convSR_R config = { filename = "hrir_hesuvi/hrir.wav" channel = 9 } }
- { type = builtin label = convolver name = convSR_L config = { filename = "hrir_hesuvi/hrir.wav" channel = 10 } }
- { type = builtin label = convolver name = convRR_R config = { filename = "hrir_hesuvi/hrir.wav" channel = 11 } }
- { type = builtin label = convolver name = convRR_L config = { filename = "hrir_hesuvi/hrir.wav" channel = 12 } }
- { type = builtin label = convolver name = convFC_R config = { filename = "hrir_hesuvi/hrir.wav" channel = 13 } }
-
- # treat LFE as FC
- { type = builtin label = convolver name = convLFE_L config = { filename = "hrir_hesuvi/hrir.wav" channel = 6 } }
- { type = builtin label = convolver name = convLFE_R config = { filename = "hrir_hesuvi/hrir.wav" channel = 13 } }
-
- # stereo output
- { type = builtin label = mixer name = mixL }
- { type = builtin label = mixer name = mixR }
- ]
- links = [
- # input
- { output = "copyFL:Out" input="convFL_L:In" }
- { output = "copyFL:Out" input="convFL_R:In" }
- { output = "copySL:Out" input="convSL_L:In" }
- { output = "copySL:Out" input="convSL_R:In" }
- { output = "copyRL:Out" input="convRL_L:In" }
- { output = "copyRL:Out" input="convRL_R:In" }
- { output = "copyFC:Out" input="convFC_L:In" }
- { output = "copyFR:Out" input="convFR_R:In" }
- { output = "copyFR:Out" input="convFR_L:In" }
- { output = "copySR:Out" input="convSR_R:In" }
- { output = "copySR:Out" input="convSR_L:In" }
- { output = "copyRR:Out" input="convRR_R:In" }
- { output = "copyRR:Out" input="convRR_L:In" }
- { output = "copyFC:Out" input="convFC_R:In" }
- { output = "copyLFE:Out" input="convLFE_L:In" }
- { output = "copyLFE:Out" input="convLFE_R:In" }
-
- # output
- { output = "convFL_L:Out" input="mixL:In 1" }
- { output = "convFL_R:Out" input="mixR:In 1" }
- { output = "convSL_L:Out" input="mixL:In 2" }
- { output = "convSL_R:Out" input="mixR:In 2" }
- { output = "convRL_L:Out" input="mixL:In 3" }
- { output = "convRL_R:Out" input="mixR:In 3" }
- { output = "convFC_L:Out" input="mixL:In 4" }
- { output = "convFC_R:Out" input="mixR:In 4" }
- { output = "convFR_R:Out" input="mixR:In 5" }
- { output = "convFR_L:Out" input="mixL:In 5" }
- { output = "convSR_R:Out" input="mixR:In 6" }
- { output = "convSR_L:Out" input="mixL:In 6" }
- { output = "convRR_R:Out" input="mixR:In 7" }
- { output = "convRR_L:Out" input="mixL:In 7" }
- { output = "convLFE_R:Out" input="mixR:In 8" }
- { output = "convLFE_L:Out" input="mixL:In 8" }
- ]
- inputs = [ "copyFL:In" "copyFR:In" "copyFC:In" "copyLFE:In" "copyRL:In" "copyRR:In", "copySL:In", "copySR:In" ]
- outputs = [ "mixL:Out" "mixR:Out" ]
- }
- capture.props = {
- node.name = "effect_input.virtual-surround-7.1-hesuvi"
- media.class = Audio/Sink
- audio.channels = 8
- audio.position = [ FL FR FC LFE RL RR SL SR ]
- }
- playback.props = {
- node.name = "effect_output.virtual-surround-7.1-hesuvi"
- node.passive = true
- audio.channels = 2
- audio.position = [ FL FR ]
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/source-duplicate-FL.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/source-duplicate-FL.conf
deleted file mode 100644
index 7e0158f1..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/source-duplicate-FL.conf
+++ /dev/null
@@ -1,52 +0,0 @@
-# An example filter chain that makes a source that duplicates the FL channel
-# to FL and FR.
-#
-# Copy this file into a conf.d/ directory such as
-# ~/.config/pipewire/filter-chain.conf.d/
-#
-context.modules = [
- { name = libpipewire-module-filter-chain
- args = {
- node.description = "Remap example"
- media.name = "Remap example"
- filter.graph = {
- nodes = [
- {
- name = copyIL
- type = builtin
- label = copy
- }
- {
- name = copyOL
- type = builtin
- label = copy
- }
- {
- name = copyOR
- type = builtin
- label = copy
- }
- ]
- links = [
- # we can only tee from nodes, not inputs so we need
- # to copy the inputs and then tee.
- { output = "copyIL:Out" input = "copyOL:In" }
- { output = "copyIL:Out" input = "copyOR:In" }
- ]
- inputs = [ "copyIL:In" ]
- outputs = [ "copyOL:Out" "copyOR:Out" ]
- }
- capture.props = {
- node.name = "remap_input.remap-FL-to-FL-FR"
- audio.position = [ FL ]
- stream.dont-remix = true
- node.passive = true
- }
- playback.props = {
- node.name = "remap_output.remap-FL-to-FL-FR"
- audio.position = [ FL FR ]
- media.class = "Audio/Source"
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/source-rnnoise.conf b/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/source-rnnoise.conf
deleted file mode 100644
index f3c2c71b..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/filter-chain/source-rnnoise.conf
+++ /dev/null
@@ -1,44 +0,0 @@
-# Noise canceling source
-#
-# Copy this file into a conf.d/ directory such as
-# ~/.config/pipewire/filter-chain.conf.d/
-#
-# Adjust the paths to the rnnoise plugin to match your system
-#
-context.modules = [
- { name = libpipewire-module-filter-chain
- flags = [ nofail ]
- args = {
- node.description = "Noise Canceling source"
- media.name = "Noise Canceling source"
- filter.graph = {
- nodes = [
- {
- type = ladspa
- name = rnnoise
- # The path to the plugin. The suffix .so is appended to
- # this string and then the file is then located in the directories
- # listed in the environment variable LADSPA_PATH or
- # /usr/lib64/ladspa, /usr/lib/ladspa or the system library directory
- # as a fallback.
- # You might want to use an absolute path here to avoid problems.
- plugin = "librnnoise_ladspa"
- label = noise_suppressor_stereo
- control = {
- "VAD Threshold (%)" 50.0
- }
- }
- ]
- }
- audio.position = [ FL FR ]
- capture.props = {
- node.name = "effect_input.rnnoise"
- node.passive = true
- }
- playback.props = {
- node.name = "effect_output.rnnoise"
- media.class = Audio/Source
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/jack.conf b/buildroot-external/rootfs-overlay/etc/pipewire/jack.conf
deleted file mode 100644
index 9eb839f4..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/jack.conf
+++ /dev/null
@@ -1,133 +0,0 @@
-# JACK client config file for PipeWire version "0.3.81" #
-#
-# Copy and edit this file in /etc/pipewire for system-wide changes
-# or in ~/.config/pipewire for local changes.
-#
-# It is also possible to place a file with an updated section in
-# /etc/pipewire/jack.conf.d/ for system-wide changes or in
-# ~/.config/pipewire/jack.conf.d/ for local changes.
-#
-
-context.properties = {
- ## Configure properties in the system.
- #mem.warn-mlock = false
- #mem.allow-mlock = true
- #mem.mlock-all = false
- log.level = 0
-
- #default.clock.quantum-limit = 8192
-}
-
-context.spa-libs = {
- # =
- #
- # Used to find spa factory names. It maps an spa factory name
- # regular expression to a library name that should contain
- # that factory.
- #
- support.* = support/libspa-support
-}
-
-context.modules = [
- #{ name =
- # ( args = { = ... } )
- # ( flags = [ ( ifexists ) ( nofail ) ] )
- # ( condition = [ { = ... } ... ] )
- #}
- #
- # Loads a module with the given parameters.
- # If ifexists is given, the module is ignored when it is not found.
- # If nofail is given, module initialization failures are ignored.
- #
- #
- # Boost the data thread priority.
- { name = libpipewire-module-rt
- args = {
- #rt.prio = 88
- #rt.time.soft = -1
- #rt.time.hard = -1
- }
- flags = [ ifexists nofail ]
- }
-
- # The native communication protocol.
- { name = libpipewire-module-protocol-native }
-
- # Allows creating nodes that run in the context of the
- # client. Is used by all clients that want to provide
- # data to PipeWire.
- { name = libpipewire-module-client-node }
-
- # Allows applications to create metadata objects. It creates
- # a factory for Metadata objects.
- { name = libpipewire-module-metadata }
-]
-
-# global properties for all jack clients
-jack.properties = {
- #node.latency = 1024/48000
- #node.rate = 1/48000
- #node.quantum = 1024/48000
- #node.lock-quantum = true
- #node.force-quantum = 0
- #jack.show-monitor = true
- #jack.merge-monitor = true
- #jack.show-midi = true
- #jack.short-name = false
- #jack.filter-name = false
- #jack.filter-char = " "
- #
- # allow: Don't restrict self connect requests
- # fail-external: Fail self connect requests to external ports only
- # ignore-external: Ignore self connect requests to external ports only
- # fail-all: Fail all self connect requests
- # ignore-all: Ignore all self connect requests
- #jack.self-connect-mode = allow
- #jack.locked-process = true
- #jack.default-as-system = false
- #jack.fix-midi-events = true
- #jack.global-buffer-size = false
- #jack.max-client-ports = 768
- #jack.fill-aliases = false
-}
-
-# client specific properties
-jack.rules = [
- { matches = [
- {
- # all keys must match the value. ! negates. ~ starts regex.
- #client.name = "Carla"
- #application.process.binary = "jack_simple_client"
- #application.name = "~jack_simple_client.*"
- }
- ]
- actions = {
- update-props = {
- #node.latency = 512/48000
- }
- }
- }
- { matches = [ { application.process.binary = "jack_bufsize" } ]
- actions = {
- update-props = {
- jack.global-buffer-size = true # quantum set globally using metadata
- }
- }
- }
- { matches = [ { application.process.binary = "qsynth" } ]
- actions = {
- update-props = {
- node.always-process = false # makes qsynth idle
- node.pause-on-idle = false # makes audio fade out when idle
- node.passive = out # makes the sink and qsynth suspend
- }
- }
- }
- { matches = [ { client.name = "Mixxx" } ]
- actions = {
- update-props = {
- jack.merge-monitor = false
- }
- }
- }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/minimal.conf b/buildroot-external/rootfs-overlay/etc/pipewire/minimal.conf
deleted file mode 100644
index 35bcd027..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/minimal.conf
+++ /dev/null
@@ -1,363 +0,0 @@
-# Simple daemon config file for PipeWire version "0.3.81" #
-#
-# Copy and edit this file in /etc/pipewire for system-wide changes
-# or in ~/.config/pipewire for local changes.
-#
-# It is also possible to place a file with an updated section in
-# /etc/pipewire/minimal.conf.d/ for system-wide changes or in
-# ~/.config/pipewire/minimal.conf.d/ for local changes.
-#
-
-context.properties = {
- ## Configure properties in the system.
- #library.name.system = support/libspa-support
- #context.data-loop.library.name.system = support/libspa-support
- #support.dbus = true
- #link.max-buffers = 64
- link.max-buffers = 16 # version < 3 clients can't handle more
- #mem.warn-mlock = false
- #mem.allow-mlock = true
- #mem.mlock-all = false
- #clock.power-of-two-quantum = true
- #log.level = 2
- #cpu.zero.denormals = false
-
- core.daemon = true # listening for socket connections
- core.name = pipewire-0 # core name and socket name
-
- ## Properties for the DSP configuration.
- default.clock.rate = 48000
- default.clock.allowed-rates = [ 16000 22050 44100 48000 88200 96000 ]
- #default.clock.quantum = 1024
- #default.clock.min-quantum = 32
- #default.clock.max-quantum = 2048
- #default.clock.quantum-limit = 8192
- #default.video.width = 640
- #default.video.height = 480
- #default.video.rate.num = 25
- #default.video.rate.denom = 1
- #
- settings.check-quantum = true
- settings.check-rate = true
- #
- # These overrides are only applied when running in a vm.
- vm.overrides = {
- default.clock.min-quantum = 1024
- }
-}
-
-context.spa-libs = {
- # =
- #
- # Used to find spa factory names. It maps an spa factory name
- # regular expression to a library name that should contain
- # that factory.
- #
- audio.convert.* = audioconvert/libspa-audioconvert
- api.alsa.* = alsa/libspa-alsa
- support.* = support/libspa-support
-}
-
-context.modules = [
- #{ name =
- # ( args = { = ... } )
- # ( flags = [ ( ifexists ) ( nofail ) ] )
- # ( condition = [ { = ... } ... ] )
- #}
- #
- # Loads a module with the given parameters.
- # If ifexists is given, the module is ignored when it is not found.
- # If nofail is given, module initialization failures are ignored.
- #
-
- # Uses realtime scheduling to boost the audio thread priorities. This uses
- # RTKit if the user doesn't have permission to use regular realtime
- # scheduling.
- { name = libpipewire-module-rt
- args = {
- nice.level = -11
- #rt.prio = 88
- #rt.time.soft = -1
- #rt.time.hard = -1
- }
- flags = [ ifexists nofail ]
- }
-
- # The native communication protocol.
- { name = libpipewire-module-protocol-native }
-
- # The profile module. Allows application to access profiler
- # and performance data. It provides an interface that is used
- # by pw-top and pw-profiler.
- { name = libpipewire-module-profiler }
-
- # Allows applications to create metadata objects. It creates
- # a factory for Metadata objects.
- { name = libpipewire-module-metadata }
-
- # Creates a factory for making nodes that run in the
- # context of the PipeWire server.
- { name = libpipewire-module-spa-node-factory }
-
- # Allows creating nodes that run in the context of the
- # client. Is used by all clients that want to provide
- # data to PipeWire.
- { name = libpipewire-module-client-node }
-
- # The access module can perform access checks and block
- # new clients.
- { name = libpipewire-module-access
- args = {
- # access.allowed to list an array of paths of allowed
- # apps.
- #access.allowed = [
- # /usr/bin/pipewire-media-session
- #]
-
- # An array of rejected paths.
- #access.rejected = [ ]
-
- # An array of paths with restricted access.
- #access.restricted = [ ]
-
- # Anything not in the above lists gets assigned the
- # access.force permission.
- #access.force = flatpak
- }
- }
-
- # Makes a factory for wrapping nodes in an adapter with a
- # converter and resampler.
- { name = libpipewire-module-adapter }
-
- # Makes a factory for creating links between ports.
- { name = libpipewire-module-link-factory }
-]
-
-context.objects = [
- #{ factory =
- # ( args = { = ... } )
- # ( flags = [ ( nofail ) ] )
- # ( condition = [ { = ... } ... ] )
- #}
- #
- # Creates an object from a PipeWire factory with the given parameters.
- # If nofail is given, errors are ignored (and no object is created).
- #
- #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
- #{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] }
- #{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
- #{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
- #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test node.description = audiotestsrc } }
- #{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
-
- # Make a default metadata store
- { factory = metadata
- args = {
- metadata.name = default
- # metadata.values = [
- # { key = default.audio.sink value = { name = somesink } }
- # { key = default.audio.source value = { name = somesource } }
- # ]
- }
- }
-
- # A default dummy driver. This handles nodes marked with the "node.always-driver"
- # property when no other driver is currently active. JACK clients need this.
- { factory = spa-node-factory
- args = {
- factory.name = support.node.driver
- node.name = Dummy-Driver
- node.group = pipewire.dummy
- priority.driver = 20000
- }
- }
- { factory = spa-node-factory
- args = {
- factory.name = support.node.driver
- node.name = Freewheel-Driver
- priority.driver = 19000
- node.group = pipewire.freewheel
- node.freewheel = true
- }
- }
-
- # This creates a single PCM source device for the given
- # alsa device path hw:0. You can change source to sink
- # to make a sink in the same way.
- { factory = adapter
- args = {
- factory.name = api.alsa.pcm.source
- node.name = "system"
- node.description = "system"
- media.class = "Audio/Source"
- api.alsa.path = "hw:0"
- #api.alsa.period-size = 0
- #api.alsa.period-num = 0
- #api.alsa.headroom = 0
- #api.alsa.start-delay = 0
- #api.alsa.disable-mmap = false
- #api.alsa.disable-batch = false
- #api.alsa.use-chmap = false
- #api.alsa.multirate = true
- #latency.internal.rate = 0
- #latency.internal.ns = 0
- #clock.name = api.alsa.0
- node.suspend-on-idle = true
- #audio.format = "S32"
- #audio.rate = 48000
- #audio.allowed-rates = [ ]
- #audio.channels = 4
- #audio.position = [ FL FR RL RR ]
- #resample.quality = 4
- resample.disable = true
- #monitor.channel-volumes = false
- #channelmix.normalize = false
- #channelmix.mix-lfe = true
- #channelmix.upmix = true
- #channelmix.upmix-method = psd # none, simple
- #channelmix.lfe-cutoff = 150
- #channelmix.fc-cutoff = 12000
- #channelmix.rear-delay = 12.0
- #channelmix.stereo-widen = 0.0
- #channelmix.hilbert-taps = 0
- channelmix.disable = true
- #dither.noise = 0
- #node.param.Props = {
- # params = [
- # audio.channels 6
- # ]
- #}
- adapter.auto-port-config = {
- mode = dsp
- monitor = false
- control = false
- position = unknown # aux, preserve
- }
- #node.param.PortConfig = {
- # direction = Output
- # mode = dsp
- # format = {
- # mediaType = audio
- # mediaSubtype = raw
- # format = F32
- # rate = 48000
- # channels = 4
- # position = [ FL FR RL RR ]
- # }
- #}
- }
- }
- { factory = adapter
- args = {
- factory.name = api.alsa.pcm.sink
- node.name = "system"
- node.description = "system"
- media.class = "Audio/Sink"
- api.alsa.path = "hw:0"
- #api.alsa.period-size = 0
- #api.alsa.period-num = 0
- #api.alsa.headroom = 0
- #api.alsa.start-delay = 0
- #api.alsa.disable-mmap = false
- #api.alsa.disable-batch = false
- #api.alsa.use-chmap = false
- #api.alsa.multirate = true
- #latency.internal.rate = 0
- #latency.internal.ns = 0
- #clock.name = api.alsa.0
- node.suspend-on-idle = true
- #audio.format = "S32"
- #audio.rate = 48000
- #audio.allowed-rates = [ ]
- #audio.channels = 2
- #audio.position = "FL,FR"
- #resample.quality = 4
- resample.disable = true
- #channelmix.normalize = false
- #channelmix.mix-lfe = true
- #channelmix.upmix = true
- #channelmix.upmix-method = psd # none, simple
- #channelmix.lfe-cutoff = 150
- #channelmix.fc-cutoff = 12000
- #channelmix.rear-delay = 12.0
- #channelmix.stereo-widen = 0.0
- #channelmix.hilbert-taps = 0
- channelmix.disable = true
- #dither.noise = 0
- #node.param.Props = {
- # params = [
- # audio.format S16
- # ]
- #}
- adapter.auto-port-config = {
- mode = dsp
- monitor = false
- control = false
- position = unknown # aux, preserve
- }
- #node.param.PortConfig = {
- # direction = Input
- # mode = dsp
- # monitor = true
- # format = {
- # mediaType = audio
- # mediaSubtype = raw
- # format = F32
- # rate = 48000
- # channels = 4
- # }
- #}
- }
- }
- # This creates a new Source node. It will have input ports
- # that you can link, to provide audio for this source.
- #{ factory = adapter
- # args = {
- # factory.name = support.null-audio-sink
- # node.name = "my-mic"
- # node.description = "Microphone"
- # media.class = "Audio/Source/Virtual"
- # audio.position = "FL,FR"
- # adapter.auto-port-config = {
- # mode = dsp
- # monitor = true
- # position = preserve # unknown, aux, preserve
- # }
- # }
- #}
- # This creates a new link between the source and the virtual
- # source ports.
- #{ factory = link-factory
- # args = {
- # link.output.node = system
- # link.output.port = capture_1
- # link.input.node = my-mic
- # link.input.port = input_FL
- # }
- #}
- #{ factory = link-factory
- # args = {
- # link.output.node = system
- # link.output.port = capture_2
- # link.input.node = my-mic
- # link.input.port = input_FR
- # }
- #}
-]
-
-context.exec = [
- #{ path =
- # ( args = "" )
- # ( condition = [ { = ... } ... ] )
- #}
- #
- # Execute the given program with arguments.
- #
- # You can optionally start the pulseaudio-server here as well
- # but it is better to start it as a systemd service.
- # It can be interesting to start another daemon here that listens
- # on another address with the -a option (eg. -a tcp:4713).
- #
- ##{ path = "/usr/bin/pipewire" args = "-c pipewire-pulse.conf" }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/pipewire-aes67.conf b/buildroot-external/rootfs-overlay/etc/pipewire/pipewire-aes67.conf
deleted file mode 100644
index cdb18b95..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/pipewire-aes67.conf
+++ /dev/null
@@ -1,129 +0,0 @@
-# AES67 config file for PipeWire version "0.3.81" #
-#
-# Copy and edit this file in /etc/pipewire for system-wide changes
-# or in ~/.config/pipewire for local changes.
-#
-# It is also possible to place a file with an updated section in
-# /etc/pipewire/pipewire-aes67.conf.d/ for system-wide changes or in
-# ~/.config/pipewire/pipewire-aes67.conf.d/ for local changes.
-#
-
-context.properties = {
- ## Configure properties in the system.
- #mem.warn-mlock = false
- #mem.allow-mlock = true
- #mem.mlock-all = false
- #log.level = 2
-
- #default.clock.quantum-limit = 8192
-}
-
-context.spa-libs = {
- support.* = support/libspa-support
-}
-
-context.objects = [
- # An example clock reading from /dev/ptp0. Another option is to sync the
- # ptp clock to CLOCK_TAI and then set clock.id = tai.
- # If both device and ID are given and available, device takes precedence
- { factory = spa-node-factory
- args = {
- factory.name = support.node.driver
- node.name = PTP0-Driver
- node.group = pipewire.ptp0
- # This driver should only be used for network nodes marked with group
- priority.driver = 0
- clock.name = "clock.system.ptp0"
- clock.device = "/dev/ptp0"
- clock.id = tai
- object.export = true
- }
- }
-]
-
-context.modules = [
- { name = libpipewire-module-rt
- args = {
- nice.level = -11
- #rt.prio = 88
- #rt.time.soft = -1
- #rt.time.hard = -1
- }
- flags = [ ifexists nofail ]
- }
- { name = libpipewire-module-protocol-native }
- { name = libpipewire-module-client-node }
- { name = libpipewire-module-spa-node-factory }
- { name = libpipewire-module-adapter }
- { name = libpipewire-module-rtp-sap
- args = {
- local.ifname = eth0
- sap.ip = 239.255.255.255
- sap.port = 9875
- net.ttl = 32
- net.loop = true
-
- stream.rules = [
- {
- matches = [
- {
- rtp.session = "~.*"
- }
- ]
- actions = {
- create-stream = {
- node.virtual = false
- media.class = "Audio/Source"
- device.api = aes67
- sess.latency.msec = 10
- node.group = pipewire.ptp0
- }
- }
- },
- {
- matches = [
- {
- sess.sap.announce = true
- }
- ]
- actions = {
- announce-stream = {}
- }
- }
- ]
- }
- },
- { name = libpipewire-module-rtp-sink
- args = {
- local.ifname = eth0
- destination.ip = 239.69.150.243
- destination.port = 5004
- net.mtu = 1280
- net.ttl = 32
- net.loop = true
- sess.min-ptime = 1
- sess.max-ptime = 1
- sess.name = "PipeWire RTP stream"
- sess.media = "audio"
- sess.ts-refclk = "ptp=traceable"
- sess.ts-offset = 0
- sess.ptime = 1
- sess.latency.msec = 1
- sess.announce = true
- audio.format = "S24BE"
- audio.rate = 48000
- audio.channels = 2
- audio.position = [ FL FR ]
-
- stream.props = {
- node.name = "rtp-sink"
- media.class = "Audio/Sink"
- node.virtual = false
- device.api = aes67
- sess.sap.announce = true
- node.always-process = true
- node.group = pipewire.ptp0
- }
- }
- },
-]
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/pipewire-avb.conf b/buildroot-external/rootfs-overlay/etc/pipewire/pipewire-avb.conf
deleted file mode 100644
index 0f172ac2..00000000
--- a/buildroot-external/rootfs-overlay/etc/pipewire/pipewire-avb.conf
+++ /dev/null
@@ -1,73 +0,0 @@
-# PulseAudio config file for PipeWire version "0.3.81" #
-#
-# Copy and edit this file in /etc/pipewire for system-wide changes
-# or in ~/.config/pipewire for local changes.
-#
-# It is also possible to place a file with an updated section in
-# /etc/pipewire/pipewire-pulse.conf.d/ for system-wide changes or in
-# ~/.config/pipewire/pipewire-pulse.conf.d/ for local changes.
-#
-
-context.properties = {
- ## Configure properties in the system.
- #mem.warn-mlock = false
- #mem.allow-mlock = true
- #mem.mlock-all = false
- #log.level = 2
-
- #default.clock.quantum-limit = 8192
-}
-
-context.spa-libs = {
- audio.convert.* = audioconvert/libspa-audioconvert
- support.* = support/libspa-support
-}
-
-context.modules = [
- { name = libpipewire-module-rt
- args = {
- nice.level = -11
- #rt.prio = 88
- #rt.time.soft = -1
- #rt.time.hard = -1
- }
- flags = [ ifexists nofail ]
- }
- { name = libpipewire-module-protocol-native }
- { name = libpipewire-module-client-node }
- { name = libpipewire-module-adapter }
- { name = libpipewire-module-avb
- args = {
- # contents of avb.properties can also be placed here
- # to have config per server.
- }
- }
-]
-
-# Extra modules can be loaded here. Setup in default.pa can be moved here
-context.exec = [
- #{ path = "pactl" args = "load-module module-always-sink" }
-]
-
-stream.properties = {
- #node.latency = 1024/48000
- #node.autoconnect = true
- #resample.quality = 4
- #channelmix.normalize = false
- #channelmix.mix-lfe = true
- #channelmix.upmix = true
- #channelmix.lfe-cutoff = 120
- #channelmix.fc-cutoff = 6000
- #channelmix.rear-delay = 12.0
- #channelmix.stereo-widen = 0.1
- #channelmix.hilbert-taps = 0
-}
-
-avb.properties = {
- # the addresses this server listens on
- #ifname = "eth0.2"
- ifname = "enp3s0"
- # These overrides are only applied when running in a vm.
- vm.overrides = {
- }
-}
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/pipewire-pulse.conf b/buildroot-external/rootfs-overlay/etc/pipewire/pipewire-pulse.conf
index e4a505ee..3ba92451 100644
--- a/buildroot-external/rootfs-overlay/etc/pipewire/pipewire-pulse.conf
+++ b/buildroot-external/rootfs-overlay/etc/pipewire/pipewire-pulse.conf
@@ -1,4 +1,4 @@
-# PulseAudio config file for PipeWire version "0.3.78" #
+# PulseAudio config file for PipeWire version "1.0.0" #
#
# Copy and edit this file in /etc/pipewire for system-wide changes
# or in ~/.config/pipewire for local changes.
@@ -27,9 +27,12 @@ context.modules = [
{ name = libpipewire-module-rt
args = {
nice.level = -19
+ #rt.prio = 88
rt.prio = 95
#rt.time.soft = -1
#rt.time.hard = -1
+ #uclamp.min = 0
+ #uclamp.max = 1024
}
flags = [ ifexists nofail ]
}
@@ -42,16 +45,6 @@ context.modules = [
args = {
# contents of pulse.properties can also be placed here
# to have config per server.
- pulse.min.req = "256/48000"
- pulse.default.req = "256/48000"
- pulse.max.req = "256/48000"
- pulse.min.quantum = "256/48000"
- pulse.max.quantum = "256/48000"
- pulse.min.req = "256/48000"
- pulse.default.req = "256/48000"
- pulse.max.req = "256/48000"
- pulse.min.quantum = "256/48000"
- pulse.max.quantum = "256/48000"
}
}
]
@@ -75,7 +68,7 @@ pulse.cmd = [
]
stream.properties = {
- node.latency = 256/48000
+ #node.latency = 1024/48000
#node.autoconnect = true
#resample.quality = 4
#channelmix.normalize = false
@@ -126,7 +119,7 @@ pulse.rules = [
{
matches = [
{
- # all keys must match the value. ~ starts regex.
+ # all keys must match the value. ! negates. ~ starts regex.
#client.name = "Firefox"
#application.process.binary = "teams"
#application.name = "~speech-dispatcher.*"
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/pipewire.conf b/buildroot-external/rootfs-overlay/etc/pipewire/pipewire.conf
index 5dbaec21..a50062fc 100644
--- a/buildroot-external/rootfs-overlay/etc/pipewire/pipewire.conf
+++ b/buildroot-external/rootfs-overlay/etc/pipewire/pipewire.conf
@@ -1,4 +1,4 @@
-# Daemon config file for PipeWire version "0.3.78" #
+# Daemon config file for PipeWire version "1.0.0" #
#
# Copy and edit this file in /etc/pipewire for system-wide changes
# or in ~/.config/pipewire for local changes.
@@ -26,11 +26,11 @@ context.properties = {
core.name = pipewire-0 # core name and socket name
## Properties for the DSP configuration.
- default.clock.rate = 48000
- default.clock.allowed-rates = [ 48000 ]
- default.clock.quantum = 256
- default.clock.min-quantum = 64
- default.clock.max-quantum = 512
+ #default.clock.rate = 48000
+ #default.clock.allowed-rates = [ 48000 ]
+ #default.clock.quantum = 1024
+ #default.clock.min-quantum = 32
+ #default.clock.max-quantum = 2048
#default.clock.quantum-limit = 8192
#default.video.width = 640
#default.video.height = 480
@@ -50,6 +50,8 @@ context.properties = {
# enables autoloading of access module, when disabled an alternative
# access module needs to be loaded.
module.access = true
+ # enables autoloading of module-jackdbus-detect
+ module.jackdbus-detect = true
}
context.spa-libs = {
@@ -88,19 +90,27 @@ context.modules = [
# Uses realtime scheduling to boost the audio thread priorities. This uses
# RTKit if the user doesn't have permission to use regular realtime
- # scheduling.
+ # scheduling. You can also clamp utilisation values to improve scheduling
+ # on embedded and heterogeneous systems, e.g. Arm big.LITTLE devices.
{ name = libpipewire-module-rt
args = {
- nice.level = -19
- rt.prio = 95
+ nice.level = -19
+ rt.prio = 95
#rt.time.soft = -1
#rt.time.hard = -1
+ #uclamp.min = 0
+ #uclamp.max = 1024
}
flags = [ ifexists nofail ]
}
# The native communication protocol.
- { name = libpipewire-module-protocol-native }
+ { name = libpipewire-module-protocol-native
+ args = {
+ # List of server Unix sockets, and optionally permissions
+ #sockets = [ { name = "pipewire-0" }, { name = "pipewire-0-manager" } ]
+ }
+ }
# The profile module. Allows application to access profiler
# and performance data. It provides an interface that is used
@@ -139,21 +149,12 @@ context.modules = [
# new clients.
{ name = libpipewire-module-access
args = {
- # access.allowed to list an array of paths of allowed
- # apps.
- #access.allowed = [
- # /usr/bin/pipewire-media-session
- #]
+ # Socket-specific access permissions
+ #access.socket = { pipewire-0 = "default", pipewire-0-manager = "unrestricted" }
- # An array of rejected paths.
- #access.rejected = [ ]
-
- # An array of paths with restricted access.
- #access.restricted = [ ]
-
- # Anything not in the above lists gets assigned the
- # access.force permission.
- #access.force = flatpak
+ # Deprecated legacy mode (not socket-based),
+ # for now enabled by default if access.socket is not specified
+ #access.legacy = true
}
condition = [ { module.access = true } ]
}
@@ -179,6 +180,29 @@ context.modules = [
flags = [ ifexists nofail ]
condition = [ { module.x11.bell = true } ]
}
+ { name = libpipewire-module-jackdbus-detect
+ args = {
+ #jack.library = libjack.so.0
+ #jack.server = null
+ #jack.client-name = PipeWire
+ #jack.connect = true
+ #tunnel.mode = duplex # source|sink|duplex
+ source.props = {
+ #audio.channels = 2
+ #midi.ports = 1
+ #audio.position = [ FL FR ]
+ # extra sink properties
+ }
+ sink.props = {
+ #audio.channels = 2
+ #midi.ports = 1
+ #audio.position = [ FL FR ]
+ # extra sink properties
+ }
+ }
+ flags = [ ifexists nofail ]
+ condition = [ { module.jackdbus-detect = true } ]
+ }
]
context.objects = [
@@ -193,11 +217,11 @@ context.objects = [
# If condition is given, the object is created only when the context properties
# all match the match rules.
#
- #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
+ #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } }
#{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] }
#{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
#{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
- #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test } }
+ #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test node.description = audiotestsrc } }
#{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
# A default dummy driver. This handles nodes marked with the "node.always-driver"
diff --git a/buildroot-external/rootfs-overlay/etc/pipewire/pipewire.conf.d/90-input-denoising.conf b/buildroot-external/rootfs-overlay/etc/pipewire/pipewire.conf.d/90-input-denoising.conf
index 3d2270c8..f8dcceee 100644
--- a/buildroot-external/rootfs-overlay/etc/pipewire/pipewire.conf.d/90-input-denoising.conf
+++ b/buildroot-external/rootfs-overlay/etc/pipewire/pipewire.conf.d/90-input-denoising.conf
@@ -10,7 +10,7 @@ context.modules = [
type = ladspa
name = rnnoise
plugin = /usr/lib/ladspa/librnnoise_ladspa.so
- label = noise_suppressor_mono
+ label = noise_suppressor_stereo
control = {
"VAD Threshold (%)" 85.0
"VAD Grace Period (ms)" = 200
@@ -27,7 +27,6 @@ context.modules = [
playback.props = {
node.name = "openvoiceos_denoised_mic"
media.class = Audio/Source
- audio.rate = 48000
}
}
}
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.conf b/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.conf
deleted file mode 100644
index e4d666d1..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.conf
+++ /dev/null
@@ -1,91 +0,0 @@
-# WirePlumber daemon context configuration #
-
-context.properties = {
- ## Properties to configure the PipeWire context and some modules
-
- application.name = "WirePlumber Bluetooth"
- log.level = 2
- wireplumber.script-engine = lua-scripting
- wireplumber.export-core = true
-
- #mem.mlock-all = false
- #support.dbus = true
-}
-
-context.spa-libs = {
- # =
- #
- # Used to find spa factory names. It maps an spa factory name
- # regular expression to a library name that should contain
- # that factory.
- #
- api.bluez5.* = bluez5/libspa-bluez5
- audio.convert.* = audioconvert/libspa-audioconvert
- support.* = support/libspa-support
-}
-
-context.modules = [
- #{ name =
- # [ args = { = ... } ]
- # [ flags = [ [ ifexists ] [ nofail ] ]
- #}
- #
- # PipeWire modules to load.
- # If ifexists is given, the module is ignored when it is not found.
- # If nofail is given, module initialization failures are ignored.
- #
-
- # Uses RTKit to boost the data thread priority. Also allows clamping
- # of utilisation when using the Completely Fair Scheduler on Linux.
- { name = libpipewire-module-rt
- args = {
- nice.level = -11
- #rt.prio = 88
- #rt.time.soft = -1
- #rt.time.hard = -1
- #uclamp.min = 0
- #uclamp.max = 1024
- }
- flags = [ ifexists nofail ]
- }
-
- # The native communication protocol.
- { name = libpipewire-module-protocol-native }
-
- # Allows creating nodes that run in the context of the
- # client. Is used by all clients that want to provide
- # data to PipeWire.
- { name = libpipewire-module-client-node }
-
- # Allows creating devices that run in the context of the
- # client. Is used by the session manager.
- { name = libpipewire-module-client-device }
-
- # Makes a factory for wrapping nodes in an adapter with a
- # converter and resampler.
- { name = libpipewire-module-adapter }
-
- # Allows applications to create metadata objects. It creates
- # a factory for Metadata objects.
- { name = libpipewire-module-metadata }
-
- # Provides factories to make session manager objects.
- { name = libpipewire-module-session-manager }
-
- # Provides factories to make SPA node objects.
- { name = libpipewire-module-spa-node-factory }
-]
-
-wireplumber.components = [
- #{ name = , type = }
- #
- # WirePlumber components to load
- #
-
- # The lua scripting engine
- { name = libwireplumber-module-lua-scripting, type = module }
-
- # The lua configuration file
- # Other components are loaded from there
- { name = bluetooth.lua, type = config/lua }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/00-functions.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/00-functions.lua
deleted file mode 100644
index 451ad4f5..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/00-functions.lua
+++ /dev/null
@@ -1,36 +0,0 @@
-components = {}
-
-function load_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libwireplumber-module-" .. m, type = "module", args = a }
- end
-end
-
-function load_optional_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libwireplumber-module-" .. m, type = "module", args = a, optional = true }
- end
-end
-
-function load_pw_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libpipewire-module-" .. m, type = "pw_module", args = a }
- end
-end
-
-function load_script(s, a)
- if not components[s] then
- components[s] = { s, type = "script/lua", args = a }
- end
-end
-
-function load_monitor(s, a)
- load_script("monitors/" .. s .. ".lua", a)
-end
-
-function load_access(s, a)
- load_script("access/access-" .. s .. ".lua", a)
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/30-bluez-midi-monitor.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/30-bluez-midi-monitor.lua
deleted file mode 100644
index 839ec108..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/30-bluez-midi-monitor.lua
+++ /dev/null
@@ -1,18 +0,0 @@
-bluez_midi_monitor = {}
-bluez_midi_monitor.properties = {}
-bluez_midi_monitor.rules = {}
-
-function bluez_midi_monitor.enable()
- if bluez_midi_monitor.enabled == false then
- return
- end
-
- load_monitor("bluez-midi", {
- properties = bluez_midi_monitor.properties,
- rules = bluez_midi_monitor.rules,
- })
-
- if bluez_midi_monitor.properties["with-logind"] then
- load_optional_module("logind")
- end
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/30-bluez-monitor.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/30-bluez-monitor.lua
deleted file mode 100644
index a870aa5d..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/30-bluez-monitor.lua
+++ /dev/null
@@ -1,18 +0,0 @@
-bluez_monitor = {}
-bluez_monitor.properties = {}
-bluez_monitor.rules = {}
-
-function bluez_monitor.enable()
- if bluez_monitor.enabled == false then
- return
- end
-
- load_monitor("bluez", {
- properties = bluez_monitor.properties,
- rules = bluez_monitor.rules,
- })
-
- if bluez_monitor.properties["with-logind"] then
- load_optional_module("logind")
- end
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/90-enable-all.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/90-enable-all.lua
deleted file mode 100644
index efa6bf54..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/bluetooth.lua.d/90-enable-all.lua
+++ /dev/null
@@ -1,2 +0,0 @@
-bluez_monitor.enable()
-bluez_midi_monitor.enable()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/common/00-functions.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/common/00-functions.lua
deleted file mode 100644
index 451ad4f5..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/common/00-functions.lua
+++ /dev/null
@@ -1,36 +0,0 @@
-components = {}
-
-function load_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libwireplumber-module-" .. m, type = "module", args = a }
- end
-end
-
-function load_optional_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libwireplumber-module-" .. m, type = "module", args = a, optional = true }
- end
-end
-
-function load_pw_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libpipewire-module-" .. m, type = "pw_module", args = a }
- end
-end
-
-function load_script(s, a)
- if not components[s] then
- components[s] = { s, type = "script/lua", args = a }
- end
-end
-
-function load_monitor(s, a)
- load_script("monitors/" .. s .. ".lua", a)
-end
-
-function load_access(s, a)
- load_script("access/access-" .. s .. ".lua", a)
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.conf b/buildroot-external/rootfs-overlay/etc/wireplumber/main.conf
deleted file mode 100644
index e822f020..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.conf
+++ /dev/null
@@ -1,74 +0,0 @@
-# WirePlumber daemon context configuration #
-
-context.properties = {
- ## Properties to configure the PipeWire context and some modules
-
- #application.name = WirePlumber
- log.level = 2
- wireplumber.script-engine = lua-scripting
-
- #mem.mlock-all = false
- #support.dbus = true
-}
-
-context.spa-libs = {
- # =
- #
- # Used to find spa factory names. It maps an spa factory name
- # regular expression to a library name that should contain
- # that factory.
- #
- api.alsa.* = alsa/libspa-alsa
- api.v4l2.* = v4l2/libspa-v4l2
- audio.convert.* = audioconvert/libspa-audioconvert
- support.* = support/libspa-support
-}
-
-context.modules = [
- #{ name =
- # [ args = { = ... } ]
- # [ flags = [ [ ifexists ] [ nofail ] ]
- #}
- #
- # PipeWire modules to load.
- # If ifexists is given, the module is ignored when it is not found.
- # If nofail is given, module initialization failures are ignored.
- #
-
- # The native communication protocol.
- { name = libpipewire-module-protocol-native }
-
- # Allows creating nodes that run in the context of the
- # client. Is used by all clients that want to provide
- # data to PipeWire.
- { name = libpipewire-module-client-node }
-
- # Allows creating devices that run in the context of the
- # client. Is used by the session manager.
- { name = libpipewire-module-client-device }
-
- # Makes a factory for wrapping nodes in an adapter with a
- # converter and resampler.
- { name = libpipewire-module-adapter }
-
- # Allows applications to create metadata objects. It creates
- # a factory for Metadata objects.
- { name = libpipewire-module-metadata }
-
- # Provides factories to make session manager objects.
- { name = libpipewire-module-session-manager }
-]
-
-wireplumber.components = [
- #{ name = , type = }
- #
- # WirePlumber components to load
- #
-
- # The lua scripting engine
- { name = libwireplumber-module-lua-scripting, type = module }
-
- # The lua configuration file
- # Other components are loaded from there
- { name = main.lua, type = config/lua }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/00-functions.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/00-functions.lua
deleted file mode 100644
index 451ad4f5..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/00-functions.lua
+++ /dev/null
@@ -1,36 +0,0 @@
-components = {}
-
-function load_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libwireplumber-module-" .. m, type = "module", args = a }
- end
-end
-
-function load_optional_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libwireplumber-module-" .. m, type = "module", args = a, optional = true }
- end
-end
-
-function load_pw_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libpipewire-module-" .. m, type = "pw_module", args = a }
- end
-end
-
-function load_script(s, a)
- if not components[s] then
- components[s] = { s, type = "script/lua", args = a }
- end
-end
-
-function load_monitor(s, a)
- load_script("monitors/" .. s .. ".lua", a)
-end
-
-function load_access(s, a)
- load_script("access/access-" .. s .. ".lua", a)
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/20-default-access.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/20-default-access.lua
deleted file mode 100644
index 0a7eb955..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/20-default-access.lua
+++ /dev/null
@@ -1,19 +0,0 @@
-default_access = {}
-default_access.properties = {}
-default_access.rules = {}
-
-function default_access.enable()
- if default_access.enabled == false then
- return
- end
-
- load_access("default", {
- rules = default_access.rules
- })
-
- if default_access.properties["enable-flatpak-portal"] then
- -- Enables portal permissions via org.freedesktop.impl.portal.PermissionStore
- load_module("portal-permissionstore")
- load_access("portal")
- end
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-alsa-monitor.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-alsa-monitor.lua
deleted file mode 100644
index 8e45e434..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-alsa-monitor.lua
+++ /dev/null
@@ -1,29 +0,0 @@
-alsa_monitor = {}
-alsa_monitor.properties = {}
-alsa_monitor.rules = {}
-
-function alsa_monitor.enable()
- if alsa_monitor.enabled == false then
- return
- end
-
- -- The "reserve-device" module needs to be loaded for reservation to work
- if alsa_monitor.properties["alsa.reserve"] then
- load_module("reserve-device")
- end
-
- load_monitor("alsa", {
- properties = alsa_monitor.properties,
- rules = alsa_monitor.rules,
- })
-
- if alsa_monitor.properties["alsa.midi"] then
- load_monitor("alsa-midi", {
- properties = alsa_monitor.properties,
- })
- -- The "file-monitor-api" module needs to be loaded for MIDI device monitoring
- if alsa_monitor.properties["alsa.midi.monitoring"] then
- load_module("file-monitor-api")
- end
- end
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-libcamera-monitor.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-libcamera-monitor.lua
deleted file mode 100644
index cd820a83..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-libcamera-monitor.lua
+++ /dev/null
@@ -1,14 +0,0 @@
-libcamera_monitor = {}
-libcamera_monitor.properties = {}
-libcamera_monitor.rules = {}
-
-function libcamera_monitor.enable()
- if libcamera_monitor.enabled == false then
- return
- end
-
- load_monitor("libcamera", {
- properties = libcamera_monitor.properties,
- rules = libcamera_monitor.rules,
- })
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-v4l2-monitor.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-v4l2-monitor.lua
deleted file mode 100644
index 3fbdc9e7..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/30-v4l2-monitor.lua
+++ /dev/null
@@ -1,14 +0,0 @@
-v4l2_monitor = {}
-v4l2_monitor.properties = {}
-v4l2_monitor.rules = {}
-
-function v4l2_monitor.enable()
- if v4l2_monitor.enabled == false then
- return
- end
-
- load_monitor("v4l2", {
- properties = v4l2_monitor.properties,
- rules = v4l2_monitor.rules,
- })
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/40-device-defaults.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/40-device-defaults.lua
deleted file mode 100644
index 19202914..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/40-device-defaults.lua
+++ /dev/null
@@ -1,85 +0,0 @@
-device_defaults = {}
-device_defaults.enabled = true
-
-device_defaults.properties = {
- -- store preferences to the file system and restore them at startup;
- -- when set to false, default nodes and routes are selected based on
- -- their priorities and any runtime changes do not persist after restart
- ["use-persistent-storage"] = true,
-
- -- the default volumes to apply to ACP device nodes, in the linear scale
- --["default-volume"] = 0.064,
- --["default-input-volume"] = 1.0,
-
- -- Whether to auto-switch to echo cancel sink and source nodes or not
- ["auto-echo-cancel"] = true,
-
- -- Sets the default echo-cancel-sink node name to automatically switch to
- ["echo-cancel-sink-name"] = "echo-cancel-sink",
-
- -- Sets the default echo-cancel-source node name to automatically switch to
- ["echo-cancel-source-name"] = "echo-cancel-source",
-}
-
--- Sets persistent device profiles that should never change when wireplumber is
--- running, even if a new profile with higher priority becomes available
-device_defaults.persistent_profiles = {
- {
- matches = {
- {
- -- Matches all devices
- { "device.name", "matches", "*" },
- },
- },
- profile_names = {
- "off",
- "pro-audio"
- }
- },
-}
-
-device_defaults.profile_priorities = {
- {
- matches = {
- {
- -- Matches all bluez devices
- { "device.name", "matches", "bluez_card.*" },
- },
- },
- -- lower the index higher the priority
- priorities = {
- -- "a2dp-sink-sbc",
- -- "a2dp-sink-aptx_ll",
- -- "a2dp-sink-aptx",
- -- "a2dp-sink-aptx_hd",
- -- "a2dp-sink-ldac",
- -- "a2dp-sink-aac",
- -- "a2dp-sink-sbc_xq",
- }
- },
-}
-
-function device_defaults.enable()
- if device_defaults.enabled == false then
- return
- end
-
- -- Selects appropriate default nodes and enables saving and restoring them
- load_module("default-nodes", device_defaults.properties)
-
- -- Selects appropriate profile for devices
- load_script("policy-device-profile.lua", {
- persistent = device_defaults.persistent_profiles,
- priorities = device_defaults.profile_priorities
- })
-
- -- Selects appropriate device routes ("ports" in pulseaudio terminology)
- -- and enables saving and restoring them together with
- -- their properties (per-route/port volume levels, channel maps, etc)
- load_script("policy-device-routes.lua", device_defaults.properties)
-
- if device_defaults.properties["use-persistent-storage"] then
- -- Enables functionality to save and restore default device profiles
- load_module("default-profile")
- end
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/40-stream-defaults.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/40-stream-defaults.lua
deleted file mode 100644
index b869099b..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/40-stream-defaults.lua
+++ /dev/null
@@ -1,42 +0,0 @@
-stream_defaults = {}
-stream_defaults.enabled = true
-
-stream_defaults.properties = {
- -- whether to restore the last stream properties or not
- ["restore-props"] = true,
-
- -- whether to restore the last stream target or not
- ["restore-target"] = true,
-
- -- the default channel volume for new streams whose props were never saved
- -- previously. This is only used if "restore-props" is set to true.
- ["default-channel-volume"] = 1.0,
-}
-
-stream_defaults.rules = {
- -- Rules to override settings per node
- -- {
- -- matches = {
- -- {
- -- { "application.name", "matches", "pw-play" },
- -- },
- -- },
- -- apply_properties = {
- -- ["state.restore-props"] = false,
- -- ["state.restore-target"] = false,
- -- ["state.default-channel-volume"] = 0.5,
- -- },
- -- },
-}
-
-function stream_defaults.enable()
- if stream_defaults.enabled == false then
- return
- end
-
- -- Save and restore stream-specific properties
- load_script("restore-stream.lua", {
- properties = stream_defaults.properties,
- rules = stream_defaults.rules,
- })
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-alsa-config.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-alsa-config.lua
index 315cd1bf..f37949d9 100644
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-alsa-config.lua
+++ b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-alsa-config.lua
@@ -140,8 +140,8 @@ alsa_monitor.rules = {
--["audio.rate"] = 44100,
--["audio.allowed-rates"] = "32000,96000",
--["audio.position"] = "FL,FR",
- ["api.alsa.period-size"] = 256,
- ["api.alsa.period-num"] = 3,
+ --["api.alsa.period-size"] = 256,
+ --["api.alsa.period-num"] = 3,
--["api.alsa.headroom"] = 0,
--["api.alsa.start-delay"] = 0,
--["api.alsa.disable-mmap"] = false,
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-default-access-config.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-default-access-config.lua
deleted file mode 100644
index 4ad3d57a..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-default-access-config.lua
+++ /dev/null
@@ -1,36 +0,0 @@
-default_access.enabled = true
-
-default_access.properties = {
- -- Enable the use of the flatpak portal integration.
- -- Disable if you are running a system-wide instance, which
- -- doesn't have access to the D-Bus user session
- ["enable-flatpak-portal"] = true,
-}
-
-default_access.rules = {
- {
- matches = {
- {
- { "pipewire.access", "=", "flatpak" },
- { "media.category", "=", "Manager" },
- },
- },
- default_permissions = "all",
- },
- {
- matches = {
- {
- { "pipewire.access", "=", "flatpak" },
- },
- },
- default_permissions = "rx",
- },
- {
- matches = {
- {
- { "pipewire.access", "=", "restricted" },
- },
- },
- default_permissions = "rx",
- },
-}
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-libcamera-config.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-libcamera-config.lua
deleted file mode 100644
index d63fed11..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-libcamera-config.lua
+++ /dev/null
@@ -1,38 +0,0 @@
-libcamera_monitor.enabled = true
-
-libcamera_monitor.rules = {
- -- An array of matches/actions to evaluate.
- {
- -- Rules for matching a device or node. It is an array of
- -- properties that all need to match the regexp. If any of the
- -- matches work, the actions are executed for the object.
- matches = {
- {
- -- This matches all cards.
- { "device.name", "matches", "libcamera_device.*" },
- },
- },
- -- Apply properties on the matched object.
- apply_properties = {
- -- ["device.nick"] = "My Device",
- },
- },
- {
- matches = {
- {
- -- Matches all sources.
- { "node.name", "matches", "libcamera_input.*" },
- },
- {
- -- Matches all sinks.
- { "node.name", "matches", "libcamera_output.*" },
- },
- },
- apply_properties = {
- --["node.nick"] = "My Node",
- --["priority.driver"] = 100,
- --["priority.session"] = 100,
- --["node.pause-on-idle"] = false,
- },
- },
-}
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-v4l2-config.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-v4l2-config.lua
deleted file mode 100644
index 36e9f423..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/50-v4l2-config.lua
+++ /dev/null
@@ -1,38 +0,0 @@
-v4l2_monitor.enabled = true
-
-v4l2_monitor.rules = {
- -- An array of matches/actions to evaluate.
- {
- -- Rules for matching a device or node. It is an array of
- -- properties that all need to match the regexp. If any of the
- -- matches work, the actions are executed for the object.
- matches = {
- {
- -- This matches all cards.
- { "device.name", "matches", "v4l2_device.*" },
- },
- },
- -- Apply properties on the matched object.
- apply_properties = {
- -- ["device.nick"] = "My Device",
- },
- },
- {
- matches = {
- {
- -- Matches all sources.
- { "node.name", "matches", "v4l2_input.*" },
- },
- {
- -- Matches all sinks.
- { "node.name", "matches", "v4l2_output.*" },
- },
- },
- apply_properties = {
- --["node.nick"] = "My Node",
- --["priority.driver"] = 100,
- --["priority.session"] = 100,
- --["node.pause-on-idle"] = false,
- },
- },
-}
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/90-enable-all.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/90-enable-all.lua
deleted file mode 100644
index 37d790ea..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/main.lua.d/90-enable-all.lua
+++ /dev/null
@@ -1,26 +0,0 @@
--- Provide the "default" pw_metadata, which stores
--- dynamic properties of pipewire objects in RAM
-load_module("metadata")
-
--- Default client access policy
-default_access.enable()
-
--- Load devices
-alsa_monitor.enable()
-v4l2_monitor.enable()
-libcamera_monitor.enable()
-
--- Track/store/restore user choices about devices
-device_defaults.enable()
-
--- Track/store/restore user choices about streams
-stream_defaults.enable()
-
--- Link nodes by stream role and device intended role
-load_script("intended-roles.lua")
-
--- Automatically suspends idle nodes after 3 seconds
-load_script("suspend-node.lua")
-
--- Allows loading objects on demand via metadata
-load_script("sm-objects.lua")
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/policy.conf b/buildroot-external/rootfs-overlay/etc/wireplumber/policy.conf
deleted file mode 100644
index 42f71484..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/policy.conf
+++ /dev/null
@@ -1,73 +0,0 @@
-# WirePlumber daemon context configuration #
-
-context.properties = {
- ## Properties to configure the PipeWire context and some modules
-
- application.name = "WirePlumber Policy"
- log.level = 2
- wireplumber.script-engine = lua-scripting
- wireplumber.export-core = false
-
- #mem.mlock-all = false
- #support.dbus = true
-}
-
-context.spa-libs = {
- # =
- #
- # Used to find spa factory names. It maps an spa factory name
- # regular expression to a library name that should contain
- # that factory.
- #
- audio.convert.* = audioconvert/libspa-audioconvert
- support.* = support/libspa-support
-}
-
-context.modules = [
- #{ name =
- # [ args = { = ... } ]
- # [ flags = [ [ ifexists ] [ nofail ] ]
- #}
- #
- # PipeWire modules to load.
- # If ifexists is given, the module is ignored when it is not found.
- # If nofail is given, module initialization failures are ignored.
- #
-
- # The native communication protocol.
- { name = libpipewire-module-protocol-native }
-
- # Allows creating nodes that run in the context of the
- # client. Is used by all clients that want to provide
- # data to PipeWire.
- { name = libpipewire-module-client-node }
-
- # Allows creating devices that run in the context of the
- # client. Is used by the session manager.
- { name = libpipewire-module-client-device }
-
- # Makes a factory for wrapping nodes in an adapter with a
- # converter and resampler.
- { name = libpipewire-module-adapter }
-
- # Allows applications to create metadata objects. It creates
- # a factory for Metadata objects.
- { name = libpipewire-module-metadata }
-
- # Provides factories to make session manager objects.
- { name = libpipewire-module-session-manager }
-]
-
-wireplumber.components = [
- #{ name = , type = }
- #
- # WirePlumber components to load
- #
-
- # The lua scripting engine
- { name = libwireplumber-module-lua-scripting, type = module }
-
- # The lua configuration file
- # Other components are loaded from there
- { name = policy.lua, type = config/lua }
-]
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/00-functions.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/00-functions.lua
deleted file mode 100644
index 451ad4f5..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/00-functions.lua
+++ /dev/null
@@ -1,36 +0,0 @@
-components = {}
-
-function load_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libwireplumber-module-" .. m, type = "module", args = a }
- end
-end
-
-function load_optional_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libwireplumber-module-" .. m, type = "module", args = a, optional = true }
- end
-end
-
-function load_pw_module(m, a)
- assert(type(m) == "string", "module name is mandatory, bail out");
- if not components[m] then
- components[m] = { "libpipewire-module-" .. m, type = "pw_module", args = a }
- end
-end
-
-function load_script(s, a)
- if not components[s] then
- components[s] = { s, type = "script/lua", args = a }
- end
-end
-
-function load_monitor(s, a)
- load_script("monitors/" .. s .. ".lua", a)
-end
-
-function load_access(s, a)
- load_script("access/access-" .. s .. ".lua", a)
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/10-default-policy.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/10-default-policy.lua
deleted file mode 100644
index 83d0a3b2..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/10-default-policy.lua
+++ /dev/null
@@ -1,98 +0,0 @@
-default_policy = {}
-default_policy.enabled = true
-default_policy.properties = {}
-default_policy.endpoints = {}
-
-default_policy.policy = {
- ["move"] = true, -- moves session items when metadata target.node changes
- ["follow"] = true, -- moves session items to the default device when it has changed
-
- -- Whether to forward the ports format of filter stream nodes to their
- -- associated filter device nodes. This is needed for application to stream
- -- surround audio if echo-cancel is enabled.
- ["filter.forward-format"] = false,
-
- -- Set to 'true' to disable channel splitting & merging on nodes and enable
- -- passthrough of audio in the same format as the format of the device.
- -- Note that this breaks JACK support; it is generally not recommended
- ["audio.no-dsp"] = false,
-
- -- how much to lower the volume of lower priority streams when ducking
- -- note that this is a linear volume modifier (not cubic as in pulseaudio)
- ["duck.level"] = 0.3,
-}
-
-bluetooth_policy = {}
-
-bluetooth_policy.policy = {
- -- Whether to store state on the filesystem.
- ["use-persistent-storage"] = true,
-
- -- Whether to use headset profile in the presence of an input stream.
- ["media-role.use-headset-profile"] = true,
-
- -- Application names correspond to application.name in stream properties.
- -- Applications which do not set media.role but which should be considered
- -- for role based profile switching can be specified here.
- ["media-role.applications"] = {
- "Firefox", "Chromium input", "Google Chrome input", "Brave input",
- "Microsoft Edge input", "Vivaldi input", "ZOOM VoiceEngine",
- "Telegram Desktop", "telegram-desktop", "linphone", "Mumble",
- "WEBRTC VoiceEngine", "Skype", "Firefox Developer Edition",
- },
-}
-
-dsp_policy = {}
-
-dsp_policy.policy = {}
-
-dsp_policy.policy.properties = {}
-
--- An array of matches/filters to apply.
--- `matches` are rules for matching a sink node. It is an array of
--- properties that all need to match the regexp. If any of the
--- matches in an array work, the filters are executed for the sink.
--- `filter_chain` is a JSON string of parameters to filter-chain module
--- `properties` table only has `pro_audio` boolean, which enables Pro Audio mode on the sink when applying DSP
-dsp_policy.policy.rules = {}
-
-function default_policy.enable()
- if default_policy.enabled == false then
- return
- end
-
- -- Session item factories, building blocks for the session management graph
- -- Do not disable these unless you really know what you are doing
- load_module("si-node")
- load_module("si-audio-adapter")
- 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 endpoints statically at startup
- load_script("static-endpoints.lua", default_policy.endpoints)
-
- -- Create items for nodes that appear in the graph
- load_script("create-item.lua", default_policy.policy)
-
- -- Link nodes to each other to make media flow in the graph
- load_script("policy-node.lua", default_policy.policy)
-
- -- Link client nodes with endpoints to make media flow in the graph
- load_script("policy-endpoint-client.lua", default_policy.policy)
- load_script("policy-endpoint-client-links.lua", default_policy.policy)
-
- -- Link endpoints with device nodes to make media flow in the graph
- load_script("policy-endpoint-device.lua", default_policy.policy)
-
- -- Switch bluetooth profile based on media.role
- load_script("policy-bluetooth.lua", bluetooth_policy.policy)
-
- -- Load filter chains for hardware requiring DSP
- load_script("policy-dsp.lua", dsp_policy.policy)
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/50-endpoints-config.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/50-endpoints-config.lua
deleted file mode 100644
index 28656949..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/50-endpoints-config.lua
+++ /dev/null
@@ -1,95 +0,0 @@
--- uncomment to enable role-based endpoints
--- this is not yet ready for desktop use
---
---[[
-
-default_policy.policy.roles = {
- ["Capture"] = {
- ["alias"] = { "Multimedia", "Music", "Voice", "Capture" },
- ["priority"] = 25,
- ["action.default"] = "cork",
- ["action.capture"] = "mix",
- ["media.class"] = "Audio/Source",
- },
- ["Multimedia"] = {
- ["alias"] = { "Movie", "Music", "Game" },
- ["priority"] = 25,
- ["action.default"] = "cork",
- },
- ["Speech-Low"] = {
- ["priority"] = 30,
- ["action.default"] = "cork",
- ["action.Speech-Low"] = "mix",
- },
- ["Custom-Low"] = {
- ["priority"] = 35,
- ["action.default"] = "cork",
- ["action.Custom-Low"] = "mix",
- },
- ["Navigation"] = {
- ["priority"] = 50,
- ["action.default"] = "duck",
- ["action.Navigation"] = "mix",
- },
- ["Speech-High"] = {
- ["priority"] = 60,
- ["action.default"] = "cork",
- ["action.Speech-High"] = "mix",
- },
- ["Custom-High"] = {
- ["priority"] = 65,
- ["action.default"] = "cork",
- ["action.Custom-High"] = "mix",
- },
- ["Communication"] = {
- ["priority"] = 75,
- ["action.default"] = "cork",
- ["action.Communication"] = "mix",
- },
- ["Emergency"] = {
- ["alias"] = { "Alert" },
- ["priority"] = 99,
- ["action.default"] = "cork",
- ["action.Emergency"] = "mix",
- },
-}
-
-default_policy.endpoints = {
- ["endpoint.capture"] = {
- ["media.class"] = "Audio/Source",
- ["role"] = "Capture",
- },
- ["endpoint.multimedia"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Multimedia",
- },
- ["endpoint.speech_low"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Speech-Low",
- },
- ["endpoint.custom_low"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Custom-Low",
- },
- ["endpoint.navigation"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Navigation",
- },
- ["endpoint.speech_high"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Speech-High",
- },
- ["endpoint.custom_high"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Custom-High",
- },
- ["endpoint.communication"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Communication",
- },
- ["endpoint.emergency"] = {
- ["media.class"] = "Audio/Sink",
- ["role"] = "Emergency",
- },
-}
-]]--
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/90-enable-all.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/90-enable-all.lua
deleted file mode 100644
index c20e23ab..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/policy.lua.d/90-enable-all.lua
+++ /dev/null
@@ -1 +0,0 @@
-default_policy.enable()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/access/access-default.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/access/access-default.lua
deleted file mode 100644
index 0fac87b7..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/access/access-default.lua
+++ /dev/null
@@ -1,53 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author George Kiagiadakis
---
--- SPDX-License-Identifier: MIT
-
-local config = ... or {}
-
--- preprocess rules and create Interest objects
-for _, r in ipairs(config.rules or {}) do
- r.interests = {}
- for _, i in ipairs(r.matches) do
- local interest_desc = { type = "properties" }
- 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
- r.matches = nil
-end
-
-function rulesGetDefaultPermissions(properties)
- for _, r in ipairs(config.rules or {}) do
- if r.default_permissions then
- for _, interest in ipairs(r.interests) do
- if interest:matches(properties) then
- return r.default_permissions
- end
- end
- end
- end
-end
-
-clients_om = ObjectManager {
- Interest { type = "client" }
-}
-
-clients_om:connect("object-added", function (om, client)
- local id = client["bound-id"]
- local properties = client["properties"]
-
- local perms = rulesGetDefaultPermissions(properties)
-
- if perms then
- Log.info(client, "Granting permissions to client " .. id .. ": " .. perms)
- client:update_permissions { ["any"] = perms }
- end
-end)
-
-clients_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/access/access-portal.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/access/access-portal.lua
deleted file mode 100644
index e87a1572..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/access/access-portal.lua
+++ /dev/null
@@ -1,141 +0,0 @@
-MEDIA_ROLE_NONE = 0
-MEDIA_ROLE_CAMERA = 1 << 0
-
-function hasPermission (permissions, app_id, lookup)
- if permissions then
- for key, values in pairs(permissions) do
- if key == app_id then
- for _, v in pairs(values) do
- if v == lookup then
- return true
- end
- end
- end
- end
- end
- return false
-end
-
-function parseMediaRoles (media_roles_str)
- local media_roles = MEDIA_ROLE_NONE
- for role in media_roles_str:gmatch('[^,%s]+') do
- if role == "Camera" then
- media_roles = media_roles | MEDIA_ROLE_CAMERA
- end
- end
- return media_roles
-end
-
-function setPermissions (client, allow_client, allow_nodes)
- local client_id = client["bound-id"]
- Log.info(client, "Granting ALL access to client " .. client_id)
-
- -- Update permissions on client
- client:update_permissions { [client_id] = allow_client and "all" or "-" }
-
- -- Update permissions on camera source nodes
- for node in nodes_om:iterate() do
- local node_id = node["bound-id"]
- client:update_permissions { [node_id] = allow_nodes and "all" or "-" }
- end
-end
-
-function updateClientPermissions (client, permissions)
- local client_id = client["bound-id"]
- local str_prop = nil
- local app_id = nil
- local media_roles = nil
- local allowed = false
-
- -- Make sure the client is not the portal itself
- str_prop = client.properties["pipewire.access.portal.is_portal"]
- if str_prop == "yes" then
- Log.info (client, "client is the portal itself")
- return
- end
-
- -- Make sure the client has a portal app Id
- str_prop = client.properties["pipewire.access.portal.app_id"]
- if str_prop == nil then
- Log.info (client, "Portal managed client did not set app_id")
- return
- end
- if str_prop == "" then
- Log.info (client, "Ignoring portal check for non-sandboxed client")
- setPermissions (client, true, true)
- return
- end
- app_id = str_prop
-
- -- Make sure the client has portal media roles
- str_prop = client.properties["pipewire.access.portal.media_roles"]
- if str_prop == nil then
- Log.info (client, "Portal managed client did not set media_roles")
- return
- end
- media_roles = parseMediaRoles (str_prop)
- if (media_roles & MEDIA_ROLE_CAMERA) == 0 then
- Log.info (client, "Ignoring portal check for clients without camera role")
- return
- end
-
- -- Update permissions
- allowed = hasPermission (permissions, app_id, "yes")
-
- Log.info (client, "setting permissions: " .. tostring(allowed))
- setPermissions (client, allowed, allowed)
-end
-
--- Create portal clients object manager
-clients_om = ObjectManager {
- Interest {
- type = "client",
- Constraint { "pipewire.access", "=", "portal" },
- }
-}
-
--- Set permissions to portal clients from the permission store if loaded
-pps_plugin = Plugin.find("portal-permissionstore")
-if pps_plugin then
- nodes_om = ObjectManager {
- Interest {
- type = "node",
- Constraint { "media.role", "=", "Camera" },
- Constraint { "media.class", "=", "Video/Source" },
- }
- }
- nodes_om:activate()
-
- clients_om:connect("object-added", function (om, client)
- local new_perms = pps_plugin:call("lookup", "devices", "camera");
- updateClientPermissions (client, new_perms)
- end)
-
- nodes_om:connect("object-added", function (om, node)
- local new_perms = pps_plugin:call("lookup", "devices", "camera");
- for client in clients_om:iterate() do
- updateClientPermissions (client, new_perms)
- end
- end)
-
- pps_plugin:connect("changed", function (p, table, id, deleted, permissions)
- if table == "devices" or id == "camera" then
- for app_id, _ in pairs(permissions) do
- for client in clients_om:iterate {
- Constraint { "pipewire.access.portal.app_id", "=", app_id }
- } do
- updateClientPermissions (client, permissions)
- end
- end
- end
- end)
-else
- -- Otherwise, just set all permissions to all portal clients
- clients_om:connect("object-added", function (om, client)
- local id = client["bound-id"]
- Log.info(client, "Granting ALL access to client " .. id)
- client:update_permissions { ["any"] = "all" }
- end)
-end
-
-clients_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/create-item.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/create-item.lua
deleted file mode 100644
index 6d8056aa..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/create-item.lua
+++ /dev/null
@@ -1,130 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author Julian Bouzas
---
--- SPDX-License-Identifier: MIT
-
--- Receive script arguments from config.lua
-local config = ... or {}
-
-items = {}
-
-function configProperties(node)
- local np = node.properties
- local properties = {
- ["item.node"] = node,
- ["item.plugged.usec"] = GLib.get_monotonic_time(),
- ["item.features.no-dsp"] = config["audio.no-dsp"],
- ["item.features.monitor"] = true,
- ["item.features.control-port"] = false,
- ["node.id"] = node["bound-id"],
- ["client.id"] = np["client.id"],
- ["object.path"] = np["object.path"],
- ["object.serial"] = np["object.serial"],
- ["target.object"] = np["target.object"],
- ["priority.session"] = np["priority.session"],
- ["device.id"] = np["device.id"],
- ["card.profile.device"] = np["card.profile.device"],
- ["target.endpoint"] = np["target.endpoint"],
- }
-
- for k, v in pairs(np) do
- if k:find("^node") or k:find("^stream") or k:find("^media") then
- properties[k] = v
- end
- end
-
- local media_class = properties["media.class"] or ""
-
- if not properties["media.type"] then
- for _, i in ipairs({ "Audio", "Video", "Midi" }) do
- if media_class:find(i) then
- properties["media.type"] = i
- break
- end
- end
- end
-
- properties["item.node.type"] =
- media_class:find("^Stream/") and "stream" or "device"
-
- if media_class:find("Sink") or
- media_class:find("Input") or
- media_class:find("Duplex") then
- properties["item.node.direction"] = "input"
- elseif media_class:find("Source") or media_class:find("Output") then
- properties["item.node.direction"] = "output"
- end
- return properties
-end
-
-function addItem (node, item_type)
- local id = node["bound-id"]
- local item
-
- -- create item
- item = SessionItem ( item_type )
- items[id] = item
-
- -- configure item
- if not item:configure(configProperties(node)) then
- Log.warning(item, "failed to configure item for node " .. tostring(id))
- return
- end
-
- item:register ()
-
- -- activate item
- items[id]:activate (Features.ALL, function (item, e)
- if e then
- Log.message(item, "failed to activate item: " .. tostring(e));
- if item then
- item:remove ()
- end
- else
- Log.info(item, "activated item for node " .. tostring(id))
-
- -- Trigger object managers to update status
- item:remove ()
- if item["active-features"] ~= 0 then
- item:register ()
- end
- end
- end)
-end
-
-nodes_om = ObjectManager {
- Interest {
- type = "node",
- Constraint { "media.class", "#", "Stream/*", type = "pw-global" },
- },
- Interest {
- type = "node",
- Constraint { "media.class", "#", "Video/*", type = "pw-global" },
- },
- Interest {
- type = "node",
- Constraint { "media.class", "#", "Audio/*", type = "pw-global" },
- Constraint { "wireplumber.is-endpoint", "-", type = "pw" },
- },
-}
-
-nodes_om:connect("object-added", function (om, node)
- local media_class = node.properties['media.class']
- if string.find (media_class, "Audio") then
- addItem (node, "si-audio-adapter")
- else
- addItem (node, "si-node")
- end
-end)
-
-nodes_om:connect("object-removed", function (om, node)
- local id = node["bound-id"]
- if items[id] then
- items[id]:remove ()
- items[id] = nil
- end
-end)
-
-nodes_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/fallback-sink.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/fallback-sink.lua
deleted file mode 100644
index d7c3cfa2..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/fallback-sink.lua
+++ /dev/null
@@ -1,93 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author Frédéric Danis
---
--- SPDX-License-Identifier: MIT
-
-local sink_ids = {}
-local fallback_node = nil
-
-node_om = ObjectManager {
- Interest {
- type = "node",
- Constraint { "media.class", "matches", "Audio/Sink", type = "pw-global" },
- -- Do not consider endpoints created by WirePlumber
- Constraint { "wireplumber.is-endpoint", "!", true, type = "pw" },
- -- or the fallback sink itself
- Constraint { "wireplumber.is-fallback", "!", true, type = "pw" },
- }
-}
-
-function createFallbackSink()
- if fallback_node then
- return
- end
-
- Log.info("Create fallback sink")
-
- local properties = {}
-
- properties["node.name"] = "auto_null"
- properties["node.description"] = "Dummy Output"
-
- properties["audio.rate"] = 48000
- properties["audio.channels"] = 2
- properties["audio.position"] = "FL,FR"
-
- properties["media.class"] = "Audio/Sink"
- properties["factory.name"] = "support.null-audio-sink"
- properties["node.virtual"] = "true"
- properties["monitor.channel-volumes"] = "true"
-
- properties["wireplumber.is-fallback"] = "true"
- properties["priority.session"] = 500
-
- fallback_node = LocalNode("adapter", properties)
- fallback_node:activate(Feature.Proxy.BOUND)
-end
-
-function checkSinks()
- local sink_ids_items = 0
- for _ in pairs(sink_ids) do sink_ids_items = sink_ids_items + 1 end
-
- if sink_ids_items > 0 then
- if fallback_node then
- Log.info("Remove fallback sink")
- fallback_node = nil
- end
- elseif not fallback_node then
- createFallbackSink()
- end
-end
-
-function checkSinksAfterTimeout()
- if timeout_source then
- timeout_source:destroy()
- end
- timeout_source = Core.timeout_add(1000, function ()
- checkSinks()
- timeout_source = nil
- end)
-end
-
-node_om:connect("object-added", function (_, node)
- Log.debug("object added: " .. node.properties["object.id"] .. " " ..
- tostring(node.properties["node.name"]))
-
- sink_ids[node.properties["object.id"]] = node.properties["node.name"]
-
- checkSinksAfterTimeout()
-end)
-
-node_om:connect("object-removed", function (_, node)
- Log.debug("object removed: " .. node.properties["object.id"] .. " " ..
- tostring(node.properties["node.name"]))
-
- sink_ids[node.properties["object.id"]] = nil
- checkSinksAfterTimeout()
-end)
-
-node_om:activate()
-
-checkSinksAfterTimeout()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/intended-roles.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/intended-roles.lua
deleted file mode 100644
index f0d472b9..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/intended-roles.lua
+++ /dev/null
@@ -1,74 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Asymptotic
--- @author Arun Raghavan
---
--- 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()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/alsa-midi.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/alsa-midi.lua
deleted file mode 100644
index 6fdf34d3..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/alsa-midi.lua
+++ /dev/null
@@ -1,68 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author Julian Bouzas
---
--- SPDX-License-Identifier: MIT
-
--- Receive script arguments from config.lua
-local config = ... or {}
-
--- ensure config.properties is not nil
-config.properties = config.properties or {}
-
-SND_PATH = "/dev/snd"
-SEQ_NAME = "seq"
-SND_SEQ_PATH = SND_PATH .. "/" .. SEQ_NAME
-
-midi_node = nil
-fm_plugin = nil
-
-function CreateMidiNode ()
- -- Midi properties
- local props = {}
- if type(config.properties["alsa.midi.node-properties"]) == "table" then
- props = config.properties["alsa.midi.node-properties"]
- end
- props["factory.name"] = "api.alsa.seq.bridge"
- props["node.name"] = props["node.name"] or "Midi-Bridge"
-
- -- create the midi node
- local node = Node("spa-node-factory", props)
- node:activate(Feature.Proxy.BOUND, function (n)
- Log.info ("activated Midi bridge")
- end)
-
- return node;
-end
-
-if GLib.access (SND_SEQ_PATH, "rw") then
- midi_node = CreateMidiNode ()
-elseif config.properties["alsa.midi.monitoring"] then
- fm_plugin = Plugin.find("file-monitor-api")
-end
-
--- Only monitor the MIDI device if file does not exist and plugin API is loaded
-if midi_node == nil and fm_plugin ~= nil then
- -- listen for changed events
- fm_plugin:connect ("changed", function (o, file, old, evtype)
- -- files attributes changed
- if evtype == "attribute-changed" then
- if file ~= SND_SEQ_PATH then
- return
- end
- if midi_node == nil and GLib.access (SND_SEQ_PATH, "rw") then
- midi_node = CreateMidiNode ()
- fm_plugin:call ("remove-watch", SND_PATH)
- end
- end
-
- -- directory is going to be unmounted
- if evtype == "pre-unmount" then
- fm_plugin:call ("remove-watch", SND_PATH)
- end
- end)
-
- -- add watch
- fm_plugin:call ("add-watch", SND_PATH, "m")
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/alsa.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/alsa.lua
deleted file mode 100644
index d56c9f04..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/alsa.lua
+++ /dev/null
@@ -1,427 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author George Kiagiadakis
---
--- SPDX-License-Identifier: MIT
-
--- Receive script arguments from config.lua
-local config = ... or {}
-
--- ensure config.properties is not nil
-config.properties = config.properties or {}
-
--- unique device/node name tables
-device_names_table = nil
-node_names_table = nil
-
--- preprocess rules and create Interest objects
-for _, r in ipairs(config.rules or {}) do
- r.interests = {}
- for _, i in ipairs(r.matches) do
- local interest_desc = { type = "properties" }
- 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
- r.matches = nil
-end
-
--- applies properties from config.rules when asked to
-function rulesApplyProperties(properties)
- for _, r in ipairs(config.rules or {}) do
- if r.apply_properties then
- for _, interest in ipairs(r.interests) do
- if interest:matches(properties) then
- for k, v in pairs(r.apply_properties) do
- properties[k] = v
- end
- end
- end
- end
- end
-end
-
-function nonempty(str)
- return str ~= "" and str or nil
-end
-
-function createNode(parent, id, obj_type, factory, properties)
- local dev_props = parent.properties
-
- -- set the device id and spa factory name; REQUIRED, do not change
- properties["device.id"] = parent["bound-id"]
- properties["factory.name"] = factory
-
- -- set the default pause-on-idle setting
- properties["node.pause-on-idle"] = false
-
- -- try to negotiate the max ammount of channels
- if dev_props["api.alsa.use-acp"] ~= "true" then
- properties["audio.channels"] = properties["audio.channels"] or "64"
- end
-
- local dev = properties["api.alsa.pcm.device"]
- or properties["alsa.device"] or "0"
- local subdev = properties["api.alsa.pcm.subdevice"]
- or properties["alsa.subdevice"] or "0"
- local stream = properties["api.alsa.pcm.stream"] or "unknown"
- local profile = properties["device.profile.name"]
- or (stream .. "." .. dev .. "." .. subdev)
- local profile_desc = properties["device.profile.description"]
-
- -- set priority
- if not properties["priority.driver"] then
- local priority = (dev == "0") and 1000 or 744
- if stream == "capture" then
- priority = priority + 1000
- end
-
- priority = priority - (tonumber(dev) * 16) - tonumber(subdev)
-
- if profile:find("^pro%-") then
- priority = priority + 500
- elseif profile:find("^analog%-") then
- priority = priority + 9
- elseif profile:find("^iec958%-") then
- priority = priority + 8
- end
-
- properties["priority.driver"] = priority
- properties["priority.session"] = priority
- end
-
- -- ensure the node has a media class
- if not properties["media.class"] then
- if stream == "capture" then
- properties["media.class"] = "Audio/Source"
- else
- properties["media.class"] = "Audio/Sink"
- end
- end
-
- -- ensure the node has a name
- if not properties["node.name"] then
- local name =
- (stream == "capture" and "alsa_input" or "alsa_output")
- .. "." ..
- (dev_props["device.name"]:gsub("^alsa_card%.(.+)", "%1") or
- dev_props["device.name"] or
- "unnamed-device")
- .. "." ..
- profile
-
- -- sanitize name
- name = name:gsub("([^%w_%-%.])", "_")
-
- properties["node.name"] = name
-
- -- deduplicate nodes with the same name
- for counter = 2, 99, 1 do
- if node_names_table[properties["node.name"]] ~= true then
- node_names_table[properties["node.name"]] = true
- break
- end
- properties["node.name"] = name .. "." .. counter
- end
- end
-
- -- and a nick
- local nick = nonempty(properties["node.nick"])
- or nonempty(properties["api.alsa.pcm.name"])
- or nonempty(properties["alsa.name"])
- or nonempty(profile_desc)
- or dev_props["device.nick"]
- if nick == "USB Audio" then
- nick = dev_props["device.nick"]
- end
- -- also sanitize nick, replace ':' with ' '
- properties["node.nick"] = nick:gsub("(:)", " ")
-
- -- ensure the node has a description
- if not properties["node.description"] then
- local desc = nonempty(dev_props["device.description"]) or "unknown"
- local name = nonempty(properties["api.alsa.pcm.name"]) or
- nonempty(properties["api.alsa.pcm.id"]) or dev
-
- if profile_desc then
- desc = desc .. " " .. profile_desc
- elseif subdev ~= "0" then
- desc = desc .. " (" .. name .. " " .. subdev .. ")"
- elseif dev ~= "0" then
- desc = desc .. " (" .. name .. ")"
- end
-
- -- also sanitize description, replace ':' with ' '
- properties["node.description"] = desc:gsub("(:)", " ")
- end
-
- -- add api.alsa.card.* properties for rule matching purposes
- for k, v in pairs(dev_props) do
- if k:find("^api%.alsa%.card%..*") then
- properties[k] = v
- end
- end
-
- -- apply VM overrides
- local vm_overrides = config.properties["vm.node.defaults"]
- if nonempty(Core.get_vm_type()) and type(vm_overrides) == "table" then
- for k, v in pairs(vm_overrides) do
- properties[k] = v
- end
- end
-
- -- apply properties from config.rules
- rulesApplyProperties(properties)
- if properties["node.disabled"] then
- node_names_table [properties ["node.name"]] = nil
- return
- end
-
- -- create the node
- local node = Node("adapter", properties)
- node:activate(Feature.Proxy.BOUND)
- parent:store_managed_object(id, node)
-end
-
-function createDevice(parent, id, factory, properties)
- local device = SpaDevice(factory, properties)
- if device then
- device:connect("create-object", createNode)
- device:connect("object-removed", function (parent, id)
- local node = parent:get_managed_object(id)
- if not node then
- return
- end
-
- node_names_table[node.properties["node.name"]] = nil
- end)
- device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND)
- parent:store_managed_object(id, device)
- else
- Log.warning ("Failed to create '" .. factory .. "' device")
- end
-end
-
-function prepareDevice(parent, id, obj_type, factory, properties)
- -- ensure the device has an appropriate name
- local name = "alsa_card." ..
- (properties["device.name"] or
- properties["device.bus-id"] or
- properties["device.bus-path"] or
- tostring(id)):gsub("([^%w_%-%.])", "_")
-
- properties["device.name"] = name
-
- -- deduplicate devices with the same name
- for counter = 2, 99, 1 do
- if device_names_table[properties["device.name"]] ~= true then
- device_names_table[properties["device.name"]] = true
- break
- end
- properties["device.name"] = name .. "." .. counter
- end
-
- -- ensure the device has a description
- if not properties["device.description"] then
- local d = nil
- local f = properties["device.form-factor"]
- local c = properties["device.class"]
- local n = properties["api.alsa.card.name"]
-
- if n == "Loopback" then
- d = I18n.gettext("Loopback")
- elseif f == "internal" then
- d = I18n.gettext("Built-in Audio")
- elseif c == "modem" then
- d = I18n.gettext("Modem")
- end
-
- d = d or properties["device.product.name"]
- or properties["api.alsa.card.name"]
- or properties["alsa.card_name"]
- or "Unknown device"
- properties["device.description"] = d
- end
-
- -- ensure the device has a nick
- properties["device.nick"] =
- properties["device.nick"] or
- properties["api.alsa.card.name"] or
- properties["alsa.card_name"]
-
- -- set the icon name
- if not properties["device.icon-name"] then
- local icon = nil
- local icon_map = {
- -- form factor -> icon
- ["microphone"] = "audio-input-microphone",
- ["webcam"] = "camera-web",
- ["handset"] = "phone",
- ["portable"] = "multimedia-player",
- ["tv"] = "video-display",
- ["headset"] = "audio-headset",
- ["headphone"] = "audio-headphones",
- ["speaker"] = "audio-speakers",
- ["hands-free"] = "audio-handsfree",
- }
- local f = properties["device.form-factor"]
- local c = properties["device.class"]
- local b = properties["device.bus"]
-
- icon = icon_map[f] or ((c == "modem") and "modem") or "audio-card"
- properties["device.icon-name"] = icon .. "-analog" .. (b and ("-" .. b) or "")
- end
-
- -- apply properties from config.rules
- rulesApplyProperties(properties)
- if properties["device.disabled"] then
- device_names_table [properties ["device.name"]] = nil
- return
- end
-
- -- override the device factory to use ACP
- if properties["api.alsa.use-acp"] then
- Log.info("Enabling the use of ACP on " .. properties["device.name"])
- factory = "api.alsa.acp.device"
- end
-
- -- use device reservation, if available
- if rd_plugin and properties["api.alsa.card"] then
- local rd_name = "Audio" .. properties["api.alsa.card"]
- local rd = rd_plugin:call("create-reservation",
- rd_name,
- config.properties["alsa.reserve.application-name"] or "WirePlumber",
- properties["device.name"],
- config.properties["alsa.reserve.priority"] or -20);
-
- properties["api.dbus.ReserveDevice1"] = rd_name
-
- -- unlike pipewire-media-session, this logic here keeps the device
- -- acquired at all times and destroys it if someone else acquires
- rd:connect("notify::state", function (rd, pspec)
- local state = rd["state"]
-
- if state == "acquired" then
- -- create the device
- createDevice(parent, id, factory, properties)
-
- elseif state == "available" then
- -- attempt to acquire again
- rd:call("acquire")
-
- elseif state == "busy" then
- -- destroy the device
- parent:store_managed_object(id, nil)
- end
- end)
-
- rd:connect("release-requested", function (rd)
- Log.info("release requested")
- parent:store_managed_object(id, nil)
- rd:call("release")
- end)
-
- if jack_device then
- rd:connect("notify::owner-name-changed", function (rd, pspec)
- if rd["state"] == "busy" and
- rd["owner-application-name"] == "Jack audio server" then
- -- TODO enable the jack device
- else
- -- TODO disable the jack device
- end
- end)
- end
-
- rd:call("acquire")
- else
- -- create the device
- createDevice(parent, id, factory, properties)
- end
-end
-
-function createMonitor ()
- local m = SpaDevice("api.alsa.enum.udev", config.properties)
- if m == nil then
- Log.message("PipeWire's SPA ALSA udev plugin(\"api.alsa.enum.udev\")"
- .. "missing or broken. Sound Cards cannot be enumerated")
- return nil
- end
-
- -- handle create-object to prepare device
- m:connect("create-object", prepareDevice)
-
- -- handle object-removed to destroy device reservations and recycle device name
- m:connect("object-removed", function (parent, id)
- local device = parent:get_managed_object(id)
- if not device then
- return
- end
-
- if rd_plugin then
- local rd_name = device.properties["api.dbus.ReserveDevice1"]
- if rd_name then
- rd_plugin:call("destroy-reservation", rd_name)
- end
- end
- device_names_table[device.properties["device.name"]] = nil
- for managed_node in device:iterate_managed_objects() do
- node_names_table[managed_node.properties["node.name"]] = nil
- end
- end)
-
- -- reset the name tables to make sure names are recycled
- device_names_table = {}
- node_names_table = {}
-
- -- activate monitor
- Log.info("Activating ALSA monitor")
- m:activate(Feature.SpaDevice.ENABLED)
- return m
-end
-
--- create the JACK device (for PipeWire to act as client to a JACK server)
-if config.properties["alsa.jack-device"] then
- jack_device = Device("spa-device-factory", {
- ["factory.name"] = "api.jack.device",
- ["node.name"] = "JACK-Device",
- })
- jack_device:activate(Feature.Proxy.BOUND)
-end
-
--- enable device reservation if requested
-if config.properties["alsa.reserve"] then
- rd_plugin = Plugin.find("reserve-device")
-end
-
--- if the reserve-device plugin is enabled, at the point of script execution
--- it is expected to be connected. if it is not, assume the d-bus connection
--- has failed and continue without it
-if rd_plugin and rd_plugin:call("get-dbus")["state"] ~= "connected" then
- Log.message("reserve-device plugin is not connected to D-Bus, "
- .. "disabling device reservation")
- rd_plugin = nil
-end
-
--- handle rd_plugin state changes to destroy and re-create the ALSA monitor in
--- case D-Bus service is restarted
-if rd_plugin then
- local dbus = rd_plugin:call("get-dbus")
- dbus:connect("notify::state", function (b, pspec)
- local state = b["state"]
- Log.info ("rd-plugin state changed to " .. state)
- if state == "connected" then
- Log.info ("Creating ALSA monitor")
- monitor = createMonitor()
- elseif state == "closed" then
- Log.info ("Destroying ALSA monitor")
- monitor = nil
- end
- end)
-end
-
--- create the monitor
-monitor = createMonitor()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/bluez-midi.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/bluez-midi.lua
deleted file mode 100644
index 32b886ec..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/bluez-midi.lua
+++ /dev/null
@@ -1,187 +0,0 @@
--- WirePlumber
---
--- Copyright © 2022 Pauli Virtanen
--- @author Pauli Virtanen
---
--- SPDX-License-Identifier: MIT
-
-local config = ... or {}
-
--- unique device/node name tables
-node_names_table = nil
-id_to_name_table = nil
-
--- preprocess rules and create Interest objects
-for _, r in ipairs(config.rules or {}) do
- r.interests = {}
- for _, i in ipairs(r.matches) do
- local interest_desc = { type = "properties" }
- 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
- r.matches = nil
-end
-
--- applies properties from config.rules when asked to
-function rulesApplyProperties(properties)
- for _, r in ipairs(config.rules or {}) do
- if r.apply_properties then
- for _, interest in ipairs(r.interests) do
- if interest:matches(properties) then
- for k, v in pairs(r.apply_properties) do
- properties[k] = v
- end
- end
- end
- end
- end
-end
-
-function setLatencyOffset(node, offset_msec)
- if not offset_msec then
- return
- end
-
- local props = { "Spa:Pod:Object:Param:Props", "Props" }
- props.latencyOffsetNsec = tonumber(offset_msec) * 1000000
-
- local param = Pod.Object(props)
- Log.debug(param, "setting latency offset on " .. tostring(node))
- node:set_param("Props", param)
-end
-
-function createNode(parent, id, type, factory, properties)
- properties["factory.name"] = factory
-
- -- set the node description
- local desc = properties["node.description"]
- -- sanitize description, replace ':' with ' '
- properties["node.description"] = desc:gsub("(:)", " ")
-
- -- set the node name
- local name =
- "bluez_midi." .. properties["api.bluez5.address"]
- -- sanitize name
- name = name:gsub("([^%w_%-%.])", "_")
- -- deduplicate nodes with the same name
- properties["node.name"] = name
- for counter = 2, 99, 1 do
- if node_names_table[properties["node.name"]] ~= true then
- node_names_table[properties["node.name"]] = true
- break
- end
- properties["node.name"] = name .. "." .. counter
- end
-
- properties["api.glib.mainloop"] = "true"
-
- -- apply properties from config.rules
- rulesApplyProperties(properties)
-
- local latency_offset = properties["node.latency-offset-msec"]
- properties["node.latency-offset-msec"] = nil
-
- -- create the node
- -- it doesn't necessarily need to be a local node,
- -- the other Bluetooth parts run in the local process,
- -- so it's consistent to have also this here
- local node = LocalNode("spa-node-factory", properties)
- node:activate(Feature.Proxy.BOUND)
- parent:store_managed_object(id, node)
- id_to_name_table[id] = properties["node.name"]
- setLatencyOffset(node, latency_offset)
-end
-
-function createMonitor()
- local monitor_props = {}
- for k, v in pairs(config.properties or {}) do
- monitor_props[k] = v
- end
- monitor_props["server"] = nil
-
- monitor_props["api.glib.mainloop"] = "true"
-
- local monitor = SpaDevice("api.bluez5.midi.enum", monitor_props)
- if monitor then
- monitor:connect("create-object", createNode)
- monitor:connect("object-removed", function (parent, id)
- node_names_table[id_to_name_table[id]] = nil
- id_to_name_table[id] = nil
- end)
- else
- Log.message("PipeWire's BlueZ MIDI SPA missing or broken. Bluetooth not supported.")
- return nil
- end
-
- -- reset the name tables to make sure names are recycled
- node_names_table = {}
- id_to_name_table = {}
-
- monitor:activate(Feature.SpaDevice.ENABLED)
- return monitor
-end
-
-function createServers()
- local props = config.properties or {}
-
- if not props["servers"] then
- return nil
- end
-
- local servers = {}
- local i = 1
-
- for k, v in pairs(props["servers"]) do
- local node_props = {
- ["node.name"] = v,
- ["node.description"] = string.format(I18n.gettext("BLE MIDI %d"), i),
- ["api.bluez5.role"] = "server",
- ["factory.name"] = "api.bluez5.midi.node",
- ["api.glib.mainloop"] = "true",
- }
- rulesApplyProperties(node_props)
-
- local latency_offset = node_props["node.latency-offset-msec"]
- node_props["node.latency-offset-msec"] = nil
-
- local node = LocalNode("spa-node-factory", node_props)
- if node then
- node:activate(Feature.Proxy.BOUND)
- table.insert(servers, node)
- setLatencyOffset(node, latency_offset)
- else
- Log.message("Failed to create BLE MIDI server.")
- end
- i = i + 1
- end
-
- return servers
-end
-
-logind_plugin = Plugin.find("logind")
-if logind_plugin then
- -- if logind support is enabled, activate
- -- the monitor only when the seat is active
- function startStopMonitor(seat_state)
- Log.info(logind_plugin, "Seat state changed: " .. seat_state)
-
- if seat_state == "active" then
- monitor = createMonitor()
- servers = createServers()
- elseif monitor then
- monitor:deactivate(Feature.SpaDevice.ENABLED)
- monitor = nil
- servers = nil
- end
- end
-
- logind_plugin:connect("state-changed", function(p, s) startStopMonitor(s) end)
- startStopMonitor(logind_plugin:call("get-state"))
-else
- monitor = createMonitor()
- servers = createServers()
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/bluez.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/bluez.lua
deleted file mode 100644
index 4924ae00..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/bluez.lua
+++ /dev/null
@@ -1,428 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author George Kiagiadakis
---
--- SPDX-License-Identifier: MIT
-
-local config = ... or {}
-local COMBINE_OFFSET = 64
-
-devices_om = ObjectManager {
- Interest {
- type = "device",
- }
-}
-
-nodes_om = ObjectManager {
- Interest {
- type = "node",
- Constraint { "node.name", "#", "*.bluez_*put*"},
- Constraint { "device.id", "+" },
- }
-}
-
--- preprocess rules and create Interest objects
-for _, r in ipairs(config.rules or {}) do
- r.interests = {}
- for _, i in ipairs(r.matches) do
- local interest_desc = { type = "properties" }
- 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
- r.matches = nil
-end
-
--- applies properties from config.rules when asked to
-function rulesApplyProperties(properties)
- for _, r in ipairs(config.rules or {}) do
- if r.apply_properties then
- for _, interest in ipairs(r.interests) do
- if interest:matches(properties) then
- for k, v in pairs(r.apply_properties) do
- properties[k] = v
- end
- end
- end
- end
- end
-end
-
-function setOffloadActive(device, value)
- local pod = Pod.Object {
- "Spa:Pod:Object:Param:Props", "Props", bluetoothOffloadActive = value
- }
- device:set_params("Props", pod)
-end
-
-nodes_om:connect("object-added", function(_, node)
- node:connect("state-changed", function(node, old_state, cur_state)
- local interest = Interest {
- type = "device",
- Constraint { "object.id", "=", node.properties["device.id"]}
- }
- for d in devices_om:iterate (interest) do
- if cur_state == "running" then
- setOffloadActive(d, true)
- else
- setOffloadActive(d, false)
- end
- end
- end)
-end)
-
-function createOffloadScoNode(parent, id, type, factory, properties)
- local dev_props = parent.properties
-
- local args = {
- ["audio.channels"] = 1,
- ["audio.position"] = "[MONO]",
- }
-
- local desc =
- dev_props["device.description"]
- or dev_props["device.name"]
- or dev_props["device.nick"]
- or dev_props["device.alias"]
- or "bluetooth-device"
- -- sanitize description, replace ':' with ' '
- args["node.description"] = desc:gsub("(:)", " ")
-
- if factory:find("sink") then
- local capture_args = {
- ["device.id"] = parent["bound-id"],
- ["media.class"] = "Audio/Sink",
- ["node.pause-on-idle"] = false,
- }
- for k, v in pairs(properties) do
- capture_args[k] = v
- end
-
- local name = "bluez_output" .. "." .. (properties["api.bluez5.address"] or dev_props["device.name"]) .. "." .. tostring(id)
- args["node.name"] = name:gsub("([^%w_%-%.])", "_")
- args["capture.props"] = Json.Object(capture_args)
- args["playback.props"] = Json.Object {
- ["node.passive"] = true,
- ["node.pause-on-idle"] = false,
- }
- elseif factory:find("source") then
- local playback_args = {
- ["device.id"] = parent["bound-id"],
- ["media.class"] = "Audio/Source",
- ["node.pause-on-idle"] = false,
- }
- for k, v in pairs(properties) do
- playback_args[k] = v
- end
-
- local name = "bluez_input" .. "." .. (properties["api.bluez5.address"] or dev_props["device.name"]) .. "." .. tostring(id)
- args["node.name"] = name:gsub("([^%w_%-%.])", "_")
- args["capture.props"] = Json.Object {
- ["node.passive"] = true,
- ["node.pause-on-idle"] = false,
- }
- args["playback.props"] = Json.Object(playback_args)
- else
- Log.warning(parent, "Unsupported factory: " .. factory)
- return
- end
-
- -- Transform 'args' to a json object here
- local args_json = Json.Object(args)
-
- -- and get the final JSON as a string from the json object
- local args_string = args_json:get_data()
-
- local loopback_properties = {}
-
- local loopback = LocalModule("libpipewire-module-loopback", args_string, loopback_properties)
- parent:store_managed_object(id, loopback)
-end
-
-device_set_nodes_om = ObjectManager {
- Interest {
- type = "node",
- Constraint { "api.bluez5.set.leader", "+", type = "pw" },
- }
-}
-
-device_set_nodes_om:connect ("object-added", function(_, node)
- -- Connect ObjectConfig events to the right node
- if not monitor then
- return
- end
-
- local interest = Interest {
- type = "device",
- Constraint { "object.id", "=", node.properties["device.id"] }
- }
- Log.info("Device set node found: " .. tostring (node["bound-id"]))
- for device in devices_om:iterate (interest) do
- local device_id = device.properties["api.bluez5.id"]
- if not device_id then
- goto next_device
- end
-
- local spa_device = monitor:get_managed_object (tonumber (device_id))
- if not spa_device then
- goto next_device
- end
-
- local id = node.properties["card.profile.device"]
- if id ~= nil then
- Log.info(".. assign to device: " .. tostring (device["bound-id"]) .. " node " .. tostring (id))
- spa_device:store_managed_object (id, node)
-
- -- set routes again to update volumes etc.
- for route in device:iterate_params ("Route") do
- device:set_param ("Route", route)
- end
- end
-
- ::next_device::
- end
-end)
-
-function createSetNode(parent, id, type, factory, properties)
- local args = {}
- local name
- local target_class
- local stream_class
- local rules = {}
- local members_json = Json.Raw (properties["api.bluez5.set.members"])
- local channels_json = Json.Raw (properties["api.bluez5.set.channels"])
- local members = members_json:parse ()
- local channels = channels_json:parse ()
-
- if properties["media.class"] == "Audio/Sink" then
- name = "bluez_output"
- args["combine.mode"] = "sink"
- target_class = "Audio/Sink/Internal"
- stream_class = "Stream/Output/Audio/Internal"
- else
- name = "bluez_input"
- args["combine.mode"] = "source"
- target_class = "Audio/Source/Internal"
- stream_class = "Stream/Input/Audio/Internal"
- end
-
- Log.info("Device set: " .. properties["node.name"])
-
- for _, member in pairs(members) do
- Log.info("Device set member:" .. member["object.path"])
- table.insert(rules,
- Json.Object {
- ["matches"] = Json.Array {
- Json.Object {
- ["object.path"] = member["object.path"],
- ["media.class"] = target_class,
- },
- },
- ["actions"] = Json.Object {
- ["create-stream"] = Json.Object {
- ["media.class"] = stream_class,
- ["audio.position"] = Json.Array (member["channels"]),
- }
- },
- }
- )
- end
-
- properties["node.virtual"] = false
- properties["device.api"] = "bluez5"
- properties["api.bluez5.set.members"] = nil
- properties["api.bluez5.set.channels"] = nil
- properties["api.bluez5.set.leader"] = true
- properties["audio.position"] = Json.Array (channels)
- args["combine.props"] = Json.Object (properties)
- args["stream.props"] = Json.Object {}
- args["stream.rules"] = Json.Array (rules)
-
- local args_json = Json.Object(args)
- local args_string = args_json:get_data()
- local combine_properties = {}
- Log.info("Device set node: " .. args_string)
- return LocalModule("libpipewire-module-combine-stream", args_string, combine_properties)
-end
-
-function createNode(parent, id, type, factory, properties)
- local dev_props = parent.properties
-
- if config.properties["bluez5.hw-offload-sco"] and factory:find("sco") then
- createOffloadScoNode(parent, id, type, factory, properties)
- return
- end
-
- -- set the device id and spa factory name; REQUIRED, do not change
- properties["device.id"] = parent["bound-id"]
- properties["factory.name"] = factory
-
- -- set the default pause-on-idle setting
- properties["node.pause-on-idle"] = false
-
- -- set the node description
- local desc =
- dev_props["device.description"]
- or dev_props["device.name"]
- or dev_props["device.nick"]
- or dev_props["device.alias"]
- or "bluetooth-device"
- -- sanitize description, replace ':' with ' '
- properties["node.description"] = desc:gsub("(:)", " ")
-
- -- set the node name
- local name =
- ((factory:find("sink") and "bluez_output") or
- (factory:find("source") and "bluez_input" or factory)) .. "." ..
- (properties["api.bluez5.address"] or dev_props["device.name"]) .. "." ..
- tostring(id)
- -- sanitize name
- properties["node.name"] = name:gsub("([^%w_%-%.])", "_")
-
- -- set priority
- if not properties["priority.driver"] then
- local priority = factory:find("source") and 2010 or 1010
- properties["priority.driver"] = priority
- properties["priority.session"] = priority
- end
-
- -- autoconnect if it's a stream
- if properties["api.bluez5.profile"] == "headset-audio-gateway" or
- properties["api.bluez5.profile"] == "bap-sink" or
- factory:find("a2dp.source") or factory:find("media.source") then
- properties["node.autoconnect"] = true
- end
-
- -- apply properties from config.rules
- rulesApplyProperties(properties)
-
- -- create the node; bluez requires "local" nodes, i.e. ones that run in
- -- the same process as the spa device, for several reasons
-
- if properties["api.bluez5.set.leader"] then
- local combine = createSetNode(parent, id, type, factory, properties)
- parent:store_managed_object(id + COMBINE_OFFSET, combine)
- else
- local node = LocalNode("adapter", properties)
- node:activate(Feature.Proxy.BOUND)
- parent:store_managed_object(id, node)
- end
-end
-
-function removeNode(parent, id)
- -- Clear also the device set module, if any
- parent:store_managed_object(id + COMBINE_OFFSET, nil)
-end
-
-function createDevice(parent, id, type, factory, properties)
- local device = parent:get_managed_object(id)
- if not device then
- -- ensure a proper device name
- local name =
- (properties["device.name"] or
- properties["api.bluez5.address"] or
- properties["device.description"] or
- tostring(id)):gsub("([^%w_%-%.])", "_")
-
- if not name:find("^bluez_card%.", 1) then
- name = "bluez_card." .. name
- end
- properties["device.name"] = name
-
- -- set the icon name
- if not properties["device.icon-name"] then
- local icon = nil
- local icon_map = {
- -- form factor -> icon
- ["microphone"] = "audio-input-microphone",
- ["webcam"] = "camera-web",
- ["handset"] = "phone",
- ["portable"] = "multimedia-player",
- ["tv"] = "video-display",
- ["headset"] = "audio-headset",
- ["headphone"] = "audio-headphones",
- ["speaker"] = "audio-speakers",
- ["hands-free"] = "audio-handsfree",
- }
- local f = properties["device.form-factor"]
- local b = properties["device.bus"]
-
- icon = icon_map[f] or "audio-card"
- properties["device.icon-name"] = icon .. (b and ("-" .. b) or "")
- end
-
- -- initial profile is to be set by policy-device-profile.lua, not spa-bluez5
- properties["bluez5.profile"] = "off"
- properties["api.bluez5.id"] = id
-
- -- apply properties from config.rules
- rulesApplyProperties(properties)
-
- -- create the device
- device = SpaDevice(factory, properties)
- if device then
- device:connect("create-object", createNode)
- device:connect("object-removed", removeNode)
- parent:store_managed_object(id, device)
- else
- Log.warning ("Failed to create '" .. factory .. "' device")
- return
- end
- end
-
- Log.info(parent, string.format("%d, %s (%s): %s",
- id, properties["device.description"],
- properties["api.bluez5.address"], properties["api.bluez5.connection"]))
-
- -- activate the device after the bluez profiles are connected
- if properties["api.bluez5.connection"] == "connected" then
- device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND)
- else
- device:deactivate(Features.ALL)
- end
-end
-
-function createMonitor()
- local monitor_props = config.properties or {}
- monitor_props["api.bluez5.connection-info"] = true
-
- local monitor = SpaDevice("api.bluez5.enum.dbus", monitor_props)
- if monitor then
- monitor:connect("create-object", createDevice)
- else
- Log.message("PipeWire's BlueZ SPA missing or broken. Bluetooth not supported.")
- return nil
- end
- monitor:activate(Feature.SpaDevice.ENABLED)
-
- return monitor
-end
-
-logind_plugin = Plugin.find("logind")
-if logind_plugin then
- -- if logind support is enabled, activate
- -- the monitor only when the seat is active
- function startStopMonitor(seat_state)
- Log.info(logind_plugin, "Seat state changed: " .. seat_state)
-
- if seat_state == "active" then
- monitor = createMonitor()
- elseif monitor then
- monitor:deactivate(Feature.SpaDevice.ENABLED)
- monitor = nil
- end
- end
-
- logind_plugin:connect("state-changed", function(p, s) startStopMonitor(s) end)
- startStopMonitor(logind_plugin:call("get-state"))
-else
- monitor = createMonitor()
-end
-
-nodes_om:activate()
-devices_om:activate()
-device_set_nodes_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/libcamera.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/libcamera.lua
deleted file mode 100644
index 3f411f28..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/libcamera.lua
+++ /dev/null
@@ -1,174 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author George Kiagiadakis
---
--- SPDX-License-Identifier: MIT
-
-local config = ... or {}
-
--- preprocess rules and create Interest objects
-for _, r in ipairs(config.rules or {}) do
- r.interests = {}
- for _, i in ipairs(r.matches) do
- local interest_desc = { type = "properties" }
- 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
- r.matches = nil
-end
-
--- applies properties from config.rules when asked to
-function rulesApplyProperties(properties)
- for _, r in ipairs(config.rules or {}) do
- if r.apply_properties then
- for _, interest in ipairs(r.interests) do
- if interest:matches(properties) then
- for k, v in pairs(r.apply_properties) do
- properties[k] = v
- end
- end
- end
- end
- end
-end
-
-function findDuplicate(parent, id, property, value)
- for i = 0, id - 1, 1 do
- local obj = parent:get_managed_object(i)
- if obj and obj.properties[property] == value then
- return true
- end
- end
- return false
-end
-
-function createNode(parent, id, type, factory, properties)
- local dev_props = parent.properties
- local location = properties["api.libcamera.location"]
-
- -- set the device id and spa factory name; REQUIRED, do not change
- properties["device.id"] = parent["bound-id"]
- properties["factory.name"] = factory
-
- -- set the default pause-on-idle setting
- properties["node.pause-on-idle"] = false
-
- -- set the node name
- local name =
- (factory:find("sink") and "libcamera_output") or
- (factory:find("source") and "libcamera_input" or factory)
- .. "." ..
- (dev_props["device.name"]:gsub("^libcamera_device%.(.+)", "%1") or
- dev_props["device.name"] or
- dev_props["device.nick"] or
- dev_props["device.alias"] or
- "libcamera-device")
- -- sanitize name
- name = name:gsub("([^%w_%-%.])", "_")
-
- properties["node.name"] = name
-
- -- deduplicate nodes with the same name
- for counter = 2, 99, 1 do
- if findDuplicate(parent, id, "node.name", properties["node.name"]) then
- properties["node.name"] = name .. "." .. counter
- else
- break
- end
- end
-
- -- set the node description
- local desc = dev_props["device.description"] or "libcamera-device"
- if location == "front" then
- desc = I18n.gettext("Built-in Front Camera")
- elseif location == "back" then
- desc = I18n.gettext("Built-in Back Camera")
- end
- -- sanitize description, replace ':' with ' '
- properties["node.description"] = desc:gsub("(:)", " ")
-
- -- set the node nick
- local nick = properties["node.nick"] or
- dev_props["device.product.name"] or
- dev_props["device.description"] or
- dev_props["device.nick"]
- properties["node.nick"] = nick:gsub("(:)", " ")
-
- -- set priority
- if not properties["priority.session"] then
- local priority = 700
- if location == "external" then
- priority = priority + 150
- elseif location == "front" then
- priority = priority + 100
- elseif location == "back" then
- priority = priority + 50
- end
- properties["priority.session"] = priority
- end
-
- -- apply properties from config.rules
- rulesApplyProperties(properties)
- if properties ["node.disabled"] then
- return
- end
-
- -- create the node
- local node = Node("spa-node-factory", properties)
- node:activate(Feature.Proxy.BOUND)
- parent:store_managed_object(id, node)
-end
-
-function createDevice(parent, id, type, factory, properties)
- -- ensure the device has an appropriate name
- local name = "libcamera_device." ..
- (properties["device.name"] or
- properties["device.bus-id"] or
- properties["device.bus-path"] or
- tostring(id)):gsub("([^%w_%-%.])", "_")
-
- properties["device.name"] = name
-
- -- deduplicate devices with the same name
- for counter = 2, 99, 1 do
- if findDuplicate(parent, id, "device.name", properties["device.name"]) then
- properties["device.name"] = name .. "." .. counter
- else
- break
- end
- end
-
- -- ensure the device has a description
- properties["device.description"] =
- properties["device.description"]
- or properties["device.product.name"]
- or "Unknown device"
-
- -- apply properties from config.rules
- rulesApplyProperties(properties)
- if properties ["device.disabled"] then
- return
- end
- -- create the device
- local device = SpaDevice(factory, properties)
- if device then
- device:connect("create-object", createNode)
- device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND)
- parent:store_managed_object(id, device)
- else
- Log.warning ("Failed to create '" .. factory .. "' device")
- end
-end
-
-monitor = SpaDevice("api.libcamera.enum.manager", config.properties or {})
-if monitor then
- monitor:connect("create-object", createDevice)
- monitor:activate(Feature.SpaDevice.ENABLED)
-else
- Log.message("PipeWire's libcamera SPA missing or broken. libcamera not supported.")
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/v4l2.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/v4l2.lua
deleted file mode 100644
index 609d7e71..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/monitors/v4l2.lua
+++ /dev/null
@@ -1,165 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author George Kiagiadakis
---
--- SPDX-License-Identifier: MIT
-
-local config = ... or {}
-
--- preprocess rules and create Interest objects
-for _, r in ipairs(config.rules or {}) do
- r.interests = {}
- for _, i in ipairs(r.matches) do
- local interest_desc = { type = "properties" }
- 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
- r.matches = nil
-end
-
--- applies properties from config.rules when asked to
-function rulesApplyProperties(properties)
- for _, r in ipairs(config.rules or {}) do
- if r.apply_properties then
- for _, interest in ipairs(r.interests) do
- if interest:matches(properties) then
- for k, v in pairs(r.apply_properties) do
- properties[k] = v
- end
- end
- end
- end
- end
-end
-
-function findDuplicate(parent, id, property, value)
- for i = 0, id - 1, 1 do
- local obj = parent:get_managed_object(i)
- if obj and obj.properties[property] == value then
- return true
- end
- end
- return false
-end
-
-function createNode(parent, id, type, factory, properties)
- local dev_props = parent.properties
-
- -- set the device id and spa factory name; REQUIRED, do not change
- properties["device.id"] = parent["bound-id"]
- properties["factory.name"] = factory
-
- -- set the default pause-on-idle setting
- properties["node.pause-on-idle"] = false
-
- -- set the node name
- local name =
- (factory:find("sink") and "v4l2_output") or
- (factory:find("source") and "v4l2_input" or factory)
- .. "." ..
- (dev_props["device.name"]:gsub("^v4l2_device%.(.+)", "%1") or
- dev_props["device.name"] or
- dev_props["device.nick"] or
- dev_props["device.alias"] or
- "v4l2-device")
- -- sanitize name
- name = name:gsub("([^%w_%-%.])", "_")
-
- properties["node.name"] = name
-
- -- deduplicate nodes with the same name
- for counter = 2, 99, 1 do
- if findDuplicate(parent, id, "node.name", properties["node.name"]) then
- properties["node.name"] = name .. "." .. counter
- else
- break
- end
- end
-
- -- set the node description
- local desc = dev_props["device.description"] or "v4l2-device"
- desc = desc .. " (V4L2)"
- -- sanitize description, replace ':' with ' '
- properties["node.description"] = desc:gsub("(:)", " ")
-
- -- set the node nick
- local nick = properties["node.nick"] or
- dev_props["device.product.name"] or
- dev_props["api.v4l2.cap.card"] or
- dev_props["device.description"] or
- dev_props["device.nick"]
- properties["node.nick"] = nick:gsub("(:)", " ")
-
- -- set priority
- if not properties["priority.session"] then
- local path = properties["api.v4l2.path"] or "/dev/video100"
- local dev = path:gsub("/dev/video(%d+)", "%1")
- properties["priority.session"] = 1000 - (tonumber(dev) * 10)
- end
-
- -- apply properties from config.rules
- rulesApplyProperties(properties)
- if properties["node.disabled"] then
- return
- end
-
- -- create the node
- local node = Node("spa-node-factory", properties)
- node:activate(Feature.Proxy.BOUND)
- parent:store_managed_object(id, node)
-end
-
-function createDevice(parent, id, type, factory, properties)
- -- ensure the device has an appropriate name
- local name = "v4l2_device." ..
- (properties["device.name"] or
- properties["device.bus-id"] or
- properties["device.bus-path"] or
- tostring(id)):gsub("([^%w_%-%.])", "_")
-
- properties["device.name"] = name
-
- -- deduplicate devices with the same name
- for counter = 2, 99, 1 do
- if findDuplicate(parent, id, "device.name", properties["device.name"]) then
- properties["device.name"] = name .. "." .. counter
- else
- break
- end
- end
-
- -- ensure the device has a description
- properties["device.description"] =
- properties["device.description"]
- or properties["device.product.name"]
- or "Unknown device"
-
- -- apply properties from config.rules
- rulesApplyProperties(properties)
- if properties["device.disabled"] then
- return
- end
-
- -- create the device
- local device = SpaDevice(factory, properties)
- if device then
- device:connect("create-object", createNode)
- device:activate(Feature.SpaDevice.ENABLED | Feature.Proxy.BOUND)
- parent:store_managed_object(id, device)
- else
- Log.warning ("Failed to create '" .. factory .. "' device")
- end
-end
-
-monitor = SpaDevice("api.v4l2.enum.udev", config.properties or {})
-if monitor then
- monitor:connect("create-object", createDevice)
- monitor:activate(Feature.SpaDevice.ENABLED)
-else
- Log.message("PipeWire's V4L SPA missing or broken. Video4Linux not supported.")
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-bluetooth.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-bluetooth.lua
deleted file mode 100644
index f8f69a14..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-bluetooth.lua
+++ /dev/null
@@ -1,398 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Asymptotic Inc.
--- @author Sanchayan Maity
---
--- Based on bt-profile-switch.lua in tests/examples
--- Copyright © 2021 George Kiagiadakis
---
--- Based on bluez-autoswitch in media-session
--- Copyright © 2021 Pauli Virtanen
---
--- SPDX-License-Identifier: MIT
---
--- Checks for the existence of media.role and if present switches the bluetooth
--- profile accordingly. Also see bluez-autoswitch in media-session.
--- The intended logic of the script is as follows.
---
--- When a stream comes in, if it has a Communication or phone role in PulseAudio
--- speak in props, we switch to the highest priority profile that has an Input
--- route available. The reason for this is that we may have microphone enabled
--- non-HFP codecs eg. Faststream.
--- We track the incoming streams with Communication role or the applications
--- specified which do not set the media.role correctly perhaps.
--- When a stream goes away if the list with which we track the streams above
--- is empty, then we revert back to the old profile.
-
-local config = ...
-local use_persistent_storage = config["use-persistent-storage"] or false
-local applications = {}
-local use_headset_profile = config["media-role.use-headset-profile"] or false
-local profile_restore_timeout_msec = 2000
-
-local INVALID = -1
-local timeout_source = nil
-local restore_timeout_source = nil
-
-local state = use_persistent_storage and State("policy-bluetooth") or nil
-local headset_profiles = state and state:load() or {}
-local last_profiles = {}
-
-local active_streams = {}
-local previous_streams = {}
-
-for _, value in ipairs(config["media-role.applications"] or {}) do
- applications[value] = true
-end
-
-metadata_om = ObjectManager {
- Interest {
- type = "metadata",
- Constraint { "metadata.name", "=", "default" },
- }
-}
-
-devices_om = ObjectManager {
- Interest {
- type = "device",
- Constraint { "device.api", "=", "bluez5" },
- }
-}
-
-streams_om = ObjectManager {
- Interest {
- type = "node",
- Constraint { "media.class", "matches", "Stream/Input/Audio", type = "pw-global" },
- -- Do not consider monitor streams
- Constraint { "stream.monitor", "!", "true" }
- }
-}
-
-local function parseParam(param_to_parse, id)
- local param = param_to_parse:parse()
- if param.pod_type == "Object" and param.object_id == id then
- return param.properties
- else
- return nil
- end
-end
-
-local function storeAfterTimeout()
- if not use_persistent_storage then
- return
- end
-
- if timeout_source then
- timeout_source:destroy()
- end
- timeout_source = Core.timeout_add(1000, function ()
- local saved, err = state:save(headset_profiles)
- if not saved then
- Log.warning(err)
- end
- timeout_source = nil
- end)
-end
-
-local function saveHeadsetProfile(device, profile_name)
- local key = "saved-headset-profile:" .. device.properties["device.name"]
- headset_profiles[key] = profile_name
- storeAfterTimeout()
-end
-
-local function getSavedHeadsetProfile(device)
- local key = "saved-headset-profile:" .. device.properties["device.name"]
- return headset_profiles[key]
-end
-
-local function saveLastProfile(device, profile_name)
- last_profiles[device.properties["device.name"]] = profile_name
-end
-
-local function getSavedLastProfile(device)
- return last_profiles[device.properties["device.name"]]
-end
-
-local function isSwitched(device)
- return getSavedLastProfile(device) ~= nil
-end
-
-local function isBluez5AudioSink(sink_name)
- if sink_name and string.find(sink_name, "bluez_output.") ~= nil then
- return true
- end
- return false
-end
-
-local function isBluez5DefaultAudioSink()
- local metadata = metadata_om:lookup()
- local default_audio_sink = metadata:find(0, "default.audio.sink")
- return isBluez5AudioSink(default_audio_sink)
-end
-
-local function findProfile(device, index, name)
- for p in device:iterate_params("EnumProfile") do
- local profile = parseParam(p, "EnumProfile")
- if not profile then
- goto skip_enum_profile
- end
-
- Log.debug("Profile name: " .. profile.name .. ", priority: "
- .. tostring(profile.priority) .. ", index: " .. tostring(profile.index))
- if (index ~= nil and profile.index == index) or
- (name ~= nil and profile.name == name) then
- return profile.priority, profile.index, profile.name
- end
-
- ::skip_enum_profile::
- end
-
- return INVALID, INVALID, nil
-end
-
-local function getCurrentProfile(device)
- for p in device:iterate_params("Profile") do
- local profile = parseParam(p, "Profile")
- if profile then
- return profile.name
- end
- end
-
- return nil
-end
-
-local function highestPrioProfileWithInputRoute(device)
- local profile_priority = INVALID
- local profile_index = INVALID
- local profile_name = nil
-
- for p in device:iterate_params("EnumRoute") do
- local route = parseParam(p, "EnumRoute")
- -- Parse pod
- if not route then
- goto skip_enum_route
- end
-
- if route.direction ~= "Input" then
- goto skip_enum_route
- end
-
- Log.debug("Route with index: " .. tostring(route.index) .. ", direction: "
- .. route.direction .. ", name: " .. route.name .. ", description: "
- .. route.description .. ", priority: " .. route.priority)
- if route.profiles then
- for _, v in pairs(route.profiles) do
- local priority, index, name = findProfile(device, v)
- if priority ~= INVALID then
- if profile_priority < priority then
- profile_priority = priority
- profile_index = index
- profile_name = name
- end
- end
- end
- end
-
- ::skip_enum_route::
- end
-
- return profile_priority, profile_index, profile_name
-end
-
-local function hasProfileInputRoute(device, profile_index)
- for p in device:iterate_params("EnumRoute") do
- local route = parseParam(p, "EnumRoute")
- if route and route.direction == "Input" and route.profiles then
- for _, v in pairs(route.profiles) do
- if v == profile_index then
- return true
- end
- end
- end
- end
- return false
-end
-
-local function switchProfile()
- local index
- local name
-
- if restore_timeout_source then
- restore_timeout_source:destroy()
- restore_timeout_source = nil
- end
-
- for device in devices_om:iterate() do
- if isSwitched(device) then
- goto skip_device
- end
-
- local cur_profile_name = getCurrentProfile(device)
- saveLastProfile(device, cur_profile_name)
-
- _, index, name = findProfile(device, nil, cur_profile_name)
- if hasProfileInputRoute(device, index) then
- Log.info("Current profile has input route, not switching")
- goto skip_device
- end
-
- local saved_headset_profile = getSavedHeadsetProfile(device)
- index = INVALID
- if saved_headset_profile then
- _, index, name = findProfile(device, nil, saved_headset_profile)
- end
- if index == INVALID then
- _, index, name = highestPrioProfileWithInputRoute(device)
- end
-
- if index ~= INVALID then
- local pod = Pod.Object {
- "Spa:Pod:Object:Param:Profile", "Profile",
- index = index
- }
-
- Log.info("Setting profile of '"
- .. device.properties["device.description"]
- .. "' from: " .. cur_profile_name
- .. " to: " .. name)
- device:set_params("Profile", pod)
- else
- Log.warning("Got invalid index when switching profile")
- end
-
- ::skip_device::
- end
-end
-
-local function restoreProfile()
- for device in devices_om:iterate() do
- if isSwitched(device) then
- local profile_name = getSavedLastProfile(device)
- local cur_profile_name = getCurrentProfile(device)
-
- saveLastProfile(device, nil)
-
- if cur_profile_name then
- Log.info("Setting saved headset profile to: " .. cur_profile_name)
- saveHeadsetProfile(device, cur_profile_name)
- end
-
- if profile_name then
- local _, index, name = findProfile(device, nil, profile_name)
-
- if index ~= INVALID then
- local pod = Pod.Object {
- "Spa:Pod:Object:Param:Profile", "Profile",
- index = index
- }
-
- Log.info("Restoring profile of '"
- .. device.properties["device.description"]
- .. "' from: " .. cur_profile_name
- .. " to: " .. name)
- device:set_params("Profile", pod)
- else
- Log.warning("Failed to restore profile")
- end
- end
- end
- end
-end
-
-local function triggerRestoreProfile()
- if restore_timeout_source then
- return
- end
- if next(active_streams) ~= nil then
- return
- end
- restore_timeout_source = Core.timeout_add(profile_restore_timeout_msec, function ()
- restore_timeout_source = nil
- restoreProfile()
- end)
-end
-
--- We consider a Stream of interest to have role Communication if it has
--- media.role set to Communication in props or it is in our list of
--- applications as these applications do not set media.role correctly or at
--- all.
-local function checkStreamStatus(stream)
- local app_name = stream.properties["application.name"]
- local stream_role = stream.properties["media.role"]
-
- if not (stream_role == "Communication" or applications[app_name]) then
- return false
- end
- if not isBluez5DefaultAudioSink() then
- return false
- end
-
- -- If a stream we previously saw stops running, we consider it
- -- inactive, because some applications (Teams) just cork input
- -- streams, but don't close them.
- if previous_streams[stream["bound-id"]] and stream.state ~= "running" then
- return false
- end
-
- return true
-end
-
-local function handleStream(stream)
- if not use_headset_profile then
- return
- end
-
- if checkStreamStatus(stream) then
- active_streams[stream["bound-id"]] = true
- previous_streams[stream["bound-id"]] = true
- switchProfile()
- else
- active_streams[stream["bound-id"]] = nil
- triggerRestoreProfile()
- end
-end
-
-local function handleAllStreams()
- for stream in streams_om:iterate {
- Constraint { "media.class", "matches", "Stream/Input/Audio", type = "pw-global" },
- Constraint { "stream.monitor", "!", "true" }
- } do
- handleStream(stream)
- end
-end
-
-streams_om:connect("object-added", function (_, stream)
- stream:connect("state-changed", function (stream, old_state, cur_state)
- handleStream(stream)
- end)
- stream:connect("params-changed", handleStream)
- handleStream(stream)
-end)
-
-streams_om:connect("object-removed", function (_, stream)
- active_streams[stream["bound-id"]] = nil
- previous_streams[stream["bound-id"]] = nil
- triggerRestoreProfile()
-end)
-
-devices_om:connect("object-added", function (_, device)
- -- Devices are unswitched initially
- if isSwitched(device) then
- saveLastProfile(device, nil)
- end
- handleAllStreams()
-end)
-
-metadata_om:connect("object-added", function (_, metadata)
- metadata:connect("changed", function (m, subject, key, t, value)
- if (use_headset_profile and subject == 0 and key == "default.audio.sink"
- and isBluez5AudioSink(value)) then
- -- If bluez sink is set as default, rescan for active input streams
- handleAllStreams()
- end
- end)
-end)
-
-metadata_om:activate()
-devices_om:activate()
-streams_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-device-profile.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-device-profile.lua
deleted file mode 100644
index af10f9b7..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-device-profile.lua
+++ /dev/null
@@ -1,246 +0,0 @@
--- WirePlumber
---
--- Copyright © 2022 Collabora Ltd.
--- @author Julian Bouzas
---
--- SPDX-License-Identifier: MIT
-
-local self = {}
-self.config = ... or {}
-self.config.persistent = self.config.persistent or {}
-self.config.priorities = self.config.priorities or {}
-self.active_profiles = {}
-self.default_profile_plugin = Plugin.find("default-profile")
-
-function createIntrestObjects(t)
- for _, p in ipairs(t or {}) do
- p.interests = {}
- for _, i in ipairs(p.matches) do
- local interest_desc = { type = "properties" }
- for _, c in ipairs(i) do
- c.type = "pw"
- table.insert(interest_desc, Constraint(c))
- end
- local interest = Interest(interest_desc)
- table.insert(p.interests, interest)
- end
- p.matches = nil
- end
-end
-
--- Preprocess persistent profiles and create Interest objects
-createIntrestObjects(self.config.persistent)
--- Preprocess profile priorities and create Interest objects
-createIntrestObjects(self.config.priorities)
-
--- Checks whether a device profile is persistent or not
-function isProfilePersistent(device_props, profile_name)
- for _, p in ipairs(self.config.persistent or {}) do
- if p.profile_names then
- for _, interest in ipairs(p.interests) do
- if interest:matches(device_props) then
- for _, pn in ipairs(p.profile_names) do
- if pn == profile_name then
- return true
- end
- end
- end
- end
- end
- end
- return false
-end
-
-function parseParam(param, id)
- local parsed = param:parse()
- if parsed.pod_type == "Object" and parsed.object_id == id then
- return parsed.properties
- else
- return nil
- end
-end
-
-function setDeviceProfile (device, dev_id, dev_name, profile)
- if self.active_profiles[dev_id] and
- self.active_profiles[dev_id].index == profile.index then
- Log.info ("Profile " .. profile.name .. " is already set in " .. dev_name)
- return
- end
-
- local param = Pod.Object {
- "Spa:Pod:Object:Param:Profile", "Profile",
- index = profile.index,
- }
- Log.info ("Setting profile " .. profile.name .. " on " .. dev_name)
- device:set_param("Profile", param)
-end
-
-function findDefaultProfile (device)
- local def_name = nil
-
- if self.default_profile_plugin ~= nil then
- def_name = self.default_profile_plugin:call ("get-profile", device)
- end
- if def_name == nil then
- return nil
- end
-
- for p in device:iterate_params("EnumProfile") do
- local profile = parseParam(p, "EnumProfile")
- if profile.name == def_name then
- return profile
- end
- end
-
- return nil
-end
-
--- returns the priorities, if defined
-function getDevicePriorities(device_props, profile_name)
- for _, p in ipairs(self.config.priorities or {}) do
- for _, interest in ipairs(p.interests) do
- if interest:matches(device_props) then
- return p.priorities
- end
- end
- end
-
- return nil
-end
-
--- find profiles based on user preferences.
-function findPreferredProfile(device)
- local priority_table = getDevicePriorities(device.properties)
-
- if not priority_table or #priority_table == 0 then
- return nil
- else
- Log.info("priority table found for device " ..
- device.properties["device.name"])
- end
-
- for _, priority_profile in ipairs(priority_table) do
- for p in device:iterate_params("EnumProfile") do
- device_profile = parseParam(p, "EnumProfile")
- if device_profile.name == priority_profile then
- Log.info("Selected user preferred profile " ..
- device_profile.name .. " for " .. device.properties["device.name"])
- return device_profile
- end
- end
- end
-
- return nil
-end
-
--- find profiles based on inbuilt priorities.
-function findBestProfile(device)
- -- Takes absolute priority if available or unknown
- local profile_prop = device.properties["device.profile"]
- local off_profile = nil
- local best_profile = nil
- local unk_profile = nil
- local profile = nil
-
- for p in device:iterate_params("EnumProfile") do
- profile = parseParam(p, "EnumProfile")
- if profile and profile.name == profile_prop and profile.available ~= "no" then
- return profile
- elseif profile and profile.name ~= "pro-audio" then
- if profile.name == "off" then
- off_profile = profile
- elseif profile.available == "yes" then
- if best_profile == nil or profile.priority > best_profile.priority then
- best_profile = profile
- end
- elseif profile.available ~= "no" then
- if unk_profile == nil or profile.priority > unk_profile.priority then
- unk_profile = profile
- end
- end
- end
- end
-
- if best_profile ~= nil then
- profile = best_profile
- elseif unk_profile ~= nil then
- profile = unk_profile
- elseif off_profile ~= nil then
- profile = off_profile
- end
-
- if profile ~= nil then
- Log.info("Found best profile " .. profile.name .. " for " .. device.properties["device.name"])
- return profile
- else
- return nil
- end
-end
-
-function handleProfiles (device, new_device)
- local dev_id = device["bound-id"]
- local dev_name = device.properties["device.name"]
-
- local def_profile = findDefaultProfile (device)
-
- -- Do not do anything if active profile is both persistent and default
- if not new_device and
- self.active_profiles[dev_id] ~= nil and
- isProfilePersistent (device.properties, self.active_profiles[dev_id].name) and
- def_profile ~= nil and
- self.active_profiles[dev_id].name == def_profile.name
- then
- local active_profile = self.active_profiles[dev_id].name
- Log.info ("Device profile " .. active_profile .. " is persistent for " .. dev_name)
- return
- end
-
- if def_profile ~= nil then
- if def_profile.available == "no" then
- Log.info ("Default profile " .. def_profile.name .. " unavailable for " .. dev_name)
- else
- Log.info ("Found default profile " .. def_profile.name .. " for " .. dev_name)
- setDeviceProfile (device, dev_id, dev_name, def_profile)
- return
- end
- else
- Log.info ("Default profile not found for " .. dev_name)
- end
-
- local best_profile = findPreferredProfile(device)
-
- if not best_profile then
- best_profile = findBestProfile(device)
- end
-
- if best_profile ~= nil then
- setDeviceProfile (device, dev_id, dev_name, best_profile)
- else
- Log.info ("Best profile not found on " .. dev_name)
- end
-end
-
-function onDeviceParamsChanged (device, param_name)
- if param_name == "EnumProfile" then
- handleProfiles (device, false)
- end
-end
-
-self.om = ObjectManager {
- Interest {
- type = "device",
- Constraint { "device.name", "is-present", type = "pw-global" },
- }
-}
-
-self.om:connect("object-added", function (_, device)
- device:connect ("params-changed", onDeviceParamsChanged)
- handleProfiles (device, true)
-end)
-
-self.om:connect("object-removed", function (_, device)
- local dev_id = device["bound-id"]
- self.active_profiles[dev_id] = nil
-end)
-
-self.om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-device-routes.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-device-routes.lua
deleted file mode 100644
index c21c1cce..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-device-routes.lua
+++ /dev/null
@@ -1,487 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author George Kiagiadakis
---
--- Based on default-routes.c from pipewire-media-session
--- Copyright © 2020 Wim Taymans
---
--- SPDX-License-Identifier: MIT
-
-local config = ... or {}
-
--- whether to store state on the file system
-use_persistent_storage = config["use-persistent-storage"] or false
-
--- the default volume to apply
-default_volume = tonumber(config["default-volume"] or 0.4^3)
-default_input_volume = tonumber(config["default-input-volume"] or 1.0)
-
--- table of device info
-dev_infos = {}
-
--- the state storage
-state = use_persistent_storage and State("default-routes") or nil
-state_table = state and state:load() or {}
-
--- simple serializer {"foo", "bar"} -> "foo;bar;"
-function serializeArray(a)
- local str = ""
- for _, v in ipairs(a) do
- str = str .. tostring(v):gsub(";", "\\;") .. ";"
- end
- return str
-end
-
--- simple deserializer "foo;bar;" -> {"foo", "bar"}
-function parseArray(str, convert_value)
- local array = {}
- local val = ""
- local escaped = false
- for i = 1, #str do
- local c = str:sub(i,i)
- if c == '\\' then
- escaped = true
- elseif c == ';' and not escaped then
- val = convert_value and convert_value(val) or val
- table.insert(array, val)
- val = ""
- else
- val = val .. tostring(c)
- escaped = false
- end
- end
- return array
-end
-
-function arrayContains(a, value)
- for _, v in ipairs(a) do
- if v == value then
- return true
- end
- end
- return false
-end
-
-function parseParam(param, id)
- local route = param:parse()
- if route.pod_type == "Object" and route.object_id == id then
- return route.properties
- else
- return nil
- end
-end
-
-function storeAfterTimeout()
- if timeout_source then
- timeout_source:destroy()
- end
- timeout_source = Core.timeout_add(1000, function ()
- local saved, err = state:save(state_table)
- if not saved then
- Log.warning(err)
- end
- timeout_source = nil
- end)
-end
-
-function saveProfile(dev_info, profile_name)
- if not use_persistent_storage then
- return
- end
-
- local routes = {}
- for idx, ri in pairs(dev_info.route_infos) do
- if ri.save then
- table.insert(routes, ri.name)
- end
- end
-
- if #routes > 0 then
- local key = dev_info.name .. ":profile:" .. profile_name
- state_table[key] = serializeArray(routes)
- storeAfterTimeout()
- end
-end
-
-function saveRouteProps(dev_info, route)
- if not use_persistent_storage or not route.props then
- return
- end
-
- local props = route.props.properties
- local key_base = dev_info.name .. ":" ..
- route.direction:lower() .. ":" ..
- route.name .. ":"
-
- state_table[key_base .. "volume"] =
- props.volume and tostring(props.volume) or nil
- state_table[key_base .. "mute"] =
- props.mute and tostring(props.mute) or nil
- state_table[key_base .. "channelVolumes"] =
- props.channelVolumes and serializeArray(props.channelVolumes) or nil
- state_table[key_base .. "channelMap"] =
- props.channelMap and serializeArray(props.channelMap) or nil
- state_table[key_base .. "latencyOffsetNsec"] =
- props.latencyOffsetNsec and tostring(props.latencyOffsetNsec) or nil
- state_table[key_base .. "iec958Codecs"] =
- props.iec958Codecs and serializeArray(props.iec958Codecs) or nil
-
- storeAfterTimeout()
-end
-
-function restoreRoute(device, dev_info, device_id, route)
- -- default props
- local props = {
- "Spa:Pod:Object:Param:Props", "Route",
- mute = false,
- }
-
- if route.direction == "Input" then
- props.channelVolumes = { default_input_volume }
- else
- props.channelVolumes = { default_volume }
- end
-
- -- restore props from persistent storage
- if use_persistent_storage then
- local key_base = dev_info.name .. ":" ..
- route.direction:lower() .. ":" ..
- route.name .. ":"
-
- local str = state_table[key_base .. "volume"]
- props.volume = str and tonumber(str) or props.volume
-
- local str = state_table[key_base .. "mute"]
- props.mute = str and (str == "true") or false
-
- local str = state_table[key_base .. "channelVolumes"]
- props.channelVolumes = str and parseArray(str, tonumber) or props.channelVolumes
-
- local str = state_table[key_base .. "channelMap"]
- props.channelMap = str and parseArray(str) or props.channelMap
-
- local str = state_table[key_base .. "latencyOffsetNsec"]
- props.latencyOffsetNsec = str and math.tointeger(str) or props.latencyOffsetNsec
-
- local str = state_table[key_base .. "iec958Codecs"]
- props.iec958Codecs = str and parseArray(str) or props.iec958Codecs
- end
-
- -- convert arrays to Spa Pod
- if props.channelVolumes then
- table.insert(props.channelVolumes, 1, "Spa:Float")
- props.channelVolumes = Pod.Array(props.channelVolumes)
- end
- if props.channelMap then
- table.insert(props.channelMap, 1, "Spa:Enum:AudioChannel")
- props.channelMap = Pod.Array(props.channelMap)
- end
- if props.iec958Codecs then
- table.insert(props.iec958Codecs, 1, "Spa:Enum:AudioIEC958Codec")
- props.iec958Codecs = Pod.Array(props.iec958Codecs)
- end
-
- -- construct Route param
- local param = Pod.Object {
- "Spa:Pod:Object:Param:Route", "Route",
- index = route.index,
- device = device_id,
- props = Pod.Object(props),
- save = route.save,
- }
-
- Log.debug(param, "setting route on " .. tostring(device))
- device:set_param("Route", param)
-
- route.prev_active = true
- route.active = true
-end
-
-function findActiveDeviceIDs(profile)
- -- parses the classes from the profile and returns the device IDs
- ----- sample structure, should return { 0, 8 } -----
- -- classes:
- -- 1: 2
- -- 2:
- -- 1: Audio/Source
- -- 2: 1
- -- 3: card.profile.devices
- -- 4:
- -- 1: 0
- -- pod_type: Array
- -- value_type: Spa:Int
- -- pod_type: Struct
- -- 3:
- -- 1: Audio/Sink
- -- 2: 1
- -- 3: card.profile.devices
- -- 4:
- -- 1: 8
- -- pod_type: Array
- -- value_type: Spa:Int
- -- pod_type: Struct
- -- pod_type: Struct
- local active_ids = {}
- if type(profile.classes) == "table" and profile.classes.pod_type == "Struct" then
- for _, p in ipairs(profile.classes) do
- if type(p) == "table" and p.pod_type == "Struct" then
- local i = 1
- while true do
- local k, v = p[i], p[i+1]
- i = i + 2
- if not k or not v then
- break
- end
- if k == "card.profile.devices" and
- type(v) == "table" and v.pod_type == "Array" then
- for _, dev_id in ipairs(v) do
- table.insert(active_ids, dev_id)
- end
- end
- end
- end
- end
- end
- return active_ids
-end
-
--- returns an array of the route names that were previously selected
--- for the given device and profile
-function getStoredProfileRoutes(dev_name, profile_name)
- local key = dev_name .. ":profile:" .. profile_name
- local str = state_table[key]
- return str and parseArray(str) or {}
-end
-
--- find a route that was previously stored for a device_id
--- spr needs to be the array returned from getStoredProfileRoutes()
-function findSavedRoute(dev_info, device_id, spr)
- for idx, ri in pairs(dev_info.route_infos) do
- if arrayContains(ri.devices, device_id) and
- (ri.profiles == nil or arrayContains(ri.profiles, dev_info.active_profile)) and
- arrayContains(spr, ri.name) then
- return ri
- end
- end
- return nil
-end
-
--- find the best route for a given device_id, based on availability and priority
-function findBestRoute(dev_info, device_id)
- local best_avail = nil
- local best_unk = nil
- for idx, ri in pairs(dev_info.route_infos) do
- if arrayContains(ri.devices, device_id) and
- (ri.profiles == nil or arrayContains(ri.profiles, dev_info.active_profile)) then
- if ri.available == "yes" or ri.available == "unknown" then
- if ri.direction == "Output" and ri.available ~= ri.prev_available then
- best_avail = ri
- ri.save = true
- break
- elseif ri.available == "yes" then
- if (best_avail == nil or ri.priority > best_avail.priority) then
- best_avail = ri
- end
- elseif best_unk == nil or ri.priority > best_unk.priority then
- best_unk = ri
- end
- end
- end
- end
- return best_avail or best_unk
-end
-
-function restoreProfileRoutes(device, dev_info, profile, profile_changed)
- Log.info(device, "restore routes for profile " .. profile.name)
-
- local active_ids = findActiveDeviceIDs(profile)
- local spr = getStoredProfileRoutes(dev_info.name, profile.name)
-
- for _, device_id in ipairs(active_ids) do
- Log.info(device, "restoring device " .. device_id);
-
- local route = nil
-
- -- restore routes selection for the newly selected profile
- -- don't bother if spr is empty, there is no point
- if profile_changed and #spr > 0 then
- route = findSavedRoute(dev_info, device_id, spr)
- if route then
- -- we found a saved route
- if route.available == "no" then
- Log.info(device, "saved route '" .. route.name .. "' not available")
- -- not available, try to find next best
- route = nil
- else
- Log.info(device, "found saved route: " .. route.name)
- -- make sure we save it again
- route.save = true
- end
- end
- end
-
- -- we could not find a saved route, try to find a new best
- if not route then
- route = findBestRoute(dev_info, device_id)
- if not route then
- Log.info(device, "can't find best route")
- else
- Log.info(device, "found best route: " .. route.name)
- end
- end
-
- -- restore route
- if route then
- restoreRoute(device, dev_info, device_id, route)
- end
- end
-end
-
-function findRouteInfo(dev_info, route, return_new)
- local ri = dev_info.route_infos[route.index]
- if not ri and return_new then
- ri = {
- index = route.index,
- name = route.name,
- direction = route.direction,
- devices = route.devices or {},
- profiles = route.profiles,
- priority = route.priority or 0,
- available = route.available or "unknown",
- prev_available = route.available or "unknown",
- active = false,
- prev_active = false,
- save = false,
- }
- end
- return ri
-end
-
-function handleDevice(device)
- local dev_info = dev_infos[device["bound-id"]]
- local new_route_infos = {}
- local avail_routes_changed = false
- local profile = nil
-
- -- get current profile
- for p in device:iterate_params("Profile") do
- profile = parseParam(p, "Profile")
- end
-
- -- look at all the routes and update/reset cached information
- for p in device:iterate_params("EnumRoute") do
- -- parse pod
- local route = parseParam(p, "EnumRoute")
- if not route then
- goto skip_enum_route
- end
-
- -- find cached route information
- local route_info = findRouteInfo(dev_info, route, true)
-
- -- update properties
- route_info.prev_available = route_info.available
- if route_info.available ~= route.available then
- Log.info(device, "route " .. route.name .. " available changed " ..
- route_info.available .. " -> " .. route.available)
- route_info.available = route.available
- if profile and arrayContains(route.profiles, profile.index) then
- avail_routes_changed = true
- end
- end
- route_info.prev_active = route_info.active
- route_info.active = false
- route_info.save = false
-
- -- store
- new_route_infos[route.index] = route_info
-
- ::skip_enum_route::
- end
-
- -- replace old route_infos to lose old routes
- -- that no longer exist on the device
- dev_info.route_infos = new_route_infos
- new_route_infos = nil
-
- -- check for changes in the active routes
- for p in device:iterate_params("Route") do
- local route = parseParam(p, "Route")
- if not route then
- goto skip_route
- end
-
- -- get cached route info and at the same time
- -- ensure that the route is also in EnumRoute
- local route_info = findRouteInfo(dev_info, route, false)
- if not route_info then
- goto skip_route
- end
-
- -- update state
- route_info.active = true
- route_info.save = route.save
-
- if not route_info.prev_active then
- -- a new route is now active, restore the volume and
- -- make sure we save this as a preferred route
- Log.info(device, "new active route found " .. route.name)
- restoreRoute(device, dev_info, route.device, route_info)
- elseif route.save then
- -- just save route properties
- Log.info(device, "storing route props for " .. route.name)
- saveRouteProps(dev_info, route)
- end
-
- ::skip_route::
- end
-
- -- restore routes for profile
- if profile then
- local profile_changed = (dev_info.active_profile ~= profile.index)
-
- -- if the profile changed, restore routes for that profile
- -- if any of the routes of the current profile changed in availability,
- -- then try to select a new "best" route for each device and ignore
- -- what was stored
- if profile_changed or avail_routes_changed then
- dev_info.active_profile = profile.index
- restoreProfileRoutes(device, dev_info, profile, profile_changed)
- end
-
- saveProfile(dev_info, profile.name)
- end
-end
-
-om = ObjectManager {
- Interest {
- type = "device",
- Constraint { "device.name", "is-present", type = "pw-global" },
- }
-}
-
-om:connect("objects-changed", function (om)
- local new_dev_infos = {}
- for device in om:iterate() do
- local dev_info = dev_infos[device["bound-id"]]
- -- new device appeared
- if not dev_info then
- dev_info = {
- name = device.properties["device.name"],
- active_profile = -1,
- route_infos = {},
- }
- dev_infos[device["bound-id"]] = dev_info
-
- device:connect("params-changed", handleDevice)
- handleDevice(device)
- end
-
- new_dev_infos[device["bound-id"]] = dev_info
- end
- -- replace list to get rid of dev_info for devices that no longer exist
- dev_infos = new_dev_infos
-end)
-
-om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-dsp.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-dsp.lua
deleted file mode 100644
index ce23a67a..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-dsp.lua
+++ /dev/null
@@ -1,86 +0,0 @@
--- WirePlumber
---
--- Copyright © 2022-2023 The WirePlumber project contributors
--- @author Dmitry Sharshakov
---
--- SPDX-License-Identifier: MIT
-
-local config = ... or {}
-config.rules = config.rules or {}
-
-for _, r in ipairs(config.rules) do
- r.interests = {}
- for _, i in ipairs(r.matches) do
- local interest_desc = { type = "properties" }
-
- 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
-nodes_om = ObjectManager {
- Interest { type = "node" },
-}
-
-clients_om = ObjectManager {
- Interest { type = "client" }
-}
-
-filter_chains = {}
-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["global-properties"]) then
- local id = node["global-properties"]["object.id"]
-
- 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)
- 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
-
- end
- end
- end
-end)
-
-nodes_om:connect("object-removed", function (om, node)
- local id = node["global-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")
- end
-end)
-
-clients_om:connect("object-added", function (om, client)
- for id, _ in pairs(hidden_nodes) do
- if not client["properties"]["wireplumber.daemon"] then
- client:update_permissions { [id] = "-" }
- end
- end
-end)
-
-nodes_om:activate()
-clients_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-client-links.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-client-links.lua
deleted file mode 100644
index eaa1c088..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-client-links.lua
+++ /dev/null
@@ -1,218 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author George Kiagiadakis
---
--- SPDX-License-Identifier: MIT
-
-local config = ... or {}
-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
- for r, p in pairs(config.roles) do
- if type(p.alias) == "table" then
- for i = 1, #(p.alias), 1 do
- if role == p.alias[i] then
- return r
- end
- end
- end
- end
- end
- return role
-end
-
-function priorityForRole(role)
- local r = role and config.roles[role] or nil
- return r and r.priority or 0
-end
-
-function getAction(dominant_role, other_role)
- -- default to "mix" if the role is not configured
- if not dominant_role or not config.roles[dominant_role] then
- return "mix"
- end
-
- local role_config = config.roles[dominant_role]
- return role_config["action." .. other_role]
- or role_config["action.default"]
- 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 getSuspendPlaybackMetadata ()
- local suspend = false
- local metadata = metadata_om:lookup()
- if metadata then
- local value = metadata:find(0, "suspend.playback")
- if value then
- suspend = value == "1" and true or false
- end
- end
- return suspend
-end
-
-function rescan()
- local links = {
- ["Audio/Source"] = {},
- ["Audio/Sink"] = {},
- ["Video/Source"] = {},
- }
-
- Log.info("Rescan endpoint links")
-
- -- deactivate all links if suspend playback metadata is present
- local suspend = getSuspendPlaybackMetadata()
- for silink in silinks_om:iterate() do
- if suspend then
- silink:deactivate(Feature.SessionItem.ACTIVE)
- end
- end
-
- -- gather info about links
- for silink in silinks_om:iterate() do
- local props = silink.properties
- local role = props["media.role"]
- local target_class = props["target.media.class"]
- local plugged = props["item.plugged.usec"]
- local active =
- ((silink:get_active_features() & Feature.SessionItem.ACTIVE) ~= 0)
- if links[target_class] then
- table.insert(links[target_class], {
- silink = silink,
- role = findRole(role),
- active = active,
- priority = priorityForRole(role),
- plugged = plugged and tonumber(plugged) or 0
- })
- end
- end
-
- local function compareLinks(l1, l2)
- return (l1.priority > l2.priority) or
- ((l1.priority == l2.priority) and (l1.plugged > l2.plugged))
- end
-
- for media_class, v in pairs(links) do
- -- sort on priority and stream creation time
- table.sort(v, compareLinks)
-
- -- apply actions
- local first_link = v[1]
- if first_link then
- for i = 2, #v, 1 do
- local action = getAction(first_link.role, v[i].role)
- if action == "cork" then
- if v[i].active then
- v[i].silink:deactivate(Feature.SessionItem.ACTIVE)
- end
- elseif action == "mix" then
- if not v[i].active and not suspend then
- v[i].silink:activate(Feature.SessionItem.ACTIVE, pendingOperation())
- end
- restoreVolume(v[i].role, media_class)
- elseif action == "duck" then
- if not v[i].active and not suspend then
- v[i].silink:activate(Feature.SessionItem.ACTIVE, pendingOperation())
- end
- duck(v[i].role, media_class)
- else
- Log.warning("Unknown action: " .. action)
- end
- end
-
- if not first_link.active and not suspend then
- first_link.silink:activate(Feature.SessionItem.ACTIVE, pendingOperation())
- end
- restoreVolume(first_link.role, media_class)
- end
- end
-end
-
-pending_ops = 0
-pending_rescan = false
-
-function pendingOperation()
- pending_ops = pending_ops + 1
- return function()
- pending_ops = pending_ops - 1
- if pending_ops == 0 and pending_rescan then
- pending_rescan = false
- rescan()
- end
- end
-end
-
-function maybeRescan()
- if pending_ops == 0 then
- rescan()
- else
- pending_rescan = true
- end
-end
-
-silinks_om = ObjectManager {
- Interest {
- type = "SiLink",
- Constraint { "is.policy.endpoint.client.link", "=", true },
- },
-}
-silinks_om:connect("objects-changed", maybeRescan)
-silinks_om:activate()
-
--- enable ducking if mixer-api is loaded
-mixer_api = Plugin.find("mixer-api")
-if mixer_api then
- endpoints_om = ObjectManager {
- Interest { type = "endpoint" },
- }
- endpoints_om:activate()
-end
-
-metadata_om = ObjectManager {
- Interest {
- type = "metadata",
- Constraint { "metadata.name", "=", "default" },
- }
-}
-metadata_om:connect("object-added", function (om, metadata)
- metadata:connect("changed", function (m, subject, key, t, value)
- if key == "suspend.playback" then
- maybeRescan()
- end
- end)
-end)
-metadata_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-client.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-client.lua
deleted file mode 100644
index 0b71b028..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-client.lua
+++ /dev/null
@@ -1,261 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author Julian Bouzas
---
--- SPDX-License-Identifier: MIT
-
--- Receive script arguments from config.lua
-local config = ... or {}
-config.roles = config.roles or {}
-
-local self = {}
-self.scanning = false
-self.pending_rescan = false
-
-function rescan ()
- for si in linkables_om:iterate() do
- handleLinkable (si)
- end
-end
-
-function scheduleRescan ()
- if self.scanning then
- self.pending_rescan = true
- return
- end
-
- self.scanning = true
- rescan ()
- self.scanning = false
-
- if self.pending_rescan then
- self.pending_rescan = false
- Core.sync(function ()
- scheduleRescan ()
- end)
- end
-end
-
-function findRole(role, tmc)
- if role and not config.roles[role] then
- -- find the role with matching alias
- for r, p in pairs(config.roles) do
- -- default media class can be overridden in the role config data
- mc = p["media.class"] or "Audio/Sink"
- if (type(p.alias) == "table" and tmc == mc) then
- for i = 1, #(p.alias), 1 do
- if role == p.alias[i] then
- return r
- end
- end
- end
- end
-
- -- otherwise get the lowest priority role
- local lowest_priority_p = nil
- local lowest_priority_r = nil
- for r, p in pairs(config.roles) do
- mc = p["media.class"] or "Audio/Sink"
- if tmc == mc and (lowest_priority_p == nil or
- p.priority < lowest_priority_p.priority) then
- lowest_priority_p = p
- lowest_priority_r = r
- end
- end
- return lowest_priority_r
- end
- return role
-end
-
-function findTargetEndpoint (node, media_class, role)
- local target_class_assoc = {
- ["Stream/Input/Audio"] = "Audio/Source",
- ["Stream/Output/Audio"] = "Audio/Sink",
- ["Stream/Input/Video"] = "Video/Source",
- }
- local media_role = nil
- local highest_priority = -1
- local target = nil
-
- -- get target media class
- local target_media_class = target_class_assoc[media_class]
- if not target_media_class then
- return nil
- end
-
- -- find highest priority endpoint by role
- media_role = findRole(role, target_media_class)
- for si_target_ep in endpoints_om:iterate {
- Constraint { "role", "=", media_role, type = "pw-global" },
- Constraint { "media.class", "=", target_media_class, type = "pw-global" },
- } do
- local priority = tonumber(si_target_ep.properties["priority"])
- if priority > highest_priority then
- highest_priority = priority
- target = si_target_ep
- end
- end
-
- return target
-end
-
-function createLink (si, si_target_ep)
- local out_item = nil
- local in_item = nil
- local si_props = si.properties
- local target_ep_props = si_target_ep.properties
-
- if si_props["item.node.direction"] == "output" then
- -- playback
- out_item = si
- in_item = si_target_ep
- else
- -- capture
- out_item = si_target_ep
- in_item = si
- end
-
- Log.info (string.format("link %s <-> %s",
- tostring(si_props["node.name"]),
- tostring(target_ep_props["name"])))
-
- -- create and configure link
- local si_link = SessionItem ( "si-standard-link" )
- if not si_link:configure {
- ["out.item"] = out_item,
- ["in.item"] = in_item,
- ["out.item.port.context"] = "output",
- ["in.item.port.context"] = "input",
- ["is.policy.endpoint.client.link"] = true,
- ["media.role"] = target_ep_props["role"],
- ["target.media.class"] = target_ep_props["media.class"],
- ["item.plugged.usec"] = si_props["item.plugged.usec"],
- } then
- Log.warning (si_link, "failed to configure si-standard-link")
- return
- end
-
- -- register
- si_link:register()
-end
-
-function checkLinkable (si)
- -- only handle session items that has a node associated proxy
- local node = si:get_associated_proxy ("node")
- if not node or not node.properties then
- return false
- end
-
- -- only handle stream session items
- local media_class = node.properties["media.class"]
- if not media_class or not string.find (media_class, "Stream") then
- return false
- end
-
- -- Determine if we can handle item by this policy
- if endpoints_om:get_n_objects () == 0 then
- Log.debug (si, "item won't be handled by this policy")
- return false
- end
-
- return true
-end
-
-function handleLinkable (si)
- if not checkLinkable (si) then
- return
- end
-
- local node = si:get_associated_proxy ("node")
- local media_class = node.properties["media.class"] or ""
- local media_role = node.properties["media.role"] or "Default"
- Log.info (si, "handling item " .. tostring(node.properties["node.name"]) ..
- " with role " .. media_role)
-
- -- find proper target endpoint
- local si_target_ep = findTargetEndpoint (node, media_class, media_role)
- if not si_target_ep then
- Log.info (si, "... target endpoint not found")
- return
- end
-
- -- Check if item is linked to proper target, otherwise re-link
- for link in links_om:iterate() do
- local out_id = tonumber(link.properties["out.item.id"])
- local in_id = tonumber(link.properties["in.item.id"])
- if out_id == si.id or in_id == si.id then
- local is_out = out_id == si.id and true or false
- for peer_ep in endpoints_om:iterate() do
- if peer_ep.id == (is_out and in_id or out_id) then
-
- if peer_ep.id == si_target_ep.id then
- Log.info (si, "... already linked to proper target endpoint")
- return
- end
-
- -- remove old link if active, otherwise schedule rescan
- if ((link:get_active_features() & Feature.SessionItem.ACTIVE) ~= 0) then
- link:remove ()
- Log.info (si, "... moving to new target")
- else
- scheduleRescan ()
- Log.info (si, "... scheduled rescan")
- return
- end
-
- end
- end
- end
- end
-
- -- create new link
- createLink (si, si_target_ep)
-end
-
-function unhandleLinkable (si)
- if not checkLinkable (si) then
- return
- end
-
- local node = si:get_associated_proxy ("node")
- Log.info (si, "unhandling item " .. tostring(node.properties["node.name"]))
-
- -- remove any links associated with this item
- for silink in links_om:iterate() do
- local out_id = tonumber (silink.properties["out.item.id"])
- local in_id = tonumber (silink.properties["in.item.id"])
- if out_id == si.id or in_id == si.id then
- silink:remove ()
- Log.info (silink, "... link removed")
- end
- end
-end
-
-endpoints_om = ObjectManager { Interest { type = "SiEndpoint" }}
-linkables_om = ObjectManager { Interest { type = "SiLinkable",
- -- only handle si-audio-adapter and si-node
- Constraint {
- "item.factory.name", "=", "si-audio-adapter", type = "pw-global" },
- Constraint {
- "active-features", "!", 0, type = "gobject" },
- Constraint {
- "node.link-group", "-" },
- }
-}
-links_om = ObjectManager { Interest { type = "SiLink",
- -- only handle links created by this policy
- Constraint { "is.policy.endpoint.client.link", "=", true, type = "pw-global" },
-} }
-
-linkables_om:connect("objects-changed", function (om)
- scheduleRescan ()
-end)
-
-linkables_om:connect("object-removed", function (om, si)
- unhandleLinkable (si)
-end)
-
-endpoints_om:activate()
-linkables_om:activate()
-links_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-device.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-device.lua
deleted file mode 100644
index 4440c17c..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-endpoint-device.lua
+++ /dev/null
@@ -1,285 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author Julian Bouzas
---
--- SPDX-License-Identifier: MIT
-
--- Receive script arguments from config.lua
-local config = ... or {}
-
--- ensure config.move and config.follow are not nil
-config.move = config.move or false
-config.follow = config.follow or false
-
-local self = {}
-self.scanning = false
-self.pending_rescan = false
-
-function rescan ()
- -- check endpoints and register new links
- for si_ep in endpoints_om:iterate() do
- handleLinkable(si_ep)
- end
-
- for filter in streams_om:iterate {
- Constraint { "node.link-group", "+" },
- } do
- handleFilter(filter)
- end
-end
-
-function scheduleRescan ()
- if self.scanning then
- self.pending_rescan = true
- return
- end
-
- self.scanning = true
- rescan ()
- self.scanning = false
-
- if self.pending_rescan then
- self.pending_rescan = false
- Core.sync(function ()
- scheduleRescan ()
- end)
- end
-end
-
-function findFilterTarget (props)
- for si_target in linkables_om:iterate {
- -- exclude filter targets
- Constraint { "node.link-group", "+" },
- } do
- local si_props = si_target.properties
- if si_props["target.endpoint"] and si_props["target.endpoint"] == props["name"] then
- return si_target
- end
- end
-end
-
-function findTargetByDefaultNode (target_media_class)
- local def_id = default_nodes:call("get-default-node", target_media_class)
- if def_id ~= Id.INVALID then
- for si_target in linkables_om:iterate {
- -- exclude filter targets
- Constraint { "node.link-group", "-" },
- } do
- local target_node = si_target:get_associated_proxy ("node")
- if target_node["bound-id"] == def_id then
- return si_target
- end
- end
- end
- return nil
-end
-
-function findTargetByFirstAvailable (target_media_class)
- for si_target in linkables_om:iterate {
- -- exclude filter targets
- Constraint { "node.link-group", "-" },
- } do
- local target_node = si_target:get_associated_proxy ("node")
- if target_node.properties["media.class"] == target_media_class then
- return si_target
- end
- end
- return nil
-end
-
-function findUndefinedTarget (si_ep)
- local media_class = si_ep.properties["media.class"]
- local target_class_assoc = {
- ["Audio/Source"] = "Audio/Source",
- ["Stream/Output/Audio"] = "Audio/Sink",
- ["Audio/Sink"] = "Audio/Sink",
- ["Video/Source"] = "Video/Source",
- }
- local target_media_class = target_class_assoc[media_class]
- if not target_media_class then
- return nil
- end
-
- local si_target = findFilterTarget (si_ep.properties)
- if not si_target then
- si_target = findTargetByDefaultNode (target_media_class)
- end
- if not si_target then
- si_target = findTargetByFirstAvailable (target_media_class)
- end
- return si_target
-end
-
-function createLink (si_ep, si_target)
- local out_item = nil
- local in_item = nil
- local ep_props = si_ep.properties
- local target_props = si_target.properties
-
- if target_props["item.node.direction"] == "input" then
- -- playback
- out_item = si_ep
- in_item = si_target
- else
- -- capture
- in_item = si_ep
- out_item = si_target
- end
-
- local link_string = string.format("link %s <-> %s ",
- (is_filter and ep_props["node.name"] or ep_props["name"]),
- target_props["node.name"])
-
- Log.info(si_link, link_string)
-
- -- create and configure link
- local si_link = SessionItem ( "si-standard-link" )
- if not si_link:configure {
- ["out.item"] = out_item,
- ["in.item"] = in_item,
- ["out.item.port.context"] = "output",
- ["in.item.port.context"] = "input",
- ["is.policy.endpoint.device.link"] = true,
- } then
- Log.warning (si_link, "failed to configure si-standard-link")
- return
- end
-
- -- register
- si_link:register ()
-
- Log.info (si_link, " activating link " .. link_string)
-
- -- activate
- si_link:activate (Feature.SessionItem.ACTIVE, function (l, e)
- if e then
- Log.warning (l, "failed to activate link: " .. link_string .. tostring(e))
- l:remove ()
- else
- Log.info (l, "activated link " .. link_string)
- end
- end)
-end
-
-function handleFilter(filter)
- handleLinkable(filter)
-end
-
-function handleLinkable (si)
- local si_props = si.properties
- local is_filter = (si_props["node.link-group"] ~= nil)
- if is_filter then
- Log.info (si, "handling filter " .. si_props["node.name"])
- else
- Log.info (si, "handling endpoint " .. si_props["name"])
- end
-
- -- find proper target item
- local si_target = findUndefinedTarget (si)
- if not si_target then
- Log.info (si, "... target item not found")
- return
- end
-
- -- Check if item is linked to proper target, otherwise re-link
- for link in links_om:iterate() do
- local out_id = tonumber(link.properties["out.item.id"])
- local in_id = tonumber(link.properties["in.item.id"])
- if out_id == si.id or in_id == si.id then
- local is_out = out_id == si.id and true or false
- for peer in linkables_om:iterate() do
- if peer.id == (is_out and in_id or out_id) then
-
- if peer.id == si_target.id then
- Log.info (si, "... already linked to proper target")
- return
- end
-
- -- remove old link if active, otherwise schedule rescan
- if ((link:get_active_features() & Feature.SessionItem.ACTIVE) ~= 0) then
- link:remove ()
- Log.info (si, "... moving to new target")
- else
- scheduleRescan ()
- Log.info (si, "... scheduled rescan")
- return
- end
-
- end
- end
- end
- end
-
- -- create new link
- createLink (si, si_target)
-end
-
-function unhandleLinkable (si)
- si_props = si.properties
-
- Log.info (si, string.format("unhandling item: %s (%s)",
- tostring(si_props["node.name"]), tostring(si_props["node.id"])))
-
- -- remove any links associated with this item
- for silink in links_om:iterate() do
- local out_id = tonumber (silink.properties["out.item.id"])
- local in_id = tonumber (silink.properties["in.item.id"])
- if out_id == si.id or in_id == si.id then
- silink:remove ()
- Log.info (silink, "... link removed")
- end
- end
-end
-
-default_nodes = Plugin.find("default-nodes-api")
-endpoints_om = ObjectManager { Interest { type = "SiEndpoint" }}
-linkables_om = ObjectManager {
- Interest {
- type = "SiLinkable",
- -- only handle device si-audio-adapter items
- Constraint { "item.factory.name", "=", "si-audio-adapter", type = "pw-global" },
- Constraint { "item.node.type", "=", "device", type = "pw-global" },
- Constraint { "active-features", "!", 0, type = "gobject" },
- }
-}
-streams_om = ObjectManager {
- Interest {
- type = "SiLinkable",
- -- only handle stream si-audio-adapter items
- Constraint { "item.factory.name", "=", "si-audio-adapter", type = "pw-global" },
- Constraint { "active-features", "!", 0, type = "gobject" },
- Constraint { "media.class", "=", "Stream/Output/Audio" },
- }
-}
-links_om = ObjectManager {
- Interest {
- type = "SiLink",
- -- only handle links created by this policy
- Constraint { "is.policy.endpoint.device.link", "=", true, type = "pw-global" },
- }
-}
-
--- listen for default node changes if config.follow is enabled
-if config.follow then
- default_nodes:connect("changed", function (p)
- scheduleRescan ()
- end)
-end
-
-linkables_om:connect("objects-changed", function (om)
- scheduleRescan ()
-end)
-
-endpoints_om:connect("object-added", function (om)
- scheduleRescan ()
-end)
-
-linkables_om:connect("object-removed", function (om, si)
- unhandleLinkable (si)
-end)
-
-endpoints_om:activate()
-linkables_om:activate()
-links_om:activate()
-streams_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-node.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-node.lua
deleted file mode 100644
index 99ad8473..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/policy-node.lua
+++ /dev/null
@@ -1,1012 +0,0 @@
--- WirePlumber
---
--- Copyright © 2020 Collabora Ltd.
--- @author Julian Bouzas
---
--- SPDX-License-Identifier: MIT
-
--- Receive script arguments from config.lua
-local config = ... or {}
-
--- ensure config.move and config.follow are not nil
-config.move = config.move or false
-config.follow = config.follow or false
-config.filter_forward_format = config["filter.forward-format"] or false
-
-local self = {}
-self.scanning = false
-self.pending_rescan = false
-self.events_skipped = false
-self.pending_error_timer = nil
-
-function rescan()
- for si in linkables_om:iterate() do
- handleLinkable (si)
- end
-end
-
-function scheduleRescan ()
- if self.scanning then
- self.pending_rescan = true
- return
- end
-
- self.scanning = true
- rescan ()
- self.scanning = false
-
- if self.pending_rescan then
- self.pending_rescan = false
- Core.sync(function ()
- scheduleRescan ()
- end)
- end
-end
-
-function parseBool(var)
- return var and (var:lower() == "true" or var == "1")
-end
-
-function createLink (si, si_target, passthrough, exclusive)
- local out_item = nil
- local in_item = nil
- local si_props = si.properties
- local target_props = si_target.properties
- local si_id = si.id
-
- -- break rescan if tried more than 5 times with same target
- if si_flags[si_id].failed_peer_id ~= nil and
- si_flags[si_id].failed_peer_id == si_target.id and
- si_flags[si_id].failed_count ~= nil and
- si_flags[si_id].failed_count > 5 then
- Log.warning (si, "tried to link on last rescan, not retrying")
- return
- end
-
- if si_props["item.node.direction"] == "output" then
- -- playback
- out_item = si
- in_item = si_target
- else
- -- capture
- in_item = si
- out_item = si_target
- end
-
- Log.info (
- string.format("link %s <-> %s passthrough:%s, exclusive:%s",
- tostring(si_props["node.name"]),
- tostring(target_props["node.name"]),
- tostring(passthrough), tostring(exclusive)))
-
- -- create and configure link
- local si_link = SessionItem ( "si-standard-link" )
- if not si_link:configure {
- ["out.item"] = out_item,
- ["in.item"] = in_item,
- ["passthrough"] = passthrough,
- ["exclusive"] = exclusive,
- ["out.item.port.context"] = "output",
- ["in.item.port.context"] = "input",
- ["is.policy.item.link"] = true,
- } then
- Log.warning (si_link, "failed to configure si-standard-link")
- return
- end
-
- si_link:connect("link-error", function (_, error_msg)
- local ids = {si_id}
- if si_flags[si_id] ~= nil then
- table.insert (ids, si_flags[si_id].peer_id)
- end
-
- for _, id in ipairs (ids) do
- local si = linkables_om:lookup {
- Constraint { "id", "=", id, type = "gobject" },
- }
- if si then
- local node = si:get_associated_proxy ("node")
- local client_id = node.properties["client.id"]
- if client_id then
- local client = clients_om:lookup {
- Constraint { "bound-id", "=", client_id, type = "gobject" }
- }
- if client then
- Log.info (node, "sending client error: " .. error_msg)
- client:send_error (node["bound-id"], -32, error_msg)
- end
- end
- end
- end
- end)
-
- -- register
- si_flags[si_id].peer_id = si_target.id
- si_flags[si_id].failed_peer_id = si_target.id
- if si_flags[si_id].failed_count ~= nil then
- si_flags[si_id].failed_count = si_flags[si_id].failed_count + 1
- else
- si_flags[si_id].failed_count = 1
- end
- si_link:register ()
-
- -- activate
- si_link:activate (Feature.SessionItem.ACTIVE, function (l, e)
- if e then
- Log.info (l, "failed to activate si-standard-link: " .. tostring(e))
- if si_flags[si_id] ~= nil then
- si_flags[si_id].peer_id = nil
- end
- l:remove ()
- else
- if si_flags[si_id] ~= nil then
- si_flags[si_id].failed_peer_id = nil
- si_flags[si_id].failed_count = 0
- end
- Log.info (l, "activated si-standard-link")
- end
- scheduleRescan()
- end)
-end
-
-function isLinked(si_target)
- local target_id = si_target.id
- local linked = false
- local exclusive = false
-
- for l in links_om:iterate() do
- local p = l.properties
- local out_id = tonumber(p["out.item.id"])
- local in_id = tonumber(p["in.item.id"])
- linked = (out_id == target_id) or (in_id == target_id)
- if linked then
- exclusive = parseBool(p["exclusive"]) or parseBool(p["passthrough"])
- break
- end
- end
- return linked, exclusive
-end
-
-function canPassthrough (si, si_target)
- -- both nodes must support encoded formats
- if not parseBool(si.properties["item.node.supports-encoded-fmts"])
- or not parseBool(si_target.properties["item.node.supports-encoded-fmts"]) then
- return false
- end
-
- -- make sure that the nodes have at least one common non-raw format
- local n1 = si:get_associated_proxy ("node")
- local n2 = si_target:get_associated_proxy ("node")
- for p1 in n1:iterate_params("EnumFormat") do
- local p1p = p1:parse()
- if p1p.properties.mediaSubtype ~= "raw" then
- for p2 in n2:iterate_params("EnumFormat") do
- if p1:filter(p2) then
- return true
- end
- end
- end
- end
- return false
-end
-
-function canLink (properties, si_target)
- local target_properties = si_target.properties
-
- -- nodes must have the same media type
- if properties["media.type"] ~= target_properties["media.type"] then
- return false
- end
-
- -- nodes must have opposite direction, or otherwise they must be both input
- -- and the target must have a monitor (so the target will be used as a source)
- local function isMonitor(properties)
- return properties["item.node.direction"] == "input" and
- parseBool(properties["item.features.monitor"]) and
- not parseBool(properties["item.features.no-dsp"]) and
- properties["item.factory.name"] == "si-audio-adapter"
- end
-
- if properties["item.node.direction"] == target_properties["item.node.direction"]
- and not isMonitor(target_properties) then
- return false
- end
-
- -- check link group
- local function canLinkGroupCheck (link_group, si_target, hops)
- local target_props = si_target.properties
- local target_link_group = target_props["node.link-group"]
-
- if hops == 8 then
- return false
- end
-
- -- allow linking if target has no link-group property
- if not target_link_group then
- return true
- end
-
- -- do not allow linking if target has the same link-group
- if link_group == target_link_group then
- return false
- end
-
- -- make sure target is not linked with another node with same link group
- -- start by locating other nodes in the target's link-group, in opposite direction
- for n in linkables_om:iterate {
- Constraint { "id", "!", si_target.id, type = "gobject" },
- Constraint { "item.node.direction", "!", target_props["item.node.direction"] },
- Constraint { "node.link-group", "=", target_link_group },
- } do
- -- iterate their peers and return false if one of them cannot link
- for silink in links_om:iterate() do
- local out_id = tonumber(silink.properties["out.item.id"])
- local in_id = tonumber(silink.properties["in.item.id"])
- if out_id == n.id or in_id == n.id then
- local peer_id = (out_id == n.id) and in_id or out_id
- local peer = linkables_om:lookup {
- Constraint { "id", "=", peer_id, type = "gobject" },
- }
- if peer and not canLinkGroupCheck (link_group, peer, hops + 1) then
- return false
- end
- end
- end
- end
- return true
- end
-
- local link_group = properties["node.link-group"]
- if link_group then
- return canLinkGroupCheck (link_group, si_target, 0)
- end
- return true
-end
-
-function getTargetDirection(properties)
- local target_direction = nil
- if properties["item.node.direction"] == "output" or
- (properties["item.node.direction"] == "input" and
- parseBool(properties["stream.capture.sink"])) then
- target_direction = "input"
- else
- target_direction = "output"
- end
- return target_direction
-end
-
-function getDefaultNode(properties, target_direction)
- local target_media_class =
- properties["media.type"] ..
- (target_direction == "input" and "/Sink" or "/Source")
- return default_nodes:call("get-default-node", target_media_class)
-end
-
--- Try to locate a valid target node that was explicitly requsted by the
--- client(node.target) or by the user(target.node)
--- Use the target.node metadata, if config.move is enabled,
--- then use the node.target property that was set on the node
--- `properties` must be the properties dictionary of the session item
--- that is currently being handled
-function findDefinedTarget (properties)
- local metadata = config.move and metadata_om:lookup()
- local target_direction = getTargetDirection(properties)
- local target_key
- local target_value
- local node_defined = false
-
- if properties["target.object"] ~= nil then
- target_value = properties["target.object"]
- target_key = "object.serial"
- node_defined = true
- elseif properties["node.target"] ~= nil then
- target_value = properties["node.target"]
- target_key = "node.id"
- node_defined = true
- end
-
- if metadata then
- local id = metadata:find(properties["node.id"], "target.object")
- if id ~= nil then
- target_value = id
- target_key = "object.serial"
- node_defined = false
- else
- id = metadata:find(properties["node.id"], "target.node")
- if id ~= nil then
- target_value = id
- target_key = "node.id"
- node_defined = false
- end
- end
- end
-
- if target_value == "-1" then
- return nil, false, node_defined
- end
-
- if target_value and tonumber(target_value) then
- local si_target = linkables_om:lookup {
- Constraint { target_key, "=", target_value },
- }
- if si_target and canLink (properties, si_target) then
- return si_target, true, node_defined
- end
- end
-
- if target_value then
- for si_target in linkables_om:iterate() do
- local target_props = si_target.properties
- if (target_props["node.name"] == target_value or
- target_props["object.path"] == target_value) and
- target_props["item.node.direction"] == target_direction and
- canLink (properties, si_target) then
- return si_target, true, node_defined
- end
- end
- end
- return nil, (target_value ~= nil), node_defined
-end
-
-function parseParam(param, id)
- local route = param:parse()
- if route.pod_type == "Object" and route.object_id == id then
- return route.properties
- else
- return nil
- end
-end
-
-function arrayContains(a, value)
- for _, v in ipairs(a) do
- if v == value then
- return true
- end
- end
- return false
-end
-
-
--- Does the target device have any active/available paths/routes to
--- the physical device(spkr/mic/cam)?
-function haveAvailableRoutes (si_props)
- local card_profile_device = si_props["card.profile.device"]
- local device_id = si_props["device.id"]
- local device = device_id and devices_om:lookup {
- Constraint { "bound-id", "=", device_id, type = "gobject"},
- }
-
- if not card_profile_device or not device then
- return true
- end
-
- local found = 0
- local avail = 0
-
- -- First check "SPA_PARAM_Route" if there are any active devices
- -- in an active profile.
- for p in device:iterate_params("Route") do
- local route = parseParam(p, "Route")
- if not route then
- goto skip_route
- end
-
- if (route.device ~= tonumber(card_profile_device)) then
- goto skip_route
- end
-
- if (route.available == "no") then
- return false
- end
-
- do return true end
-
- ::skip_route::
- end
-
- -- Second check "SPA_PARAM_EnumRoute" if there is any route that
- -- is available if not active.
- for p in device:iterate_params("EnumRoute") do
- local route = parseParam(p, "EnumRoute")
- if not route then
- goto skip_enum_route
- end
-
- if not arrayContains(route.devices, tonumber(card_profile_device)) then
- goto skip_enum_route
- end
- found = found + 1;
- if (route.available ~= "no") then
- avail = avail +1
- end
- ::skip_enum_route::
- end
-
- if found == 0 then
- return true
- end
- if avail > 0 then
- return true
- end
-
- return false
-
-end
-
-function findDefaultLinkable (si)
- local si_props = si.properties
- local target_direction = getTargetDirection(si_props)
- local def_node_id = getDefaultNode(si_props, target_direction)
- return linkables_om:lookup {
- Constraint { "node.id", "=", tostring(def_node_id) }
- }
-end
-
-function checkPassthroughCompatibility (si, si_target)
- local si_must_passthrough = parseBool(si.properties["item.node.encoded-only"])
- local si_target_must_passthrough = parseBool(si_target.properties["item.node.encoded-only"])
- local can_passthrough = canPassthrough(si, si_target)
- if (si_must_passthrough or si_target_must_passthrough)
- and not can_passthrough then
- return false, can_passthrough
- end
- return true, can_passthrough
-end
-
-function findBestLinkable (si)
- local si_props = si.properties
- local target_direction = getTargetDirection(si_props)
- local target_picked = nil
- local target_can_passthrough = false
- local target_priority = 0
- local target_plugged = 0
-
- for si_target in linkables_om:iterate {
- Constraint { "item.node.type", "=", "device" },
- Constraint { "item.node.direction", "=", target_direction },
- Constraint { "media.type", "=", si_props["media.type"] },
- } do
- local si_target_props = si_target.properties
- local si_target_node_id = si_target_props["node.id"]
- local priority = tonumber(si_target_props["priority.session"]) or 0
-
- Log.debug(string.format("Looking at: %s (%s)",
- tostring(si_target_props["node.name"]),
- tostring(si_target_node_id)))
-
- if not canLink (si_props, si_target) then
- Log.debug("... cannot link, skip linkable")
- goto skip_linkable
- end
-
- if not haveAvailableRoutes(si_target_props) then
- Log.debug("... does not have routes, skip linkable")
- goto skip_linkable
- end
-
- local passthrough_compatible, can_passthrough =
- checkPassthroughCompatibility (si, si_target)
- if not passthrough_compatible then
- Log.debug("... passthrough is not compatible, skip linkable")
- goto skip_linkable
- end
-
- local plugged = tonumber(si_target_props["item.plugged.usec"]) or 0
-
- Log.debug("... priority:"..tostring(priority)..", plugged:"..tostring(plugged))
-
- -- (target_picked == NULL) --> make sure atleast one target is picked.
- -- (priority > target_priority) --> pick the highest priority linkable(node)
- -- target.
- -- (priority == target_priority and plugged > target_plugged) --> pick the
- -- latest connected/plugged(in time) linkable(node) target.
- if (target_picked == nil or
- priority > target_priority or
- (priority == target_priority and plugged > target_plugged)) then
- Log.debug("... picked")
- target_picked = si_target
- target_can_passthrough = can_passthrough
- target_priority = priority
- target_plugged = plugged
- end
- ::skip_linkable::
- end
-
- if target_picked then
- Log.info(string.format("... best target picked: %s (%s), can_passthrough:%s",
- tostring(target_picked.properties["node.name"]),
- tostring(target_picked.properties["node.id"]),
- tostring(target_can_passthrough)))
- return target_picked, target_can_passthrough
- else
- return nil, nil
- end
-
-end
-
-function findUndefinedTarget (si)
- -- Just find the best linkable if default nodes module is not loaded
- if default_nodes == nil then
- return findBestLinkable (si)
- end
-
- -- Otherwise find the default linkable. If the default linkable is not
- -- compatible, we find the best one instead. We return nil if the default
- -- linkable does not exist.
- local si_target = findDefaultLinkable (si)
- if si_target then
- local passthrough_compatible, can_passthrough =
- checkPassthroughCompatibility (si, si_target)
- if canLink (si.properties, si_target) and passthrough_compatible then
- Log.info(string.format("... default target picked: %s (%s), can_passthrough:%s",
- tostring(si_target.properties["node.name"]),
- tostring(si_target.properties["node.id"]),
- tostring(can_passthrough)))
- return si_target, can_passthrough
- else
- return findBestLinkable (si)
- end
- end
- return nil, nil
-end
-
-function lookupLink (si_id, si_target_id)
- local link = links_om:lookup {
- Constraint { "out.item.id", "=", si_id },
- Constraint { "in.item.id", "=", si_target_id }
- }
- if not link then
- link = links_om:lookup {
- Constraint { "in.item.id", "=", si_id },
- Constraint { "out.item.id", "=", si_target_id }
- }
- end
- return link
-end
-
-function checkLinkable(si, handle_nonstreams)
- -- only handle stream session items
- local si_props = si.properties
- if not si_props or (si_props["item.node.type"] ~= "stream"
- and not handle_nonstreams) then
- return false
- end
-
- -- Determine if we can handle item by this policy
- if endpoints_om:get_n_objects () > 0 and
- si_props["item.factory.name"] == "si-audio-adapter" then
- return false
- end
-
- return true, si_props
-end
-
-si_flags = {}
-
-function checkPending ()
- local pending_linkables = pending_linkables_om:get_n_objects ()
-
- -- We cannot process linkables if some of them are pending activation,
- -- because linkables do not appear in the same order as nodes,
- -- and we cannot resolve target node references until all linkables
- -- have appeared.
-
- if self.pending_error_timer then
- self.pending_error_timer:destroy ()
- self.pending_error_timer = nil
- end
-
- if pending_linkables ~= 0 then
- -- Wait for linkables to get it sync
- Log.debug(string.format("pending %d linkable not ready",
- pending_linkables))
- self.events_skipped = true
-
- -- To make bugs in activation easier to debug, emit an error message
- -- if they occur. policy-node should never be suspended for 20sec.
- self.pending_error_timer = Core.timeout_add(20000, function()
- self.pending_error_timer = nil
- if pending_linkables ~= 0 then
- Log.message(string.format("%d pending linkable(s) not activated in 20sec. "
- .. "This should never happen.", pending_linkables))
- end
- end)
-
- return true
- elseif self.events_skipped then
- Log.debug("pending linkables ready")
- self.events_skipped = false
- scheduleRescan ()
- return true
- end
-
- return false
-end
-
-function checkFollowDefault (si, si_target, has_node_defined_target)
- -- If it got linked to the default target that is defined by node
- -- props but not metadata, start ignoring the node prop from now on.
- -- This is what Pulseaudio does.
- --
- -- Pulseaudio skips here filter streams (i->origin_sink and
- -- o->destination_source set in PA). Pipewire does not have a flag
- -- explicitly for this, but we can use presence of node.link-group.
- if not has_node_defined_target then
- return
- end
-
- local si_props = si.properties
- local target_props = si_target.properties
- local reconnect = not parseBool(si_props["node.dont-reconnect"])
- local is_filter = (si_props["node.link-group"] ~= nil)
-
- if config.follow and default_nodes ~= nil and reconnect and not is_filter then
- local def_id = getDefaultNode(si_props, getTargetDirection(si_props))
-
- if target_props["node.id"] == tostring(def_id) then
- local metadata = metadata_om:lookup()
- -- Set target.node, for backward compatibility
- metadata:set(tonumber(si_props["node.id"]), "target.node", "Spa:Id", "-1")
- Log.info (si, "... set metadata to follow default")
- end
- end
-end
-
-function handleLinkable (si)
- if checkPending () then
- return
- end
-
- local valid, si_props = checkLinkable(si)
- if not valid then
- return
- end
-
- -- check if we need to link this node at all
- local autoconnect = parseBool(si_props["node.autoconnect"])
- if not autoconnect then
- Log.debug (si, tostring(si_props["node.name"]) .. " does not need to be autoconnected")
- return
- end
-
- Log.info (si, string.format("handling item: %s (%s)",
- tostring(si_props["node.name"]), tostring(si_props["node.id"])))
-
- ensureSiFlags(si)
-
- -- get other important node properties
- local reconnect = not parseBool(si_props["node.dont-reconnect"])
- local exclusive = parseBool(si_props["node.exclusive"])
- local si_must_passthrough = parseBool(si_props["item.node.encoded-only"])
-
- -- find defined target
- local si_target, has_defined_target, has_node_defined_target
- = findDefinedTarget(si_props)
- local can_passthrough = si_target and canPassthrough(si, si_target)
-
- if si_target and si_must_passthrough and not can_passthrough then
- si_target = nil
- end
-
- -- if the client has seen a target that we haven't yet prepared, schedule
- -- a rescan one more time and hope for the best
- local si_id = si.id
- if has_defined_target
- and not si_target
- and not si_flags[si_id].was_handled
- and not si_flags[si_id].done_waiting then
- Log.info (si, "... waiting for target")
- si_flags[si_id].done_waiting = true
- scheduleRescan()
- return
- end
-
- -- find fallback target
- if not si_target and (reconnect or not has_defined_target) then
- si_target, can_passthrough = findUndefinedTarget(si)
- end
-
- -- Check if item is linked to proper target, otherwise re-link
- if si_flags[si_id].peer_id then
- if si_target and si_flags[si_id].peer_id == si_target.id then
- Log.debug (si, "... already linked to proper target")
- -- Check this also here, in case in default targets changed
- checkFollowDefault (si, si_target, has_node_defined_target)
- return
- end
- local link = lookupLink (si_id, si_flags[si_id].peer_id)
- if reconnect then
- if link ~= nil then
- -- remove old link
- if ((link:get_active_features() & Feature.SessionItem.ACTIVE) == 0) then
- -- Link not yet activated. We don't want to remove it now, as that
- -- may cause problems. Instead, give up for now. A rescan is scheduled
- -- once the link activates.
- Log.info (link, "Link to be moved was not activated, will wait for it.")
- return
- end
- si_flags[si_id].peer_id = nil
- link:remove ()
- Log.info (si, "... moving to new target")
- end
- else
- if link ~= nil then
- Log.info (si, "... dont-reconnect, not moving")
- return
- end
- end
- end
-
- -- if the stream has dont-reconnect and was already linked before,
- -- don't link it to a new target
- if not reconnect and si_flags[si.id].was_handled then
- si_target = nil
- end
-
- -- check target's availability
- if si_target then
- local target_is_linked, target_is_exclusive = isLinked(si_target)
- if target_is_exclusive then
- Log.info(si, "... target is linked exclusively")
- si_target = nil
- end
-
- if target_is_linked then
- if exclusive or si_must_passthrough then
- Log.info(si, "... target is already linked, cannot link exclusively")
- si_target = nil
- else
- -- disable passthrough, we can live without it
- can_passthrough = false
- end
- end
- end
-
- if not si_target then
- Log.info (si, "... target not found, reconnect:" .. tostring(reconnect))
-
- local node = si:get_associated_proxy ("node")
- if reconnect and si_flags[si.id].was_handled then
- Log.info (si, "... waiting reconnect")
- return
- end
-
- local client_id = node.properties["client.id"]
- if client_id then
- local client = clients_om:lookup {
- Constraint { "bound-id", "=", client_id, type = "gobject" }
- }
- local message
- if reconnect then
- message = "no target node available"
- else
- message = "target not found"
- end
- if client then
- client:send_error(node["bound-id"], -2, message)
- end
- end
-
- if not reconnect then
- Log.info (si, "... destroy node")
- node:request_destroy()
- end
- else
- createLink (si, si_target, can_passthrough, exclusive)
- si_flags[si.id].was_handled = true
-
- checkFollowDefault (si, si_target, has_node_defined_target)
- end
-end
-
-function unhandleLinkable (si)
- local valid, si_props = checkLinkable(si, true)
- if not valid then
- return
- end
-
- Log.info (si, string.format("unhandling item: %s (%s)",
- tostring(si_props["node.name"]), tostring(si_props["node.id"])))
-
- -- remove any links associated with this item
- for silink in links_om:iterate() do
- local out_id = tonumber (silink.properties["out.item.id"])
- local in_id = tonumber (silink.properties["in.item.id"])
- if out_id == si.id or in_id == si.id then
- if out_id == si.id and
- si_flags[in_id] and si_flags[in_id].peer_id == out_id then
- si_flags[in_id].peer_id = nil
- elseif in_id == si.id and
- si_flags[out_id] and si_flags[out_id].peer_id == in_id then
- si_flags[out_id].peer_id = nil
- end
- silink:remove ()
- Log.info (silink, "... link removed")
- end
- end
-
- si_flags[si.id] = nil
-end
-
-default_nodes = Plugin.find("default-nodes-api")
-
-metadata_om = ObjectManager {
- Interest {
- type = "metadata",
- Constraint { "metadata.name", "=", "default" },
- }
-}
-
-endpoints_om = ObjectManager { Interest { type = "SiEndpoint" } }
-
-clients_om = ObjectManager { Interest { type = "client" } }
-
-devices_om = ObjectManager { Interest { type = "device" } }
-
-linkables_om = ObjectManager {
- Interest {
- type = "SiLinkable",
- -- only handle si-audio-adapter and si-node
- Constraint { "item.factory.name", "c", "si-audio-adapter", "si-node" },
- Constraint { "active-features", "!", 0, type = "gobject" },
- }
-}
-
-pending_linkables_om = ObjectManager {
- Interest {
- type = "SiLinkable",
- -- only handle si-audio-adapter and si-node
- Constraint { "item.factory.name", "c", "si-audio-adapter", "si-node" },
- Constraint { "active-features", "=", 0, type = "gobject" },
- }
-}
-
-links_om = ObjectManager {
- Interest {
- type = "SiLink",
- -- only handle links created by this policy
- Constraint { "is.policy.item.link", "=", true },
- }
-}
-
--- listen for default node changes if config.follow is enabled
-if config.follow and default_nodes ~= nil then
- default_nodes:connect("changed", function ()
- scheduleRescan ()
- end)
-end
-
--- listen for target.node metadata changes if config.move is enabled
-if config.move then
- metadata_om:connect("object-added", function (om, metadata)
- metadata:connect("changed", function (m, subject, key, t, value)
- if key == "target.node" or key == "target.object" then
- scheduleRescan ()
- end
- end)
- end)
-end
-
-function findAssociatedLinkGroupNode (si)
- local si_props = si.properties
- local node = si:get_associated_proxy ("node")
- local link_group = node.properties["node.link-group"]
- if link_group == nil then
- return nil
- end
-
- -- get the associated media class
- local assoc_direction = getTargetDirection(si_props)
- local assoc_media_class =
- si_props["media.type"] ..
- (assoc_direction == "input" and "/Sink" or "/Source")
-
- -- find the linkable with same link group and matching assoc media class
- for assoc_si in linkables_om:iterate() do
- local assoc_node = assoc_si:get_associated_proxy ("node")
- local assoc_link_group = assoc_node.properties["node.link-group"]
- if assoc_link_group == link_group and
- assoc_media_class == assoc_node.properties["media.class"] then
- return assoc_si
- end
- end
-
- return nil
-end
-
-function onLinkGroupPortsStateChanged (si, old_state, new_state)
- local new_str = tostring(new_state)
- local si_props = si.properties
-
- -- only handle items with configured ports state
- if new_str ~= "configured" then
- return
- end
-
- Log.info (si, "ports format changed on " .. si_props["node.name"])
-
- -- find associated device
- local si_device = findAssociatedLinkGroupNode (si)
- if si_device ~= nil then
- local device_node_name = si_device.properties["node.name"]
-
- -- get the stream format
- local f, m = si:get_ports_format()
-
- -- unregister the device
- Log.info (si_device, "unregistering " .. device_node_name)
- si_device:remove()
-
- -- set new format in the device
- Log.info (si_device, "setting new format in " .. device_node_name)
- si_device:set_ports_format(f, m, function (item, e)
- if e ~= nil then
- Log.warning (item, "failed to configure ports in " ..
- device_node_name .. ": " .. e)
- end
-
- -- register back the device
- Log.info (item, "registering " .. device_node_name)
- item:register()
- end)
- end
-end
-
-function ensureSiFlags (si)
- -- prepare flags table
- if not si_flags[si.id] then
- si_flags[si.id] = {}
- end
-end
-
-function checkFiltersPortsState (si)
- local si_props = si.properties
- local node = si:get_associated_proxy ("node")
- local link_group = node.properties["node.link-group"]
-
- ensureSiFlags(si)
-
- -- only listen for ports state changed on audio filter streams
- if si_flags[si.id].ports_state_signal ~= true and
- si_props["item.factory.name"] == "si-audio-adapter" and
- si_props["item.node.type"] == "stream" and
- link_group ~= nil then
- si:connect("adapter-ports-state-changed", onLinkGroupPortsStateChanged)
- si_flags[si.id].ports_state_signal = true
- Log.info (si, "listening ports state changed on " .. si_props["node.name"])
- end
-end
-
-linkables_om:connect("object-added", function (om, si)
- local si_props = si.properties
-
- -- Forward filters ports format to associated virtual devices if enabled
- if config.filter_forward_format then
- checkFiltersPortsState (si)
- end
-
- if si_props["item.node.type"] ~= "stream" then
- scheduleRescan ()
- else
- handleLinkable (si)
- end
-end)
-
-linkables_om:connect("object-removed", function (om, si)
- unhandleLinkable (si)
- scheduleRescan ()
-end)
-
-devices_om:connect("object-added", function (om, device)
- device:connect("params-changed", function (d, param_name)
- scheduleRescan ()
- end)
-end)
-
-metadata_om:activate()
-endpoints_om:activate()
-clients_om:activate()
-linkables_om:activate()
-pending_linkables_om:activate()
-links_om:activate()
-devices_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/restore-stream.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/restore-stream.lua
deleted file mode 100644
index 06867d42..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/restore-stream.lua
+++ /dev/null
@@ -1,499 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author George Kiagiadakis
---
--- Based on restore-stream.c from pipewire-media-session
--- Copyright © 2020 Wim Taymans
---
--- SPDX-License-Identifier: MIT
-
--- Receive script arguments from config.lua
-local config = ... or {}
-config.properties = config.properties or {}
-config_restore_props = config.properties["restore-props"] or false
-config_restore_target = config.properties["restore-target"] or false
-config_default_channel_volume = config.properties["default-channel-volume"] or 1.0
-
--- preprocess rules and create Interest objects
-for _, r in ipairs(config.rules or {}) do
- r.interests = {}
- for _, i in ipairs(r.matches) do
- local interest_desc = { type = "properties" }
- 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
- r.matches = nil
-end
-
--- applies properties from config.rules when asked to
-function rulesApplyProperties(properties)
- for _, r in ipairs(config.rules or {}) do
- if r.apply_properties then
- for _, interest in ipairs(r.interests) do
- if interest:matches(properties) then
- for k, v in pairs(r.apply_properties) do
- properties[k] = v
- end
- end
- end
- end
- end
-end
-
--- the state storage
-state = State("restore-stream")
-state_table = state:load()
-
--- simple serializer {"foo", "bar"} -> "foo;bar;"
-function serializeArray(a)
- local str = ""
- for _, v in ipairs(a) do
- str = str .. tostring(v):gsub(";", "\\;") .. ";"
- end
- return str
-end
-
--- simple deserializer "foo;bar;" -> {"foo", "bar"}
-function parseArray(str, convert_value, with_type)
- local array = {}
- local val = ""
- local escaped = false
- for i = 1, #str do
- local c = str:sub(i,i)
- if c == '\\' then
- escaped = true
- elseif c == ';' and not escaped then
- val = convert_value and convert_value(val) or val
- table.insert(array, val)
- val = ""
- else
- val = val .. tostring(c)
- escaped = false
- end
- end
- if with_type then
- array["pod_type"] = "Array"
- end
- return array
-end
-
-function parseParam(param, id)
- local route = param:parse()
- if route.pod_type == "Object" and route.object_id == id then
- return route.properties
- else
- return nil
- end
-end
-
-function storeAfterTimeout()
- if timeout_source then
- timeout_source:destroy()
- end
- timeout_source = Core.timeout_add(1000, function ()
- local saved, err = state:save(state_table)
- if not saved then
- Log.warning(err)
- end
- timeout_source = nil
- end)
-end
-
-function findSuitableKey(properties)
- local keys = {
- "media.role",
- "application.id",
- "application.name",
- "media.name",
- "node.name",
- }
- local key = nil
-
- for _, k in ipairs(keys) do
- local p = properties[k]
- if p then
- key = string.format("%s:%s:%s",
- properties["media.class"]:gsub("^Stream/", ""), k, p)
- break
- end
- end
- return key
-end
-
-function saveTarget(subject, target_key, type, value)
- if target_key ~= "target.node" and target_key ~= "target.object" then
- return
- end
-
- local node = streams_om:lookup {
- Constraint { "bound-id", "=", subject, type = "gobject" }
- }
- if not node then
- return
- end
-
- local stream_props = node.properties
- rulesApplyProperties(stream_props)
-
- if stream_props["state.restore-target"] == false then
- return
- end
-
- local key_base = findSuitableKey(stream_props)
- if not key_base then
- return
- end
-
- local target_value = value
- local target_name = nil
-
- if not target_value then
- local metadata = metadata_om:lookup()
- if metadata then
- target_value = metadata:find(node["bound-id"], target_key)
- end
- end
- if target_value and target_value ~= "-1" then
- local target_node
- if target_key == "target.object" then
- target_node = allnodes_om:lookup {
- Constraint { "object.serial", "=", target_value, type = "pw-global" }
- }
- else
- target_node = allnodes_om:lookup {
- Constraint { "bound-id", "=", target_value, type = "gobject" }
- }
- end
- if target_node then
- target_name = target_node.properties["node.name"]
- end
- end
- state_table[key_base .. ":target"] = target_name
-
- Log.info(node, "saving stream target for " ..
- tostring(stream_props["node.name"]) ..
- " -> " .. tostring(target_name))
-
- storeAfterTimeout()
-end
-
-function restoreTarget(node, target_name)
-
- local stream_props = node.properties
- local target_in_props = nil
-
- if stream_props ["target.object"] ~= nil or
- stream_props ["node.target"] ~= nil then
- target_in_props = stream_props ["target.object"] or
- stream_props ["node.target"]
-
- Log.debug (string.format ("%s%s%s%s",
- "Not restoring the target for ",
- stream_props ["node.name"],
- " because it is already set to ",
- target_in_props))
-
- return
- end
-
- local target_node = allnodes_om:lookup {
- Constraint { "node.name", "=", target_name, type = "pw" }
- }
-
- if target_node then
- local metadata = metadata_om:lookup()
- if metadata then
- metadata:set(node["bound-id"], "target.node", "Spa:Id",
- target_node["bound-id"])
- end
- end
-end
-
-function jsonTable(val, name)
- local tmp = ""
- local count = 0
-
- if name then tmp = tmp .. string.format("%q", name) .. ": " end
-
- if type(val) == "table" then
- if val["pod_type"] == "Array" then
- tmp = tmp .. "["
- for _, v in ipairs(val) do
- if count > 0 then tmp = tmp .. "," end
- tmp = tmp .. jsonTable(v)
- count = count + 1
- end
- tmp = tmp .. "]"
- else
- tmp = tmp .. "{"
- for k, v in pairs(val) do
- if count > 0 then tmp = tmp .. "," end
- tmp = tmp .. jsonTable(v, k)
- count = count + 1
- end
- tmp = tmp .. "}"
- end
- elseif type(val) == "number" then
- tmp = tmp .. tostring(val)
- elseif type(val) == "string" then
- tmp = tmp .. string.format("%q", val)
- elseif type(val) == "boolean" then
- tmp = tmp .. (val and "true" or "false")
- else
- tmp = tmp .. "\"[type:" .. type(val) .. "]\""
- end
- return tmp
-end
-
-function moveToMetadata(key_base, metadata)
- local route_table = { }
- local count = 0
-
- key = "restore.stream." .. key_base
- key = string.gsub(key, ":", ".", 1);
-
- local str = state_table[key_base .. ":volume"]
- if str then
- route_table["volume"] = tonumber(str)
- count = count + 1;
- end
- local str = state_table[key_base .. ":mute"]
- if str then
- route_table["mute"] = str == "true"
- count = count + 1;
- end
- local str = state_table[key_base .. ":channelVolumes"]
- if str then
- route_table["volumes"] = parseArray(str, tonumber, true)
- count = count + 1;
- end
- local str = state_table[key_base .. ":channelMap"]
- if str then
- route_table["channels"] = parseArray(str, nil, true)
- count = count + 1;
- end
-
- if count > 0 then
- metadata:set(0, key, "Spa:String:JSON", jsonTable(route_table));
- end
-end
-
-
-function saveStream(node)
- local stream_props = node.properties
- rulesApplyProperties(stream_props)
-
- if config_restore_props and stream_props["state.restore-props"] ~= false then
- local key_base = findSuitableKey(stream_props)
- if not key_base then
- return
- end
-
- Log.info(node, "saving stream props for " ..
- tostring(stream_props["node.name"]))
-
- for p in node:iterate_params("Props") do
- local props = parseParam(p, "Props")
- if not props then
- goto skip_prop
- end
-
- if props.volume then
- state_table[key_base .. ":volume"] = tostring(props.volume)
- end
- if props.mute ~= nil then
- state_table[key_base .. ":mute"] = tostring(props.mute)
- end
- if props.channelVolumes then
- state_table[key_base .. ":channelVolumes"] = serializeArray(props.channelVolumes)
- end
- if props.channelMap then
- state_table[key_base .. ":channelMap"] = serializeArray(props.channelMap)
- end
-
- ::skip_prop::
- end
-
- storeAfterTimeout()
- end
-end
-
-function build_default_channel_volumes (node)
- local def_vol = config_default_channel_volume
- local channels = 2
- local res = {}
-
- local str = node.properties["state.default-channel-volume"]
- if str ~= nil then
- def_vol = tonumber (str)
- end
-
- for pod in node:iterate_params("Format") do
- local pod_parsed = pod:parse()
- if pod_parsed ~= nil then
- channels = pod_parsed.properties.channels
- break
- end
- end
-
- while (#res < channels) do
- table.insert(res, def_vol)
- end
-
- return res;
-end
-
-function restoreStream(node)
- local stream_props = node.properties
- rulesApplyProperties(stream_props)
-
- local key_base = findSuitableKey(stream_props)
- if not key_base then
- return
- end
-
- if config_restore_props and stream_props["state.restore-props"] ~= false then
- local props = { "Spa:Pod:Object:Param:Props", "Props" }
-
- local str = state_table[key_base .. ":volume"]
- props.volume = str and tonumber(str) or nil
-
- local str = state_table[key_base .. ":mute"]
- props.mute = str and (str == "true") or nil
-
- local str = state_table[key_base .. ":channelVolumes"]
- props.channelVolumes = str and parseArray(str, tonumber) or
- build_default_channel_volumes (node)
-
- local str = state_table[key_base .. ":channelMap"]
- props.channelMap = str and parseArray(str) or nil
-
- -- convert arrays to Spa Pod
- if props.channelVolumes then
- table.insert(props.channelVolumes, 1, "Spa:Float")
- props.channelVolumes = Pod.Array(props.channelVolumes)
- end
- if props.channelMap then
- table.insert(props.channelMap, 1, "Spa:Enum:AudioChannel")
- props.channelMap = Pod.Array(props.channelMap)
- end
-
- Log.info(node, "restore values from " .. key_base)
- local param = Pod.Object(props)
- Log.debug(param, "setting props on " .. tostring(node))
- node:set_param("Props", param)
- end
-
- if config_restore_target and stream_props["state.restore-target"] ~= false then
- local str = state_table[key_base .. ":target"]
- if str then
- restoreTarget(node, str)
- end
- end
-end
-
-if config_restore_target then
- metadata_om = ObjectManager {
- Interest {
- type = "metadata",
- Constraint { "metadata.name", "=", "default" },
- }
- }
-
- metadata_om:connect("object-added", function (om, metadata)
- -- process existing metadata
- for s, k, t, v in metadata:iterate(Id.ANY) do
- saveTarget(s, k, t, v)
- end
- -- and watch for changes
- metadata:connect("changed", function (m, subject, key, type, value)
- saveTarget(subject, key, type, value)
- end)
- end)
- metadata_om:activate()
-end
-
-function handleRouteSettings(subject, key, type, value)
- if type ~= "Spa:String:JSON" then
- return
- end
- if string.find(key, "^restore.stream.") == nil then
- return
- end
- if value == nil then
- return
- end
- local json = Json.Raw (value);
- if json == nil or not json:is_object () then
- return
- end
-
- local vparsed = json:parse()
- local key_base = string.sub(key, string.len("restore.stream.") + 1)
- local str;
-
- key_base = string.gsub(key_base, "%.", ":", 1);
-
- if vparsed.volume ~= nil then
- state_table[key_base .. ":volume"] = tostring (vparsed.volume)
- end
- if vparsed.mute ~= nil then
- state_table[key_base .. ":mute"] = tostring (vparsed.mute)
- end
- if vparsed.channels ~= nil then
- state_table[key_base .. ":channelMap"] = serializeArray (vparsed.channels)
- end
- if vparsed.volumes ~= nil then
- state_table[key_base .. ":channelVolumes"] = serializeArray (vparsed.volumes)
- end
-
- storeAfterTimeout()
-end
-
-
-rs_metadata = ImplMetadata("route-settings")
-rs_metadata:activate(Features.ALL, function (m, e)
- if e then
- Log.warning("failed to activate route-settings metadata: " .. tostring(e))
- return
- end
-
- -- copy state into the metadata
- moveToMetadata("Output/Audio:media.role:Notification", m)
- -- watch for changes
- m:connect("changed", function (m, subject, key, type, value)
- handleRouteSettings(subject, key, type, value)
- end)
-end)
-
-allnodes_om = ObjectManager { Interest { type = "node" } }
-allnodes_om:activate()
-
-streams_om = ObjectManager {
- -- match stream nodes
- Interest {
- type = "node",
- Constraint { "media.class", "matches", "Stream/*", type = "pw-global" },
- },
- -- and device nodes that are not associated with any routes
- Interest {
- type = "node",
- Constraint { "media.class", "matches", "Audio/*", type = "pw-global" },
- Constraint { "device.routes", "is-absent", type = "pw" },
- },
- Interest {
- type = "node",
- Constraint { "media.class", "matches", "Audio/*", type = "pw-global" },
- Constraint { "device.routes", "equals", "0", type = "pw" },
- },
-}
-streams_om:connect("object-added", function (streams_om, node)
- node:connect("params-changed", saveStream)
- restoreStream(node)
-end)
-streams_om:activate()
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/sm-objects.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/sm-objects.lua
deleted file mode 100644
index c22b29d7..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/sm-objects.lua
+++ /dev/null
@@ -1,103 +0,0 @@
--- WirePlumber
---
--- Copyright © 2023 Collabora Ltd.
--- @author George Kiagiadakis
---
--- SPDX-License-Identifier: MIT
---
--- The script exposes a metadata object named "sm-objects" that clients can
--- use to load objects into the WirePlumber daemon process. The objects are
--- loaded as soon as the metadata is set and are destroyed when the metadata
--- is cleared.
---
--- To load an object, a client needs to set a metadata entry with:
---
--- * subject:
--- The ID of the owner of the object; you can use 0 here, but the
--- idea is to be able to restrict which clients can change and/or
--- delete these objects by using IDs of other objects appropriately
---
--- * key: ""
--- This is the name that will be used to identify the object.
--- If an object with the same name already exists, it will be destroyed.
--- Note that the keys are unique per subject, so you can have multiple
--- objects with the same name as long as they are owned by different subjects.
---
--- * type: "Spa:String:JSON"
---
--- * value: "{ type = ,
--- name = ,
--- args = { ...object arguments... } }"
--- The object type can be one of the following:
--- - "pw-module": loads a pipewire module: `name` and `args` are interpreted
--- just like a module entry in pipewire.conf
--- - "metadata": loads a metadata object with `metadata.name` = `name`
--- and any additional properties provided in `args`
---
-
-on_demand_objects = {}
-
-object_constructors = {
- ["pw-module"] = LocalModule,
- ["metadata"] = function (name, args)
- local m = ImplMetadata (name, args)
- m:activate (Features.ALL, function (m, e)
- if e then
- Log.warning ("failed to activate on-demand metadata `" .. name .. "`: " .. tostring (e))
- end
- end)
- return m
- end
-}
-
-function handle_metadata_changed (m, subject, key, type, value)
- -- destroy all objects when metadata is cleared
- if not key then
- on_demand_objects = {}
- return
- end
-
- local object_id = key .. "@" .. tostring(subject)
-
- -- destroy existing object instance, if needed
- if on_demand_objects[object_id] then
- Log.debug("destroy on-demand object: " .. object_id)
- on_demand_objects[object_id] = nil
- end
-
- if value then
- local json = Json.Raw(value)
- if not json:is_object() then
- Log.warning("loading '".. object_id .. "' failed: expected JSON object, got: '" .. value .. "'")
- return
- end
-
- local obj = json:parse(1)
- if not obj.type then
- Log.warning("loading '".. object_id .. "' failed: no object type specified")
- return
- end
- if not obj.name then
- Log.warning("loading '".. object_id .. "' failed: no object name specified")
- return
- end
-
- local constructor = object_constructors[obj.type]
- if not constructor then
- Log.warning("loading '".. object_id .. "' failed: unknown object type: " .. obj.type)
- return
- end
-
- Log.info("load on-demand object: " .. object_id .. " -> " .. obj.name)
- on_demand_objects[object_id] = constructor(obj.name, obj.args)
- end
-end
-
-objects_metadata = ImplMetadata ("sm-objects")
-objects_metadata:activate (Features.ALL, function (m, e)
- if e then
- Log.warning ("failed to activate the sm-objects metadata: " .. tostring (e))
- else
- m:connect("changed", handle_metadata_changed)
- end
-end)
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/static-endpoints.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/static-endpoints.lua
deleted file mode 100644
index 5f9a9757..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/static-endpoints.lua
+++ /dev/null
@@ -1,36 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author Julian Bouzas
---
--- SPDX-License-Identifier: MIT
-
--- Receive script arguments from config.lua
-local endpoints_config = ...
-
-function createEndpoint (factory_name, properties)
- -- create endpoint
- local ep = SessionItem ( factory_name )
- if not ep then
- Log.warning (ep, "could not create endpoint of type " .. factory_name)
- return
- end
-
- -- configure endpoint
- if not ep:configure(properties) then
- Log.warning(ep, "failed to configure endpoint " .. properties.name)
- return
- end
-
- -- activate and register endpoint
- ep:activate (Features.ALL, function (item)
- item:register ()
- Log.info(item, "registered endpoint " .. properties.name)
- end)
-end
-
-
-for name, properties in pairs(endpoints_config) do
- properties["name"] = name
- createEndpoint ("si-audio-endpoint", properties)
-end
diff --git a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/suspend-node.lua b/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/suspend-node.lua
deleted file mode 100644
index 8b5783b3..00000000
--- a/buildroot-external/rootfs-overlay/etc/wireplumber/scripts/suspend-node.lua
+++ /dev/null
@@ -1,59 +0,0 @@
--- WirePlumber
---
--- Copyright © 2021 Collabora Ltd.
--- @author George Kiagiadakis
---
--- SPDX-License-Identifier: MIT
-
-om = ObjectManager {
- Interest { type = "node",
- Constraint { "media.class", "matches", "Audio/*" }
- },
- Interest { type = "node",
- Constraint { "media.class", "matches", "Video/*" }
- },
-}
-
-sources = {}
-
-om:connect("object-added", function (om, node)
- node:connect("state-changed", function (node, old_state, cur_state)
- -- Always clear the current source if any
- local id = node["bound-id"]
- if sources[id] then
- sources[id]:destroy()
- sources[id] = nil
- end
-
- -- Add a timeout source if idle for at least 5 seconds
- if cur_state == "idle" or cur_state == "error" then
- -- honor "session.suspend-timeout-seconds" if specified
- local timeout =
- tonumber(node.properties["session.suspend-timeout-seconds"]) or 5
-
- if timeout == 0 then
- return
- end
-
- -- add idle timeout; multiply by 1000, timeout_add() expects ms
- sources[id] = Core.timeout_add(timeout * 1000, function()
- -- Suspend the node
- -- but check first if the node still exists
- if (node:get_active_features() & Feature.Proxy.BOUND) ~= 0 then
- Log.info(node, "was idle for a while; suspending ...")
- node:send_command("Suspend")
- end
-
- -- Unref the source
- sources[id] = nil
-
- -- false (== G_SOURCE_REMOVE) destroys the source so that this
- -- function does not get fired again after 5 seconds
- return false
- end)
- end
-
- end)
-end)
-
-om:activate()