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 80 Hz
  • 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!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.