realtime-bpm-analyzer
realtime-bpm-analyzer copied to clipboard
Library using WebAudioAPI to analyse BPM from files, audionodes. It's also able to compute BPM from streams as well as realtime using a microphone. This tool might be useful for music producers and DJ...
RealTime BPM Analyzer
Documentation
Checkout gh-pages branch to edit the github-pages.
Introduction
This dependency free library allows you to compute the BPM (Beats Per minutes) in realtime of an audio
/ video
node or streams thanks to the WebAudioAPI.
Please, note that the main use case of this tool, is to compute the BPM while the video / audio is playing.
WebAudioAPI
The WebAudioAPI provides a powerful and versatile system for controlling audio on the Web, allowing developers to choose audio sources, add effects to audio, create audio visualizations, apply spatial effects (such as panning) and much more.
Motivations
Allegro Project purpose is to permits you to collect the BPM of Youtube musics listened by the user. Once the data collected the tool shall bind it at the begining of the title.
Let's imagine we are listening a song on Youtube. The "raw" title of it is: New Order - Blue Monday
, once Allegro
have collected the BPM it will bind it at the begining of the title, so we would have: [130BPM] New Order - Blue Monday
.
The project is under construction thought and this component realtime-bpm-analyzer is an essential piece of the project.
Installation
To install this module to your project, just launch the command below:
npm install realtime-bpm-analyzer
Development
npm install
npx husky install
npm test
Tests & Coverage
To launch the test suite, just launch the command below:
npm test
npm run test:report
Usage
-
An AudioNode to analyze. So something like this :
<audio src="./new_order-blue_monday.mp3" id="track"></audio>
-
Connect the AudioNode to the AudioContext and create an AudioContext.createScriptProcessor().
// Create new instance of AudioContext const audioContext = new AudioContext(); // Set the source with the HTML Audio Node const source = audioContext.createMediaElementSource(document.getElementById('track')); // Set the scriptProcessorNode to get PCM data in real time const scriptProcessorNode = audioContext.createScriptProcessor(4096, 1, 1); // Connect everythings together scriptProcessorNode.connect(audioContext.destination); source.connect(scriptProcessorNode); source.connect(audioContext.destination);
-
Now you have just to configure the tool and attach it to the audioprocess event like this :
import { RealTimeBPMAnalyzer } from 'realtime-bpm-analyzer'; const onAudioProcess = new RealTimeBPMAnalyzer({ scriptNode: { bufferSize: 4096 }, pushTime: 2000, pushCallback: (err, bpm) => { console.log('bpm', bpm); } }); // Attach realTime function to audioprocess event.inputBuffer (AudioBuffer) scriptProcessorNode.onaudioprocess = (e) => { onAudioProcess.analyze(e); };
Technical approch
This tool has been largely inspired by the Tornqvist project, which is actually optimized to compute the BPM of a song as fast as possible and not during the plying.
The algorithm use an AudioBuffer in input. We apply on it a lowpass filter to get bass frequencies. Then, we extract raw data (PCM, Pulse Code Modulation, each points is between 1 and -1) to detect peaks.
Description | |
---|---|
![]() |
PCM Data are dots with value between the max/min amplitude (1/-1). Each dots have its own index |
To detect peaks, we will test the whole AudioBuffer with a high thresold (setted to 0.9), on the amplitude axis. We need a minimum of 15 occurence to confirm a valid BPM. To find the occurencies that we need, we will decrease the thresold with a step of 0.05
.
When a peak is found, we will search for the next by jumping 10 000
indexes of PCM data, this means that we ignore 0.25
second of the song, in other words we simply ignore the descending phase of the peak.
Feel free to contact me by mail or join the chat if you have any questions.
Todo
- Migrate from ScriptProcessorNode to AudioWorklet
Credits
This library was been inspired from Tornqvist project which also based on Joe Sullivan's algorithm. Thank you to both of them !
Final
If this project helped you in any way or if you want to support it, you can always leave me a tip here:
BTC 36eHnxCRUDfWNFEx3YebRGw12WeutjkBBt
ETH 0x0F8b4F026624150e9F6267bFD93C372eb98e3010