#!/bin/sh get_cards() { pacmd list-cards | awk -F '[\t ]+' ' function printcard() { print cardindex " " cardname " " carddesc } $2 ~ "index:" { if(incard) { printcard() } incard=1 cardindex=$3 } incard && $2 ~ "name:" { cardname=substr($3, 2, length($3) - 2) } incard && $2 ~ "device.description" { carddesc=substr($0, index($0, "= ") + 2) } END { printcard() } ' } # First line will always be the active profile get_selected_card_profiles() { pacmd list-cards | awk -F '[\t ]+' \ -v selected_card_index="$selected_card_index" ' BEGIN { profile_count=0 } function print_card() { if(do_print) { print profile_names[i] " " profile_descs[i] } } $2 ~ "index:" && $3 == selected_card_index { incard=1 } incard && $2 ~ "profiles:" { inprofiles=1 next } inprofiles && $2 ~ "active" { for(i = 0; i < profile_count; i++) { if(profile_names[i] == substr($4, 2, length($4) - 2)) { current_card_index=i do_print=1 } print_card() } for(i = 0; i < current_card_index; i++) { print_card() } exit } inprofiles { profile_names[profile_count] = substr($2, 0, length($2) - 1) profile_descs[profile_count] = substr($0, index($0, ": ") + 2) profile_count++ } ' } select_default_sink_card() { selected_card=$(pacmd list-sinks | awk -F '[\t ]+' ' $2 == "*" && $3 ~ "index:" { incard=1 } incard && $2 == "card:" { print $3 " " substr($4, 2, length($4) - 2) exit } ') } select_card_manually() { card_options=$(get_cards) selected_option_index=$(printf %s\\n "$card_options" | rofi -dmenu -format 'i') selected_option_index=$((selected_option_index+1)) selected_card=$(printf %s\\n "$card_options" | sed -n "${selected_option_index}p") } print_usage() { printf ' Usage: le-audio [OPTIONS] Manage audio profiles Options -a Auto - Auto-select the card for the default sink -f Filter - Filter out "off" profiles -c Cycle - Auto-select the next audio profile after the current one Utility written by Dakedres (dakedres.sys42.net) ' } while getopts 'afc' args; do case "$args" in a) arg_auto_select_card=true ;; f) arg_filter_off_profile=true ;; c) arg_select_next_profile=true ;; ?) print_usage exit ;; *) >&2 echo "Invalid option '${args}'" esac done if [ "$arg_auto_select_card" = true ]; then select_default_sink_card else select_card_manually fi selected_card_index=$(printf %s\\n "$selected_card" | awk '{ print $1 }') echo "$selected_card" if [ "$arg_filter_off_profile" = true ]; then selected_card_profiles=$(get_selected_card_profiles | grep -v '^off') else selected_card_profiles=$(get_selected_card_profiles) fi if [ "$arg_select_next_profile" = true ]; then selected_profile_index=1 else selected_profile_index=$(printf %s\\n "$selected_card_profiles" | rofi -dmenu -format "i") fi if [ -z "$selected_profile_index" ]; then >&2 echo "No profile selected" exit 1 fi printf %s\\n "$selected_card_profiles" | awk \ -v selected_profile_index="$selected_profile_index" \ -v selected_card="$selected_card" \ -v qt="'" ' NR-1 == selected_profile_index { split(selected_card, split_card, " ") printf "pactl set-card-profile" " " split_card[1] " " $1 $1="" print " && notify-send " qt "Set audio profile to" $0 qt } ' | sh