#!/bin/bash # ================================================================= # CONFIGURATION – EDIT THESE TWO LINES # ================================================================= SINK_G435="alsa_output.usb-Logitech_G_series_G435_Wireless_Gaming_Headset_202105190004-00.analog-stereo" SINK_FALLBACK="alsa_output.pci-0000_03_00.1.hdmi-surround-extra3" # Rapid‑volume‑up detection RAPID_THRESHOLD=10 # number of VOLUMEUP events in the window RAPID_WINDOW=3 # seconds # ================================================================= # Find the G435 Consumer Control input device automatically # ================================================================= find_g435_event() { for link in /dev/input/by-id/*G435*event*; do if [ -e "$link" ]; then readlink -f "$link" return 0 fi done return 1 } DEVICE="" while [ -z "$DEVICE" ]; do DEVICE=$(find_g435_event) if [ -z "$DEVICE" ]; then echo "G435 input device not found – retrying in 2s..." >&2 sleep 2 fi done echo "Found G435 device: $DEVICE" # ================================================================= # Switch function # ================================================================= switch_to_sink() { local target="$1" pactl set-default-sink "$target" for id in $(pactl list short sink-inputs | awk '{print $1}'); do pactl move-sink-input "$id" "$target" 2>/dev/null done echo "Switched to: $target" } # ================================================================= # Event loop – grab the device exclusively # ================================================================= up_timestamps=() exec 3< <(stdbuf -oL evtest "$DEVICE") while read -u 3 line; do # Volume UP press (115) if [[ "$line" == *"code 115 (KEY_VOLUMEUP)"*"value 1"* ]]; then now=$(date +%s) up_timestamps+=("$now") # prune timestamps older than window cutoff=$((now - RAPID_WINDOW)) new_ts=() for ts in "${up_timestamps[@]}"; do [ "$ts" -ge "$cutoff" ] && new_ts+=("$ts") done up_timestamps=("${new_ts[@]}") count=${#up_timestamps[@]} if [ "$count" -gt "$RAPID_THRESHOLD" ]; then echo "Rapid VOLUMEUP ($count presses) – switching to FALLBACK" switch_to_sink "$SINK_FALLBACK" else echo "Normal VOLUMEUP – switching to G435" switch_to_sink "$SINK_G435" fi # Volume DOWN press (114) – always switch to G435 elif [[ "$line" == *"code 114 (KEY_VOLUMEDOWN)"*"value 1"* ]]; then echo "VOLUMEDOWN – switching to G435" switch_to_sink "$SINK_G435" fi done