Files
bananarchy/overlay/rootfs/usr/bin/sxmo_audio.sh
T

320 lines
8.8 KiB
Bash
Executable File

#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
export PATH="${XDG_CONFIG_HOME:-$HOME/.config}/sxmo/hooks:/usr/share/sxmo/default_hooks:$PATH"
# shellcheck source=configs/default_hooks/sxmo_hook_icons.sh
. sxmo_hook_icons.sh
. sxmo_common.sh
set -e
notifyvol() {
vol="$1"
if [ "-" = "$vol" ]; then
vol="$(cat)"
fi
if [ "muted" = "$vol" ]; then
vol=0
fi
if [ -z "$SXMO_WOB_DISABLE" ]; then
printf "%s\n" "$vol" > "$XDG_RUNTIME_DIR"/sxmo.obsock
else
notify-send -r 999 "$icon_audio Volume $vol"
fi
}
# adjust *output* vol/mute
volup() {
pactl set-sink-volume @DEFAULT_SINK@ +"${1:-5}%"
}
voldown() {
pactl set-sink-volume @DEFAULT_SINK@ -"${1:-5}%"
}
voltogglemute() {
pactl set-sink-mute @DEFAULT_SINK@ toggle
}
volismuted() {
pactl get-sink-mute @DEFAULT_SINK@ | grep -q "Mute: yes"
}
volget() {
if volismuted; then
printf "muted"
else
pactl get-sink-volume @DEFAULT_SINK@ | head -n1 | cut -d'/' -f2 | sed 's/ //g' | sed 's/\%//'
fi
}
volset() {
pactl set-sink-volume @DEFAULT_SINK@ "$1"%
}
# adjust *input* vol/mute
micvolup() {
pactl set-source-volume @DEFAULT_SOURCE@ +"${1:-5}%"
}
micvoldown() {
pactl set-source-volume @DEFAULT_SOURCE@ -"${1:-5}%"
}
mictogglemute() {
pactl set-source-mute @DEFAULT_SOURCE@ toggle
}
micismuted() {
pactl get-source-mute @DEFAULT_SOURCE@ | grep -q "Mute: yes"
}
micvolget() {
if micismuted; then
printf "muted"
else
pactl get-source-volume @DEFAULT_SOURCE@ | head -n1 | cut -d'/' -f2 | sed 's/ //g' | sed 's/\%//'
fi
}
micvolset() {
pactl set-source-volume @DEFAULT_SOURCE@ "$1"%
}
# set the *active port* for output
deviceset() {
if pactl --format=json list sinks | jq -e ".[] | select(.name == \"$(pactl get-default-sink)\") | .ports[] | select(.name == \"[Out] $1\")" >/dev/null 2>&1; then
pactl set-sink-port @DEFAULT_SINK@ "[Out] $1"
else
prof="$(pactl --format=json list cards | jq -r ".[] | . as \$c | .ports[\"[Out] $1\"]? | select(. != null and .availability != \"not available\") | .profiles[] | select(\$c.profiles[.].available == true) | \"\(\$c.name) \(.)\"" | head -n1)"
if [ -n "$prof" ]; then
card="$(printf "%s" "$prof" | cut -f1)"
profile="$(printf "%s" "$prof" | cut -f2)"
pactl set-card-profile "$card" "$profile"
fi
fi
}
# set the *active port* for input
devicesetinput() {
pactl set-source-port @DEFAULT_SOURCE@ "[In] $1"
}
# get the *active port* for input
devicegetinput() {
[ -z "$1" ] && default_source="$(pactl get-default-source)" || default_source="$1"
pactl --format=json list sources | jq -r ".[] | select(.name == \"$default_source\") | .active_port" | sed 's/\[In] //'
}
# get the *active port* for output
deviceget() {
[ -z "$1" ] && default_sink="$(pactl get-default-sink)" || default_sink="$1"
pactl --format=json list sinks | jq -r ".[] | select(.name == \"$default_sink\") | .active_port" | sed 's/\[Out] //'
}
# get the default sink
devicegetdefaultsink() {
pactl get-default-sink
}
# get the default source
devicegetdefaultsource() {
pactl get-default-source
}
sourceset() {
pactl set-default-source "$1"
}
sinkset() {
pactl set-default-sink "$1"
}
profileset() {
pactl set-card-profile "$1" "$2"
}
# get a list of sinks
_sinkssubmenu() {
[ -z "$1" ] && default_sink="$(pactl get-default-sink)" || default_sink="$1"
pactl --format=json list sinks | jq -r '.[] | .name, .description' | while read -r line; do
name="$line"
read -r description
if [ "$default_sink" = "$name" ]; then
printf "%s %s %s ^ sinkset %s\n" "$icon_chk" "$icon_spk" "$description" "$name"
else
printf " %s %s ^ sinkset %s\n" "$icon_spk" "$description" "$name"
fi
done
}
# get a list of output ports
_outportssubmenu() {
[ -z "$1" ] && default_sink="$(pactl get-default-sink)" || default_sink="$1"
active_out_port="$(deviceget "$default_sink")"
pactl --format=json list cards | jq -r ".[] | .ports | to_entries[] | select((.key | startswith(\"[Out] \")) and .value.availability != \"not available\") | .key" | sed 's/\[Out] //' | while read -r line; do
[ "$active_out_port" = "$line" ] && icon="$icon_ton" || icon="$icon_tof"
printf " %s %s ^ deviceset %s
" "$icon" "$line" "$line"
done
}
# get a list of input sources
_sourcessubmenu() {
[ -z "$1" ] && default_source="$(pactl get-default-source)" || default_source="$1"
pactl --format=json list sources | jq -r '.[] | select (.monitor_source == "") | .name, .description' | while read -r line; do
name="$line"
read -r description
if [ "$default_source" = "$name" ]; then
printf "%s %s %s ^ sourceset %s\n" "$icon_chk" "$icon_mic" "$description" "$name"
else
printf " %s %s ^ sourceset %s\n" "$icon_mic" "$description" "$name"
fi
done
}
_cardssubmenu() {
cards="$(pactl -f json list cards)"
printf "%s\n" "$cards" | jq -r '.[] | [.name, .active_profile] | @tsv' | \
while IFS=" " read -r card active_profile; do
printf "%s %s\n" "$icon_nte" "$card"
printf "%s\n" "$cards" | jq -r ".[] | select(.name == \"$card\") | .profiles | to_entries[] | select(.value.available) | [.key, .value.description] | @tsv" | \
while IFS=" " read -r profile desc; do
if [ "$profile" = "$active_profile" ]; then
printf "%s %s ^ true\n" "$icon_chk" "$desc"
else
printf " %s ^ profileset %s \"%s\"\n" "$desc" "$card" "$profile"
fi
done
done
}
# get a list of input ports
_inportssubmenu() {
# if the Headset is NOT plugged in, then do not display Headset
# as a option, as clicking on it causes pulse to unset the source!!
[ -z "$1" ] && default_source="$(pactl get-default-source)" || default_source="$1"
active_in_port="$(devicegetinput "$default_source")"
pactl --format=json list sources | jq -r ".[] | select(.name == \"$default_source\" ) | .ports[] | select(.availability != \"not available\" ) | .name" | sed 's/\[In] //' | while read -r line; do
[ "$active_in_port" = "$line" ] && icon="$icon_ton" || icon="$icon_tof"
printf " %s %s ^ devicesetinput %s\n" "$icon" "$line" "$line"
done
}
_ringmodesubmenu() {
if [ -f "$XDG_CONFIG_HOME"/sxmo/.noring ]; then
printf " %s Ring ^ rm -f \"$XDG_CONFIG_HOME\"/sxmo/.noring\n" "$icon_tof"
else
printf " %s Ring ^ touch \"$XDG_CONFIG_HOME\"/sxmo/.noring\n" "$icon_ton"
fi
if [ -f "$XDG_CONFIG_HOME"/sxmo/.novibrate ]; then
printf " %s Vibrate ^ rm -f \"$XDG_CONFIG_HOME\"/sxmo/.novibrate\n" "$icon_tof"
else
printf " %s Vibrate ^ touch \"$XDG_CONFIG_HOME\"/sxmo/.novibrate\n" "$icon_ton"
fi
if [ -f "$XDG_CONFIG_HOME"/sxmo/.busy ]; then
end="$(cat "$XDG_CONFIG_HOME"/sxmo/.busy)"
if [ -n "$end" ] && [ "$(date +%s)" -gt "$end" ]; then
rm "$XDG_CONFIG_HOME"/sxmo/.busy
fi
fi
if [ -f "$XDG_CONFIG_HOME"/sxmo/.busy ]; then
printf " %s Busy ^ rm -f \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_ton"
else
printf " %s Busy ^ touch \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tof"
printf " %s Busy for 15 min ^ date '+%%s+15*60' | bc > \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tmr"
printf " %s Busy for 30 min ^ date '+%%s+30*60' | bc > \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tmr"
printf " %s Busy for 1 hour ^ date '+%%s+60*60' | bc > \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tmr"
printf " %s Busy for 2 hour ^ date '+%%s+2*60*60' | bc > \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tmr"
printf " %s Busy for 3 hour ^ date '+%%s+3*60*60' | bc > \"$XDG_CONFIG_HOME\"/sxmo/.busy\n" "$icon_tmr"
fi
}
menuchoices() {
cur_vol="$(volget)"
cur_mic_vol="$(micvolget)"
default_sink_name="$(devicegetdefaultsink)"
default_source_name="$(devicegetdefaultsource)"
grep . <<EOF
$icon_cls Close Menu ^ exit
Output:
$(_sinkssubmenu "$default_sink_name")
$(
if [ "$cur_vol" != "muted" ]; then
printf " %s Volume (%s%%) ^ volup\n" "$icon_aru" "$cur_vol"
printf " %s Volume (%s%%) ^ voldown\n" "$icon_ard" "$cur_vol"
printf " %s Output Mute ^ voltogglemute\n" "$icon_tof"
else
printf " %s Output Mute ^ voltogglemute\n" "$icon_ton"
fi
)
$(_outportssubmenu "$default_sink_name")
Input:
$(_sourcessubmenu "$default_source_name")
$(
if [ "$cur_mic_vol" != "muted" ]; then
printf " %s Volume (%s%%) ^ micvolup\n" "$icon_aru" "$cur_mic_vol"
printf " %s Volume (%s%%) ^ micvoldown\n" "$icon_ard" "$cur_mic_vol"
printf " %s Input Mute ^ mictogglemute\n" "$icon_tof"
else
printf " %s Input Mute ^ mictogglemute\n" "$icon_ton"
fi
)
$(_inportssubmenu "$default_source_name")
Cards:
$(_cardssubmenu)
$(_ringmodesubmenu)
EOF
}
if [ -n "$SXMO_NO_AUDIO" ]; then
sxmo_log "Audio is disabled."
exit
fi
if [ -z "$*" ]; then
set -- menu
fi
cmd="$1"
shift
case "$cmd" in
menu)
while : ; do
CHOICES="$(menuchoices)"
PICKED="$(
printf "%s\n" "$CHOICES" |
cut -d'^' -f1 |
sxmo_dmenu.sh -i -p "Audio"
)"
CMD="$(printf "%s\n" "$CHOICES" | grep -m1 -F "$PICKED" | cut -d '^' -f2)"
eval "$CMD"
done
;;
vol)
verb="$1"
shift
vol"$verb" "$@"
;;
mic)
verb="$1"
shift
mic"$verb" "$@"
;;
device)
verb="$1"
shift
device"$verb" "$1"
;;
notify)
notifyvol "$(volget)"
;;
micnotify)
notifyvol "$(micvolget)"
;;
esac