I'm trying to write a tempo detection algorithm for analysis of audio samples. I'm roughly following the approach described in Scheirer, the first stages of which give me some very nice beat onset plots, which I'm happy are correct. The next stages involve the actual tempo detection process, which go something like this:
- Create a comb filter with intervals corresponding to a particular BPM, e.g. for 120BPM the interval between impulses would be 0.5 seconds
- Convolve the onset signal with the comb filter
- Calculate the energy of the resulting signal (this will be the amount of energy the sample contains at the BPM in question)
- Repeat for all BPMs of interest
Quite a neat process (I thought so, at least) and I've used it successfully. My problem stems from the fact that the comb filter convolution step is quite slow.
As I understand it, generally the fastest way to convolve two signals is to transform them into the frequency domain and then multiply, and that's what I was originally doing. While this might be much faster for complicated signals, the comb filter is not itself particularly complicated. I could achieve the same result by adding together delayed signals, where the delay is set by the BPM interval (the pulses in my comb filter are 1 sample wide and have a magnitude of 1). And this is what I've been trying to do.
I'll simplify the problem by saying that my comb filter consists of just 2 pulses, so to convolve I need to add together the original signal with a single delayed signal. For the higher BPMs the pulse interval (delay) will be less, so there will be more overlap between these two signals. This would be fine if addition was the only thing I was doing, but when I square the sum of the signals this leads to a greater total energy in the cases with more overlap. In other words the total energy increases with BPM. The plot below illustrates this effect. It uses the process I described with randomised input signal, i.e. noise. In theory it should give a (roughly) constant energy over all BPMs, but instead I get a distribution that increases with BPM.
I've tried to calculate a normalisation factor by assuming a signal of constant magnitude and calculating the energy of that for different overlaps, but that seems to skew the results the other way. So my question is essentially this:
Is there a way to normalise the total energy of a comb filter convolution, where the signals are convolved using a delay-addition approach?
Hopefully I've explained that well enough (sorry if some of the terminology isn't quite correct) and thanks in advance!