YES, it is ANOTHER beat detection thread!
I searched the forums and Google and didn't really find anything that i like or suited what i was trying to do.
Im not really trying to detect BPM or anything really fancy, just pules coming off the MSGEQ7 chip.
Right now my code is pretty simple, just comparing a new value with the past value. It works but it has some false positives and many false negatives, it also fails if the volume is not very load.
Could anyone describe an algorithm for processing the data coming from the equalizer chip to detect beat spikes?
Grumpy_Mike:
You need to average over several readings then apply a threshold to that.
If you want to get fancy you can apply a moving threshold that is taken from a list of past peaks and troughs and make the threshold ha;f way between.
Haha, that's exactly what I came up with a few mins ago.
I created an array and then i just keep iterating over each space and storing the values in the array. Then check if the new value is greater than the average of the array. Still working out the bugs.
I like the idea of the threshold because it should create a settling value that would help stabilize the detection (if I'm understanding its purpose correctly).
I'll see where i can get with this approach. Thanks.
So I worked with this for a long time trying to get something that I liked. My question: is there something else i can/should be doing with the rolling average of the inputs? Mostly the other things i tried was either too sensitive or not sensitive enough.
I also didn't try the peak and troughs because im not sure if that's the best way to attack this, also I wasn't sure how to define what a peak/trough was vs normal audio in a way that was dynamic.
Anyway, heres excerpt of my code. It uses a "magic number" for the amount of "frames" in the rolling window average, because, contrary to what i initially thought, a lower number made the code more sensitive. Which, makes sense now thinking about it.
int spectrumValue[7];
const int frames = 50;
int frame = 0;
int bass[frames];
int snare[frames];
int hat[frames];
...
int find_average(int ary[], int siz){
double sum = 0;
for (int i = 0; i < siz; i++){
sum += ary[i];
}
return sum/siz;
}
void loop(){
readEq() //im not including this function here on the forums
int new_bass = spectrumValue[0] + spectrumValue[1];
int new_snare = spectrumValue[3];
int new_hat = spectrumValue[6] + spectrumValue[5];
if ((new_snare/find_average(snare, frames)) > 1){
<stuff>
}
if ((new_hay/find_average(hat, frames)) > 1){
<stuff>
}
if ((new_bass/find_average(bass, frames)) > 1){
<stuff>
}
hat[frame] = new_hat;
snare[frame] = new_snare;
bass[frame] = new_bass;
frame++;
if (frame >= frames) frame=0;
}
Recently some researchers have told me they're working on note onset detection algorithms in the Teensy Audio Library. Hopefully later this year or early 2015, good quality beat estimation will become a reality for Arduino sketches (running on Teensy 3.1's 32 bit processor.... normal AVR is far too slow)