Detecting drum bpm in a noisy .wav file

I am looking for algorithm(s) to solve the following problem: Given a noisy .wav sound capture (some wind + friction noise on the microphone), how to detect the BPM of a soft drum beat?

I have attempted googling the subject, but the results are quite poor, due to high amount of mp3 related software for both analysis and fingerprint id generation. None of them supply information about how to actually do it.

I am aware of algorithms to remove the noise, but that still leaves me with the problem of detecting BPM. And depending on how the BPM problem is solved, it's possible that I don't even need to denoise (since drum tends to be in the lower frequencies and noise in higher, a simple low-pass might be sufficient pre-processing).

One method that works if there's a relatively strong drum beat is to take the magnitude of the STFT of the waveform, and then auto-correlate it in only the time dimension. The peak of the auto-correlation function will be the beat, or a submultiple of it.

This is equivalent to breaking up the signal into a lot of different frequency bands, finding the amplitude envelope of each, autocorrelating each envelope, and then summing them. The noise and other parts of music are averaged out by the cross-correlation operation.

This is because drum beats produce short-lived sound at many frequencies (vertical lines), while other parts of music are long-lived at only a few frequencies (horizontal lines), and noise is long-lived but random at all frequencies. You can see the beat repetition if you look at an STFT:

I came up with this for a school project to find a single BPM value for entire music files, but it could be adapted to a stream of audio with changing BPM, too. You'd need to process chunks that are at least twice as long as the period of the BPM you're looking for.

• FFT is a generally useful technique for finding periodic signals. There can be a little trickiness if the signal isn't quite as regular as you'd like: a drummer could speed up or slow down over the course of a song--deliberately or not--and this could mess with the FFT results in the frequency domain. Commented Jan 16, 2012 at 3:50
• @Rethunk: If the BPM changes over time, you'll need to do this in chunks, and find the BPM for each. Commented Jan 16, 2012 at 4:20
• Note that beats are commonly associated with music, and you see another part of music in this picture too: horizontal lines, which change height at the beat. So there are basically three energy contributions: beats (verticals), notes (horizontals) and noise (remainder). Commented Mar 10, 2014 at 17:00
• @MSalters: The notes can correlate, too, though Commented Mar 11, 2014 at 0:09

Auto-correlation is certainly a good basic method for that. There are a few things you can do to potentially enhance this further:

1. If you know the frequency spectrum of your drum, bandpass filter the signal so that only the frequencies relevant to the drum remain. Depending on the drum this could be quite narrow and should get rid of the vast majority of the noise.
2. Then calculate the time domain envelope of the signal ("lossy peak" is the easiest way to do this) with a time constant that's roughly matched to the length of the drum beats.
3. Then do the auto-correlation