Beat detection

I'm trying to create a beat detection function of a machine producing in the language R. I hosted the audio file on dropbox. It was recorded with 16 bit and 16kHz. I started with some filtering. The frequencies can be seen here. Most backgroundnoise is around 100Hz and I don't really have information above 4000Hz, so i used a bandpassfilter from 300Hz to 4000Hz. The filtered audiofile is also hosted on dropbox and the frequencies now look like this.

I then downsampled to 4000Hz to save data and computation time. Finally I used the hilbert function in combination with autocorrelation to get something like this. With the peak I can calculate that the machine cycle is 70/min, which is correct. This is the first time I'm doing something like this, so how can I improve the preprocessing? Should I downsample even more to save recources?

This method only looks at the loudness of the signal, disregards the frequency completly. Do you think thats good enough for something like this or can you recommend a method that also includes the frequency of the signal?

Calculation of start time

I also have to detect where the machine begins its production. I cut the signals into 1.5 second packets and labeled them. I used some simple metrics like mean and max of the loundness to cluster them like this. My idea was to check wheter its running or not, then use the packets of the running machine to calculate the cycle time. Then I can loop back the amount of the cycle time and check, if the machine is running at that point or not.

I don't really like that approach though. Do you have a better idea? Are there some better features than mean and max?


2 Answers 2


Interesting. I would be very tempted to use correlation and given the OP wants to specifically find the occurrence of a first pulse implies that the correlation interval is restrained to be one pulse cycle wide. (Unless we know further information, and specifically how many pulses occur after a start position- if this is known then further processing can be done on the entire "burst"). The first question to determine the applicability of an optimized correlation approach is how correlated each of the pulses are to each other, within a given sequence and from sequence to sequence (repeatability over time). This can be evaluated by cross-correlating various captures to a representative pulse and looking at the statistics on the peak magnitude of the cross correlation function, and how much margin this allows relative to the "noise" correlation everywhere else. If that were to suggest correlation could be used (by providing a sufficient probability of detection vs probability of false alarm, which such metrics would be clear from this evaluation), I would then determine the mean reference pulse and use that to detect a pulse present or not present condition using a correlation function. This is basically and optimally a matched filter; optimally if the background noise is white. If the noise is not white, then targeted noise rejection filters could also provide significant advantages - this can be determined by capturing the background with no pulses present and evaluating the time and frequency statistics of those captures to see if there are particular details that can be targeted and eliminated (for example 60 Hz spurs from power lines, etc...).

Where a correlation / matched filter approach wouldn't work well is if the content of each pulse in time and frequency is mostly random from pulse to pulse, in which case an optimized receiver would instead consist of a power detector with a pre-selection filter around the dominant frequency content of the pulse prior to detection. The first cross-correlation testing described above would reveal the optimum strategy based on those statistics. In either case, detecting the first (or any) occurrence limits the observation time for decision to be one pulse interval, which then limits the available SNR to make any such decision for any approach (unless other intelligence is known that make a first pulse unique from any other).


I have done beat detection for musical audio.

The algorithm that let me produce this: https://www.youtube.com/watch?v=E9wF-jfksvI&feature=youtu.be

Was achieved by taking the total power in one discrete frame, over a frequency interval of my choosing and passing it through a derivative filter. IIRC, I find the slope of the current power against a moving average of power, and then I manually tune a sensitivity parameter until my algorithm picks up all the drums. The derivative filter makes the algorithm much more sensitive to any sort of pulsing your machine might make.

Incase it helps you, I have some C++ code here: https://github.com/HarrisonLeece/Avalanche/tree/master/b_avalanche_twp_former

Specifically, you are going to want to look at energybands3.cpp

Pardon any dust, it is my first C program.

I will also say though, that I use an open source audio filtration model to filter the audio before I try to find drums, you might want to consider doing something similar. IDK if this is relevant to you. You say that your algorithm is working. And if it works it works, but perhaps you are concerned about its generalize application, and perhaps this can help.


Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.