summary refs log tree commit diff
path: root/bin/audm
diff options
context:
space:
mode:
Diffstat (limited to 'bin/audm')
-rwxr-xr-xbin/audm84
1 files changed, 84 insertions, 0 deletions
diff --git a/bin/audm b/bin/audm
new file mode 100755
index 0000000..58a5a91
--- /dev/null
+++ b/bin/audm
@@ -0,0 +1,84 @@
+#!/bin/bash
+set -eu
+
+# shellcheck disable=2034
+description="audio/sound manager"
+
+export FUZL_PROMPT=audm
+export FUZL_ICON=󰟥
+. libfuzl.sh
+
+main() {
+	local sink source
+
+	sink=$(inspect_node '@DEFAULT_SINK@' | awk -F\\t '{print $2}')
+	fuzl_action_add 'change_sink' "󰓃" "$sink"
+
+	source=$(inspect_node '@DEFAULT_SOURCE@' | awk -F\\t '{print $2}')
+	fuzl_action_add 'change_source' "󰍰" "$source"
+
+	fuzl_action_add 'change_profile' "󰔡" "Change profile"
+
+	fuzl_action_menu || exit 1
+}
+
+#
+# helpers
+#
+
+inspect_node() {
+	local nid
+	nid=$(wpctl inspect "${1:?}" | awk '/^id/{match($0,/[0-9]+,/); print substr($0,RSTART,RLENGTH-1);}')
+
+	test -n "$nid" || exit 1 # TODO handle error
+	pw-dump | jq -r --argjson nid "$nid" \
+		'.[]|select(.id==$nid)|.info.props|[.["object.id"],.["node.description"],.["node.name"]]|join("\t")'
+}
+
+list_nodes() {
+	pw-dump | jq -rc --arg class "${1:?}" \
+		'.[]|select((.info.props["media.class"]//"")|test($class))|.info.props|[.["object.id"],.["node.description"],.["node.name"]]|join("\t")'
+}
+
+#
+# actions
+#
+
+audm_change_sink() {
+	local id
+	id=$(list_nodes 'Audio/Sink' |
+		FUZL_PROMPT='sink' fuzl_menu $FUZL_MENU_FILTER --with-nth='{2}   [{3}]' --accept-nth=1)
+
+	test -n "$id" || main
+	fuzl_try -- wpctl set-default "$id"
+}
+
+audm_change_source() {
+	local id
+	id=$(list_nodes 'Audio/Source' |
+		FUZL_PROMPT='source' fuzl_menu $FUZL_MENU_FILTER --with-nth='{2}   [{3}]' --accept-nth=1)
+
+	test -n "$id" || main
+	fuzl_try -- wpctl set-default "$id"
+}
+
+audm_change_profile() {
+	local device did dname profile
+
+	device=$(pw-dump | jq -rc --arg class "Audio/Device" \
+		'.[]|select((.info.props["media.class"]//"")|test($class))|.info.props|[.["object.id"],.["device.description"],.["device.nick"]]|join("\t")' |
+		FUZL_PROMPT='device' fuzl_menu $FUZL_MENU_FILTER --with-nth='{2}  {3}' --accept-nth='{1}\t{2}')
+	test -n "$device" || main
+
+	did=$(printf %s "$device" | awk -F\\t '{print $1}')
+	dname=$(printf %s "$device" | awk -F\\t '{print $2}')
+
+	profile=$(pw-dump | jq -r --argjson did "$did" \
+		'.[]|select(.id==$did)|.info.params.EnumProfile[]|[.index,.description]|join("\t")' |
+		FUZL_PROMPT="profile ($dname)" fuzl_menu $FUZL_MENU_FILTER --with-nth=2 --accept-nth=1)
+	test -n "$profile" || audm_change_profile
+
+	fuzl_try -- wpctl set-profile "$did" "$profile"
+}
+
+main