realtime-bpm-analyzer

This dependency free library can analyze the BPM (Tempo) of an audio/video node or any stream in realtime on your browser

Usage no npm install needed!

<script type="module">
  import realtimeBpmAnalyzer from 'https://cdn.skypack.dev/realtime-bpm-analyzer';
</script>

README

RealTime BPM Analyzer

XO code style npm npm CI Actions Status Join the chat at https://gitter.im/realtime-bpm-analyzer/Lobby

Documentation

See the documentation

See the API documentation

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.

A schema worst better than a long speech so, 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

Usage

  1. An AudioNode to analyze. So something like this :

    <audio src="./new_order-blue_monday.mp3" id="track"></audio>
    
  2. 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);
    
  3. 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 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 VueJS 3 to NextJS for better SEO
  • 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