How to detect the BPM of a song in php [closed]

Solution 1:

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.

Solution 2:

The keywords to search for are "Beat Detection", "Beat Tracking" and "Music Information Retrieval". There is lots of information here: http://www.music-ir.org/

There is a (maybe) annual contest called MIREX where different algorithms are tested on their beat detection performance.

http://nema.lis.illinois.edu/nema_out/mirex2010/results/abt/mck/

That should give you a list of algorithms to test.

A classic algorithm is Beatroot (google it), which is nice and easy to understand. It works like this:

  1. Short-time FFT the music to get a sonogram.
  2. Sum the increases in magnitude over all frequencies for each time step (ignore the decreases). This gives you a 1D time-varying function called the "spectral flux".
  3. Find the peaks using any old peak detection algorithm. These are called "onsets" and correspond to the start of sounds in the music (starts of notes, drum hits, etc).
  4. Construct a histogram of inter-onset-intervals (IOIs). This can be used to find likely tempos.
  5. Initialise a set of "agents" or "hypotheses" for the beat-tracking result. Feed these agents the onsets one at a time in order. Each agent tracks the list of onsets that are also beats, and the current tempo estimate. The agents can either accept the onsets, if they fit closely with their last tracked beat and tempo, ignore them if they are wildly different, or spawn a new agent if they are in-between. Not every beat requires an onset - agents can interpolate.
  6. Each agent is given a score according to how neat its hypothesis is - if all its beat onsets are loud it gets a higher score. If they are all regular it gets a higher score.
  7. The highest scoring agent is the answer.

Downsides to this algorithm in my experience:

  • The peak-detection is rather ad-hoc and sensitive to threshold parameters and whatnot.
  • Some music doesn't have obvious onsets on the beats. Obviously it won't work with those.
  • Difficult to know how to resolve the 60bpm-vs-120bpm issue, especially with live tracking!
  • Throws away a lot of information by only using a 1D spectral flux. I reckon you can do much better by having a few band-limited spectral fluxes (and maybe one broadband one for drums).

Here is a demo of a live version of this algorithm, showing the spectral flux (black line at the bottom) and onsets (green circles). It's worth considering the fact that the beat is extracted from only the green circles. I've played back the onsets just as clicks, and to be honest I don't think I could hear the beat from them, so in some ways this algorithm is better than people at beat detection. I think the reduction to such a low-dimensional signal is its weak step though.

Annoyingly I did find a very good site with many algorithms and code for beat detection a few years ago. I've totally failed to refind it though.

Edit: Found it!

Here are some great links that should get you started:

http://marsyasweb.appspot.com/

http://www.vamp-plugins.org/download.html

Solution 3:

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

Solution 4:

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)