Command-Line Metronome (Shallow Thoughts)

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Sat, 23 Mar 2024

Command-Line Metronome

I mentioned before that I'm taking beginner guitar lessons. Justin recommends using a metronome for some of the practicing, and that makes sense: I notice that sometimes when I practice I try to go too fast, which might or might not be good for learning the chord changes but it also leads to more mistakes and worse chord quality.

There are probably lots of phone metronome apps, but I'm usually practicing near my computer (where I watch the lessons and where I keep all my notes on chords and rhythms for particular songs), so I thought it would be nice to have a metronome on Linux.

I found a nice one in this reddit thread on command-line metronomes, which I adapted to a shell function in my .zshrc:

metronome() {
    bpm=$1
    play -n -c1 synth 0.004 sine 2000 pad $(awk "BEGIN { print 60/$bpm -.004 }") repeat -
}

So I can say something like metronome 90 specifying a beats-per-minute, and I get a metronome. Neat! I just love the Linux command line.

(Note: play is just a link to sox. Dave says this metronome doesn't work on his Mac, but I think it's just that he hasn't installed sox and had play aliased to something else, whereas sox was preinstalled on my Debian system.)

Adding Duration and Volume

A few weeks later I extended it. The lessons have several skills I'm supposed to practice for a fixed length of time, like 2 minutes. I've been using my eggtimer program for that, but wouldn't it be handy if I could start the metronome and have it automatically stop after a fixed time? Also, it's nice to be able to specify a volume rather than adjusting the overall system volume every time I want a metronome. So now it's:

# Usage: metronome bpm [minutes [volume]]
metronome() {
    bpm=$1
    if [[ $bpm == '-h' || $bpm == '--help' || $bpm == '' ]]; then
        echo 'Usage: metronome bpm [minutes [volume]]'
        return
    fi
    minutes=$2
    volume=$3
    if [[ $minutes != '' ]]; then
        beats=$(awk "BEGIN { print $bpm * $minutes }")
    else
        beats='-'
    fi
    if [[ $volume == '' ]]; then
        volume=1
    fi
    echo "BPM $bpm minutes $minutes Volume $volume"
    play -n -c1 synth 0.004 sine 2000 pad $(awk "BEGIN { print 60/$bpm -.004 }") repeat $beats vol $volume
}

Tags: , , ,
[ 18:37 Mar 23, 2024    More linux | permalink to this entry | ]

Comments via Disqus:

blog comments powered by Disqus