0
$\begingroup$

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!

$\endgroup$
1

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.