Skip to content

ArthurBeaulieu/BeatDetect.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BeatDetect.js

License

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.

Try me here!

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.