#!/bin/bash bpm=$1 (( i = bpm? 6000/bpm-1: 74, sec = i/100, ms = i%100, bpm )) || bpm=80 printf -v interval "%i.%02i" $sec $ms help=" + - or (pg)up,dn to adjust tempo any key to enter a numeric tempo h for help q to quit" printf '\e[?25l\e[11;1]\e[H\e[2J%i bpm' $bpm [ $TERM = linux ] || printf '\n\n%s' \ 'consider switching to plain linux console' # the escape for changing bell length only works there, leading to # inaccuracy when some terms have a long bleat -- not to mention # some don't even have a bell at all amixer -q set Beep unmute # or the equivalent command for non-alsa setups, if needed # if still mute, try (as root) modprobe pcspkr trap 'amixer -q set Beep mute; exit' INT while [ "$input" ] || printf '\a'; do unset input read -sn1 -t $interval input || continue case "$input" in +|A|5) (( bpm++ )) ;; -|B|6) (( bpm-- )) ;; $'\E'|[|\~) # up/down keys need this, despite WORKING FINE JUST A SECOND AGO ;; q) amixer -q set Beep mute printf '\e[?25h\e[H\e[JGood job %s for practicing.\n' "$USER" exit ;; h) printf '\e[H\e[J%s\n\n\t%s' "$help" "press any key" read -n 1 ;; *) printf '\e[H\e[JEnter a tempo: ' old=$bpm read bpm ;; esac if (( i=6000/bpm-1, sec = i/100, ms = i%100, bpm )); then printf -v interval "%i.%02i" $sec $ms # HA, goodbye numfmt, my last external process else bpm=$old; fi printf '\e[H\e[J%i bpm' $bpm done