BeatDetect.js
BeatDetect.js
is a JavaScript ES6 component that calculates the BPM of a track, with its time offset and the time offset to its first true beat. There are several options to fine tune the process, but BeatDetect.js
works best with modern music (even better on EDM music), based on 4/4 time signature.
With ~5Ko minified, BeatDetect.js
is designed to be stable and remain as light as possible. It is meant to be used client side ; unfortunately, the web audio API is not supported in nodejs.
Get Started
This repository was made to store documentation, test bench and source code. If you want to include this component in your project, you either need the src/BeatDetect.js
file if you have an assets bundler in your project, or use the dist/BeatDetect.min.js
to use the minified component. This minified file is compiled in ES5 JavaScript for compatibility reasons. The unminified file is, in the contrary, coded in ES6 JavaScript.
You must first instantiate a BeatDetect.js
component, with several options as follows (none of them are mandatory, here are presented the default values) :
import BeatDetect from './src/BeatDetect.js';
// Component presented with default values
const beatDetect = new BeatDetect({
sampleRate: 44100, // Most track are using this sample rate
log: false, // Debug BeatDetect execution with logs
perf: false, // Attach elapsed time to result object
round: false, // To have an integer result for the BPM
float: 4, // The floating precision in [1, Infinity]
lowPassFreq: 150, // Low pass filter cut frequency
highPassFreq: 100, // High pass filter cut frequency
bpmRange: [90, 180], // The BPM range to output
timeSignature: 4 // The number of beat in a measure
});
Once the instance is created, you can now analyse track by sending the track url to the getBeatInfo()
public method :
beatDetect.getBeatInfo({
url: `./demo/audio/Teminite - Don't Stop.mp3`,
name: `Don't Stop from Teminite` // Optional argument, only for logging
}).then(info => {
console.log(info.bpm); // 140
console.log(info.offset); // 0.1542
console.log(info.firstBar); // 0.1.8722
}).catch(error => {
// The error string
});
Since the processing is asynchronous, you can call it in loops, but beware that it implies a significant load on the CPU. Because the getBeatInfo()
method returns a Promise
, it might be a better idea to chain them!
You can test those values in a mixing software, or in a AudioVisualizer's timeline component, that draws a waveform into a canvas with beat bars that scrolls over playback, the same used in DJ softwares! Just instantiate it with the provided BPM and firstBar values to check their accuracy.
This component also provides a method to manually determine a BPM using the mouse click :
beatDetect.tapBpm({
element: document.getElementById('my-clickable-element'),
precision: 4, // Floating point for result
callback: bpm => {
// Do whatever you want with it
}
});
This repository includes examples on how to use this component with hardcoded urls, or with tracks selected by the user (see example.html).
You're now good to go! If however you need more information, you can read the online documentation.
Development
If you clone this repository, you can npm install
to install development dependencies. This will allow you to build dist file, run the component tests or generate the documentation ;
npm run build
to generate the minified file ;npm run dev
to watch for any change in source code ;npm run server
to launch a local development server ;npm run doc
to generate documentation ;npm run test
to run unit tests ;npm run beforecommit
to perform tests, generate doc and bundle the JavaScript.
To avoid CORS when locally loading the example HTML file, run the web server. Please do not use it on a production environment. Unit tests are performed on both Firefox and Chrome ; ensure you have both installed before running tests, otherwise they might fail.
If you have any question or idea, feel free to DM or open an issue (or even a PR, who knows) ! I'll be glad to answer your request.
Credits
This component is based on the method described by Joe Sullivan, that renders and filters the track to keep its beats, then calculate intervals between those peaks and assumes that the BPM is based on the interval that is the most represented. The implementation is based on algorithms designed by José M. Pérez and adds the offset layer.