After last weeks mixed success, I started implementing the more advanced techniques Yov408 describes in his article. However, nothing seemed to improve the calculated beats per minute. I was about to go and implement the Fourier Transform, something which I wanted to avoid in order to keep the algorithm zippy. But I went back to the spreadsheet and discovered a much simpler solution.
Download the NetBeans example project
The second sample I tried has about 3 or 4 beats too much. Upon closer inspection of those misses, those are all instances where the energy went above the threshold during for only one sample.
Once I understood the nature of the problem, it was easy to implement a solution that only detects a beat when the energy is high enough for a few more samples. I put this into code and was amazed by the results. Pretty much any song I used resulted in a BPM count withing 5 BPM of the actual count.
The adapted algorithm is:
Every 1024 samples:
 Compute the instant sound energy ‘e’ on the 1024 new sample values taken in (an) and (bn) using the formula (R1)

Compute the average local energy
with (E) sound energy history buffer: <p align="center">
(R3)</li>  Shift the sound energy history buffer (E) of 1 index to the right. We make room for the new energy value and flush the oldest.
 Pile in the new energy value ‘e’ at E[0].

If ‘e’ > ‘C*
’ we detect a possible beat. If a possible beat was not detected in the previous calculation, we start counting, N = 0. Otherwise, N is increased by one.</em> </li>  If N equals a threshold (3 is a pretty good value), a true beat is detected. </ul>
Given the simplicity of the algorithm I think this is an incredible result and good enough to move into the next step of the project: Porting this to small devices.
To be continued …
Download the NetBeans example project
BTW for those following along via email or the RSS feed, come visit the site and let me know what you think of the new logo.