In spring, I built a beat detection algorithm in Rust. It works for very simple songs but the problem is that I have to adjust the parameters of the algorithm manually for each genre and sometimes for each song. It never worked really well. I'm looking for a simple approach with a good trade-off between accuracy and complexity.
My current approach is: I use a ring buffer with a size of 1024. The ring buffer always contains the latest music samples. The sampling rate is 44,1kHz, therefore the buffer contains the latest
1024/44100=23,2ms of audio.
I use the ring buffer because my audio input library gives me a variable number of
16 bit samples between 400 and 700 on each callback. This way I can better cope with this problem. My algorithm works as follows:
- On every callback, I merge the new samples with the ring buffer.
- I copy the data from the ring buffer into a new array and apply a low pass filter with a cut-off frequency of
- I check if the last beat is >120ms away; if not; return
- I check if, since the last beat, the maximum amplitude of the low-passed data was below an absolute value of
500(32768 is max, 16 bit) --> to prevent that the same beat gets recognized multiple times
- I check if the low-passed data contains a maximum absolute value bigger than
24000(again, 32768 is max)
- if yes => beat found
This only works for super simple music, like the song Kids by MGMT. Also, some songs have beats that are slightly below my threshold of 24000.. but if I decrease it, I get false positives in songs that worked before...
Do you have any suggestions for me? How should I tweak my parameters? How could my algorithm be improved? Thank you a lot in advance!