mitchell vitez blog music art media dark mode

Logarithmic Metronome

I made a metronome.

It’s based on a normal metronome, where you might jump around by 10bpm during practice, and stay in the 60–120bpm range.

However, the difference between 110bpm and 120bpm is about 9%, while the difference between 60bpm and 70bpm is about 17%. The percentage gap is about twice as big, because it’s relative to a number about twice as small.

When you wrap around from 120 to 60 on a normal metronome, you’re making 20bpm jumps when you were just making 10, and on my metronome you’re making ~14bpm jumps when you were just making ~13.

This metronome smooths out the learning curve by jumping about 12% each time. The exact number to multiply by is \(2^{1/6}\).

So instead of the top row’s division of the range, we do the bottom one:

60 70 80 90 100 110 120
60 67 76 85 95 107 120

These numbers (and the big number up top on the metronome) are rounded. The actual calculated tempo number is in gray below the play/pause button.

The app is super simple—it’s a pure vanilla JavaScript web app that just keeps track of a tempo, and whether or not sound is currently playing. While the JavaScript event loop isn’t a great environment for precise async timer code, my app corrects for timer drift, and uses a 25ms lookahead plus scheduling clicks 100ms ahead to keep precise timing. While the metronome is playing (as it is throughout my piano practice sessions), the app keeps the screen on by requesting the browser’s wakelock.

The app is designed to fit on my phone and look decent on an OLED screen, so it has a solid black background and a vertical layout. The buttons are big and easily tappable, especially the ones I use the most. The click sound is an electronic kick drum click where I EQed out any frequency ranges I didn’t like.

It does exactly what I want and no more.

Sometimes you have to treat yourself.