Requirements for a Metronome App

Every now and then I use a metronome while practising. I still have a traditional, spring loaded metronome available. Somewhere I must also have a digital device from the 90ties.

It was always tempting to place the metronome on top of the instrument while practising. But what I learned was that a moving pendulum or blinking LEDs distracts the player from the acoustic signal, the sheet music and the instrument. So one habit of mine was to place the metronome outside the reach of my eyes.

Since we have modern handsets at our disposal at almost any time, an app was a perfect solution. Here are a couple of requirements I have in mind:

  • Absolutely precise timing. There are many apps available, but several have difficulties coping with this non functional requirement.
  • Distraction free user interface. This removes all apps from the remaining list that are based on ads or contain animations like moving pendulums or blinking user interface elements.
  • Straightforward usage. One of the apps I used had a lot of features so that the start/stop button was difficult to locate. And when trying to start the metronome, it complained that I had to configure a couple of settings first.
  • Great user experience. The basic features should be as simple to use as possible. The Start/Stop button should be big enough to use it even at a distance of an arm.
  • Pleasant timbre. I know, de gustibus non est disputandum. But plain sine or square waves IMO sound cheap.

I really liked the Soundbrenner user interface approach, but unfortunately it failed as per the topmost and the second requirement.

After a rather long survey, I found the code of Bad Metronome, which actually provides the precision required. Ironically it provides a control to add some randomisation to its precision :) . I’m currently experimenting with the code so as to learn more about Android programming.

An obvious issue of BadMetronome is that it runs at twice the speed configured. The issue is that the code assumes that 1 sample is expressed in one byte, but actually it’s two of them. In Metronome.java I thus added
beatLength = beatLength * 2;
below the line
int beatLength = (int) Math.round((60.0/bpm)*audioTrack.getSampleRate());