This is preEetTty awesome!
I had this project in mind for a while but I could never find the time for it. Now that I did, I am regretting I did not do it before because it is soOoOo cool! I put together a couple of SoX commands to add a metronome tempo to some of the music I listen to while I am doing long runs. Are you wondering WHY or HOW? Read on!
The WHY is straightforward. When looking to optimize running, one of the first recommendations is to get the running cadence up to 180 steps per minutes. The optimal way is to follow the rhythm of a metronome set at 180 beats per minutes (BPM) and try to do as many steps. However bringing a metronome along during the run, beeping at 180 BPM, is cumbersome, and BORING! An alternative would be to search for music at 180 BPM, there are plenty of options, but in my opinion the choice is limited. More importantly, listening to music at 180 BPM makes me want to run faster, which defeats the purpose of the steady, slow, long run… A nicer way is to add a metronome beat to a sound file, so to have something nice to listen to while a simultaneous beat provides the tempo for the run’s cadence. Moreover, the metronome beat could also be added to podcasts and audiobooks which are, in my opinion, better indicated for long run since they miss the ‘motivational’ drive of a 180 BPM music piece.
I made the metronome beat with the Swiss Army knife of sound processing programs (i.e., SoX). SoX is very handy because besides from allowing many sound transformations it can be called from the command line. Therefore, SoX commands can be integrated into bash scripts to batch-process a bunch of files. [NOTE: I worked out this example in Debian Linux, for everything below to work one needs 1) SoX with the mp3 extension and 2) the id3 tagging tool id3v2. Moreover, I am not sure the command “play” exists in Windows, but you could play the sound with, for example, VLC media player and you could visualize it with audacity.]
The metronome beat is a carrier sine wave of 500Hz which is amplitude modulated by a square wave of three Hertz (3 beats per second equals 180 beats per minute). I chose 500 Hz because I found it not too annoying to listen too. In fact, ear sensitivity is best in the range 2000 to 5000 Hz, but I find those high frequencies annoying.
Below is the SoX command to create the carrier frequency: a five seconds long 500 Hz sine wave.
sox -n -r 8000 output.wav synth 5 sine 500
SoX can create the carrier frequency with the “synth” command and the “-n” option. The “-r” option specifies the sampling frequency (below I set it to 8000 Hz so that the output file generated is very small, the default is 48 kHz). SoX saves the output into the file “output.wav”. After “synth” the length of the sound to synthesize is specified in seconds (5). “Sine 500” specify a sinusoid of 500 Hz.
Alternatively, the command “play” plays the sound through the speaker instead of saving it into an output file:
play -n -c1 synth 5 sine 500
The option “-c1” makes it a mono sound. To listen to a more “ear-sensitive” sound replace the 500 with, for example, 3000.
To obtain the metronome beat I modulated the 500 Hz carrier frequency with a square wave. I tried a sine wave too, which prevents the clicks and is, therefore, more pleasant to listen to. However, the beats are less sharp than with a squared modulation and therefore less distinguishable. Personally, I would not like to lose a beat… Moreover, when mixing the metronome beat to the sound file the clicks are softer than when playing the metronome beat alone. Sox specifies the amplitude modulation with the “amod” option, preceded by the type of waveform (square) and followed by the frequency in Hz like:
square amod 3
Concatenating both commands creates the metronome beat: a 500 Hz sine modulated in amplitude by a square waveform with a frequency of 3 Hz.
sox -n -r 8000 output.wav synth 5 sine 500 synth 5 square amod 3
So in practice there are two five-seconds-long waveforms, one sine and one square, the second of which Amplitude MODulates the first. To compare this metronome beat to a sine modulated call:
echo "Square modulated" play -n -c1 synth 5 sine 500 vol 0.5 synth 5 square amod 3
echo "Sine modulated" play -n -c1 synth 5 sine 500 vol 0.5 synth 5 sine amod 3
[NOTE: if you want to double check that the beats are really three per seconds, I find the most convenient way is to create a second long sine wave and load the signal in audacity. There you can count/see the three ‘peaks’ corresponding to the beats.]
I then add this “beat” to a sound file. To do this I need to generate a beat with the same duration and sampling frequency of the sound file to which I want to add the beat. The command ‘soxi’ with the options ‘-d’ and ‘-r’ returns duration and sampling frequency respectively. Both commands can be passed to sox into one go, like this:
sox -n -r `soxi -r file1.mp3` "output.mp3" synth `soxi -d file1.mp3` sine 500 vol 0.5 synth `soxi -d file1.mp3` square amod 3
file1.mp3 is a temporary file I created transforming the stereo audio file into a mono.
sox "file2addAbeat2.mp3" "file1.mp3" remix 1
I converted from stereo to mono only to save space in my mp3 player. Why am I creating mp3 files instead of an open format? Because my mp3 player is dated and it does not read the files’ tags other than the mp3 format. Therefore, to easily select what I want to play, I need to be able to process the tag.
I then mix the two into one final file,
sox -m "file1.mp3" "output.mp3" "final.mp3"
With SoX, it is also possible to have the beat played into one hear and the music/podcast/audiobook on the other, that is one on the left and the other on the right channel. One could argue that it is then easier to focus on/ignore the sound in a given hear because they are spatially separated. This could be helpful if the metronome beat is experienced as annoying and one decides to ignore it. In that case, besides experimenting with other carrier frequencies and amplitude modulations (e.g. a sine instead of a square wave), SoX offers also the option of manipulating the volume of the single channels/sound streams. I still prefer to keep the two streams into a single channel because by merging them the resulting file is smaller and I get to squeeze more music into my mp3 player. Moreover, I am not converting to this “enhanced-metronome beat format” all the files I would listen during a run. Converting about 10% is usually enough for the exercises and it keeps the (mind) doctor away.
I embedded the SoX commands into a bash script that processes all “ogg” or “opus” files in a given directory. I can then use the bash script on a bunch of files I downloaded or after a call to youtube-dl with the “-x” options which extracts the audio only. Enjoy!