#!/bin/bash if [[ "$@" == "" ]]; then echo "spkplay " echo " t set tempo to beats per minute (default 120)" echo " o switch to octave #" echo " o+ o- change one octave up or down" echo " l set note length to 1/th, i.e. l4 for quarter notes." echo " ml mn ms mx change to legato, normal, staccato or very-staccato playing style" echo " c c+ d- d d+ ... play this note, with the current octave, length, tempo and style" echo " c. extend note to 3/2 its normal duration" echo " p pause (with the current length and tempo)" echo " h enable verbose output (for debugging)" exit fi declare -a beepies octave=3 tempo=120 length=4 # n=normal (7/8ths), s=staccato (3/4ths), l=legato (1/1) stac=n declare -A notefrq; notefrq['c']=4188 notefrq['c+']=4436 notefrq['d-']=4436 notefrq['d']=4700 notefrq['d+']=4980 notefrq['e-']=4980 notefrq['e']=5276 notefrq['f-']=5276 notefrq['e+']=5588 notefrq['f']=5588 notefrq['f+']=5920 notefrq['g-']=5920 notefrq['g']=6272 notefrq['g+']=6644 notefrq['a-']=6644 notefrq['a']=7040 notefrq['a+']=7460 notefrq['b-']=7460 notefrq['b']=7904 notefrq['b+']=8376 notefrq['p']=10 debug=0 for s in "$@" ; do first="${s:0:1}" rest="${s:1}" (( debug==1 )) && echo "$s" case $first in h) debug=1 (( debug==1 )) && echo " debug on" ;; o) case $rest in +) (( octave++ )) ;; -) (( octave-- )) ;; *) octave="$rest" ;; esac (( debug==1 )) && echo " octave $octave" ;; t) tempo=$rest (( debug==1 )) && echo " tempo $tempo" ;; l) length=$rest (( debug==1 )) && echo " length 1 / $length" ;; m) stac=$rest (( debug==1 )) && echo " music $stac" ;; *) #notes note="$s" extralength="0" [[ "${s:(-1):1}" == "." ]] && note="${s:0:(-1)}" && extralength="1"; (( debug==1 )) && echo " note $note extralength $extralength" frq="$(( ${notefrq[$note]} / ( 2 ** ( 8 - octave ) ) ))"; [[ "$note" == "p" ]] && frq="1"; fulllen="$(( 2000 * 120 / tempo / length ))"; (( extralength == 1 )) && fulllen="$(( fulllen * 3 / 2 ))"; case $stac in n) sndlen="$(( fulllen * 7 / 8 ))"; ;; s) sndlen="$(( fulllen * 6 / 8 ))"; ;; l) sndlen="$fulllen"; ;; x) sndlen="$(( fulllen / 2 ))"; ;; *) sndlen="$(( fulllen / 3 ))"; ;; esac pauslen="$(( fulllen - sndlen ))"; beepies+=( -n -f $frq -l $sndlen -D $pauslen ); (( debug==1 )) && echo " out: frq $frq len $sndlen pau $pauslen" ;; esac done # remove the first -n, otherwise beep will not interpret *any* of the arguments unset -v beepies[0]; beep "${beepies[@]}"