#!/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