#!/usr/bin/env bash # Simple wrapper around pactl to keep volume in [0,100]% range. Optionally # plays an indicator sound after changing the volume # # Args: # 1: Change amount in percent. An integer # 2: Sound file to play. No sound is played if omitted or invalid declare -r ADJUST="$1" declare -r NOTIFY_SOUND="$2" declare -ir MAX_VOLUME=100 set_volume() { if ! pactl set-sink-volume @DEFAULT_SINK@ "${1}%"; then printf "Failed to set default sink volume\n" >&2 exit 1 fi [[ -z "$NOTIFY_SOUND" ]] || play_notify_sound "$NOTIFY_SOUND" } play_notify_sound() { if ! [[ -r "$1" ]]; then printf "File '%s' is not readable" "$1" >&2 exit 1 fi if command -v ffplay &>/dev/null; then ffplay -nodisp -autoexit -v error "$1" elif command -v afplay &>/dev/null; then afplay "$1" else printf "Failed to find sound player for volume indication sound\n" >&2 fi } if ! [[ "$ADJUST" =~ ^-?[0-9]+$ ]]; then printf "No volume change amount provided\n" >&2 exit 1 fi readonly curr_volume=$(pactl get-sink-volume @DEFAULT_SINK@ | awk ' match($0, /[0-9]+%/) { printf "%s", substr($0, RSTART, RLENGTH - 1) }') if ! [[ "$curr_volume" =~ ^[0-9]+$ ]]; then printf "Failed to find default sink's volume: %s\n" "$curr_volume" >&2 exit 1 fi declare -ir new_volume=$((curr_volume + ADJUST)) printf "Changing volumes from %d -> %d\n" "$curr_volume" "$new_volume" >&2 if [[ $new_volume -gt $MAX_VOLUME ]]; then set_volume $MAX_VOLUME elif [[ $new_volume -lt 0 ]]; then set_volume 0 else set_volume $new_volume fi