My name is Stephen Schieberl. I am a Creative Technology Lead at Wieden+Kennedy in Portland, Oregon. I build everything from large format installations to experimental interactive art to database-driven web sites and more.
Pictured: Calculating tempo in real time in Cinder I'm writing DJ software for Android . Before I attempt to incorporate tempo detection and waveform display, I did a prototype in Cinder /C++ using my KissFFT block. I bounced out a couple tests against some of my tunes. Check out the video for the results. Both tracks are 126bpm, but have very different levels and beat arrangements. I woke up in the middle of the night this week and jotted down the following: Transform audio into frequency domain Low pass filter the FFT results to isolate bass Transform audio back to time domain For each sample, compare value with neighboring samples If sample is higher than neighbors, record peak For each subsequent peak, add distance from prior peak into a list Average peak distances Divide sample rate by average, multiply results by seconds to calculate tempo Record tempo for each buffer At end of file, count up the tempo which occurred most frequently -- that is the tempo I added a filter method to my KissFFT block (which now includes a basic tempo detection example). By zeroing out all values above a certain low frequency, then restoring the data to the time domain, I can analyze just the bass of a track. From there, I just went through the data and measure the distance between all samples that were higher than their neighbors. Taking some lessons I learned in creating Magnetic 's peak detection feature, I made the number of neighbors variable. I found that, generally, any sample which was higher than the nearest six samples in each direction constitutes a peak. I keep the distance between peaks in a vector and average the list to come up with a tempo. The first test I performed against a four-on-the-floor (steady beat) track worked great. The tempo was less accurate when the beats didn't occur exactly on a quarter note or when there was a lot of sub bass. Taking notes from Traktor Pro , I added a tempo analysis range. Even Traktor Pro, arguably the most advanced DJ software available, will often give inaccurate results without reasonable limits specified. Honing in on a realistic range gives very accurate results. I noticed that changing the number of neighbors used to detect a peak can produce wild variations in the results. I added a limit of 110bpm to 150bpm, the same I use in Traktor, to more intelligently guess the right tempo. If the tempo is too high, the number of neighbors used to detect a peak increases. Too low, and it decreases. Per my notes, I use the tempo which is recorded the most often across the entire track. As this video demonstrates, the tempo starts holding steady after about thirty seconds, ensuring I'll have an accurate BPM value in what will likely be a four to ten minute track.