#!/bin/bash # printVolCont # continuously print alsa or pulse # master volume as ascii slider ─────│───── ☐ Ξ · ‖ • # to be used with tint2 executor (example at the bottom). # needs: awk, bc, sed, grep, alsactl, amixer # 2017/2018 by bronto, fixed by o9000 # license: WTFPL – Do What the **** You Want to Public License # config chars="50" fil="·" poschar="│" posnum="true" # show percent number instead of "$poschar" char posmute=" ___ " # debug debug="false" # checks command -v awk >/dev/null 2>&1 || { echo "I need awk, exiting." >&2; exit 1; } command -v bc >/dev/null 2>&1 || { echo "I need bc, exiting." >&2; exit 1; } command -v sed >/dev/null 2>&1 || { echo "I need sed, exiting." >&2; exit 1; } command -v alsactl >/dev/null 2>&1 || { echo "I need alsactl, exiting." >&2; exit 1; } command -v amixer >/dev/null 2>&1 || { echo "I need amixer, exiting." >&2; exit 1; } # pulse # https://unix.stackexchange.com/questions/132230/read-out-pulseaudio-volume-from-commandline-i-want-pactl-get-sink-volume pulse () { sink=$( pactl list short sinks | sed -e 's,^\([0-9][0-9]*\)[^0-9].*,\1,' | head -n 1 ) volPercents=$( pactl list sinks | grep '^[[:space:]]Volume:' | head -n $(( sink + 1 )) | tail -n 1 | sed -e 's,.* \([0-9][0-9]*\)%.*,\1,' ) # missing mute mute=$( pactl list sinks | grep 'Mute' | head -n $(( sink + 1 )) ) # patch mute state to alsa (where 'off' equals 'Mute: yes') if [[ "$mute" = *"yes"* ]]; then mute="off" fi # i'am pulse mode=" Pulse" # Pulse } # alsa alsa () { volPercents=$(awk -F"[^0-9]*" '/dB/ { print $3 }' <(amixer sget Master)) volPercents=$(awk '{print $1; exit}' <(echo "$volPercents")) # just the first value mute=$(awk -F"[][]" '/dB/ { print $6 }' <(amixer sget Master)) mute=$(awk '{print $1; exit}' <(echo "$mute")) # just the first value # i'am alsa mode="" # Alsa } # automagic alsaOrPulse () { alsa if [[ -z "$volPercents" ]]; then pulse if [[ -z "$volPercents" ]]; then echo "error getting volume" fi fi } # main (echo ""; stdbuf -oL alsactl monitor) | while read do # automagic alsaOrPulse if (( volPercents > 100 )); then volPercents=100 fi if (( volPercents < 0 )); then volPercents=0 fi if [ "$posnum" == "true" ]; then pos="$volPercents" else pos="$poschar" fi if [ "$mute" == "off" ]; then pos="$posmute" fi [ "$debug" = true ] && { echo "$pos pos" ;} [ "$debug" = true ] && { echo "$volPercents volPercents" ;} faktor=$(echo "scale=2;$chars/100" | bc) vol=$(echo "scale=0;($volPercents*$faktor+0.5)/1" | bc -l) [ "$debug" = true ] && { echo "$vol vol" ;} postloop=$(echo "$chars-$vol" | bc) if (( vol == chars )); then postloop=0 fi preloop=$(echo "$vol-1" | bc) if (( vol == 0 )); then preloop=0 postloop=$(echo "$chars-$vol-1" | bc) fi [ "$debug" = true ] && { echo "$preloop preloop" ;} [ "$debug" = true ] && { echo "$postloop postloop" ;} a=$(for i in $(seq 1 $preloop); do printf "%s" "$fil" done) b=$(printf "%s" "$pos") c=$(for i in $(seq 1 $postloop); do printf "%s" "$fil" done) printf "$a$b$c$mode\n" done # tint2 executor example: #execp = new #execp_centered = 1 #execp_has_icon = 0 #execp_command = printVolCont #execp_continuous = 1 #execp_font = cuprum 8 #execp_font_color = #111111 100 #execp_padding = 0 0 0 #execp_tooltip = volume #execp_mclick_command = amixer set Master toggle #execp_rclick_command = amixer set Master 5%+ #execp_lclick_command = amixer set Master 5%- #execp_uwheel_command = amixer set Master 1%- #execp_dwheel_command = amixer set Master 1%+