How to detect the BPM of a song in php

Viewed 90589

How can the tempo/BPM of a song be determined programmatically? What algorithms are commonly used, and what considerations must be made?

10 Answers

This is challenging to explain in a single StackOverflow post. In general, the simplest beat-detection algorithms work by locating peaks in sound energy, which is easy to detect. More sophisticated methods use comb filters and other statistical/waveform methods. For a detailed explication including code samples, check this GameDev article out.

Beat extraction involves the identification of cognitive metric structures in music. Very often these do not correspond to physical sound energy - for example, in most music there is a level of syncopation, which means that the "foot-tapping" beat that we perceive does not correspond to the presence of a physical sound. This means that this is a quite different field to onset detection, which is the detection of the physical sounds, and is performed in a different way.

You could try the Aubio library, which is a plain C library offering both onset and beat extraction tools.

There is also the online Echonest API, although this involves uploading an MP3 to a website and retrieving XML, so might not be so suitable..

EDIT: I came across this last night - a very promising looking C/C++ library, although I haven't used it myself. Vamp Plugins

If you can manage to interface with python code in your project, Echo Nest Remix API is a pretty slick API for python:

There's a method analysis.tempo which will give you the BPM. It can do a whole lot more than simple BPM, as you can see from the API docs or this tutorial

The general area of research you are interested in is called MUSIC INFORMATION RETRIEVAL

There are many different algorithms that do this but they all are fundamentally centered around ONSET DETECTION.

Onset detection measures the start of an event, the event in this case is a note being played. You can look for changes in the weighted fourier transform (High Frequency Content) you can look for large changes in spectrial content. (Spectrial Difference). (there are a couple of papers that I recommend you look into further down) Once you apply an onset detection algorithm you pick off where the beats are via thresholding.

There are various algorithms that you can use once you've gotten that time localization of the beat. You can turn it into a pulse train (create a signal that is zero for all time and 1 only when your beat happens) then apply a FFT to that and BAM now you have a Frequency of Onsets at the largest peak.

Here are some papers to lead you in the right direction:

http://www.elec.qmul.ac.uk/people/juan/Documents/Bello-TSAP-2005.pdf

http://bingweb.binghamton.edu/~ahess2/Onset_Detection_Nov302011.pdf

Here is an extension to what some people are discussing:

Someone mentioned looking into applying a machine learning algorithm: Basically collect a bunch of features from the onset detection functions (mentioned above) and combine them with the raw signal in a neural network/logistic regression and learn what makes a beat a beat.

look into Dr Andrew Ng, he has free machine learning lectures from Stanford University online (not the long winded video lectures, there is actually an online distance course)

Perform a Fourier transform, and find peaks in the power spectrum. You're looking for peaks below the 20 Hz cutoff for human hearing. I'd guess typically in the 0.1-5ish Hz range to be generous.

SO question that might help: Bpm audio detection Library

Also, here is one of several "peak finding" questions on SO: Peak detection of measured signal


Edit: Not that I do audio processing. It's just a guess based on the fact that you're looking for a frequency domain property of the file...


another edit: It is worth noting that lossy compression formats like mp3, store Fourier domain data rather than time domain data in the first place. With a little cleverness, you can save yourself some heavy computation...but see the thoughtful comment by cobbal.

To repost my answer: The easy way to do it is to have the user tap a button in rhythm with the beat, and count the number of taps divided by the time.

I'd imagine this will be easiest in 4-4 dance music, as there should be a single low frequency thud about twice a second.

Related