Skip to content
πŸŽ› Automatic track mixing using the Web Audio API
Branch: master
Clone or download
Latest commit 15b3493 Apr 23, 2017
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src Sanity check - Disconnect buffers Apr 23, 2017
.babelrc Initial library Feb 23, 2017
.editorconfig Initial library Feb 23, 2017
.gitignore Initial library Feb 23, 2017
README.md Update README.md Apr 6, 2017
package.json 1.0.9 Apr 23, 2017

README.md

Logo

Web Audio Mixer

npm

πŸŽ› Automatic track mixing using the Web Audio API

For a demo, please visit wam.dj. Click "Try the Demo" or Sign up, connect with SoundCloud and set up a play queue of your own songs!

The library uses Joe Sullivan's idea and algorithm for detecting beats using the Web Audio API. It uses WAAClock (which is based on an article by Chris Wilson - A Tale of Two Clocks) to schedule events based on the times calculated from the beat detection. If we know the BPM and a point in time when a drum hits, we can move to any beat in a track, or schedule another track to start on a beat.

The above idea aligns the beats of two tracks, but to properly mix, they need to play at the same tempo. Using the playbackRate and detune methods, the library time stretches the new track to match the current track. Currently, this is not a cross-browser solution, so I plan on using a Javascript implementation like PhaseVocoderJS to polyfill this behaviour.

Install

npm i webaudiomixer --save

Usage

import WebAudioMixer from 'webaudiomixer';

const context = new AudioContext();
const mixer = new WebAudioMixer({
    context
});
// Connect the mixer to the output
mixer.connect(context.destination);

Creating a play queue

You can add tracks to the play queue with a URL to an audio source. The add method returns a unique ID which you can assign back to the track in your application. Any events or references to the track will use that ID.

Add a track to the play queue

const id = mixer.add(stream_url);

Start the queue

mixer.play();

Pause all tracks

mixer.pause();

Remove a track from the play queue

const removed = mixer.remove(id);

Seek to a time in the track (in seconds)

mixer.seek(id, time);

Disconnect the AudioNode

mixer.disconnect();

⚠️ TODO: Removing/replacing a track once it's started, loaded or scheduled.

Events

You can listen for events to update the UI of your application. The events are emitted in the tolerance zone (0.10s) of the event happening in the Web Audio clock. If you need greater precision, schedule things using the times from the analyzed payload, or access information in mixer.tracks directly.

Event Payload Description
analyzed { id, payload } Track has been analyzed by the beat matching module
loaded { id, track } Track has been loaded into an AudioBuffer
mixin { id, time } Track is being mixed in at time
mixout { id, time } Track has been mixed out at time
playing { id, time } Track will begin playing at time
paused { id, time } Track will be paused at time
trackEnd { id } Track is stopped and destroyed

⚠️ TODO: Helper method to find a track by ID, so that you can access the AudioBuffer, and other real-time information.

Options

Option Default Description
context new AudioContext() I recommend passing in an AudioContext from your app
maxBpmDiff 8 Maximum BPM difference between two tracks for the playbackRate to be changed
mixLength 20 Time in seconds a track should crossfade and mix for
playbackRateTween 60 Time in seconds a track should ramp back to it's original playbackRate
volume 1.0 Initial value of the gainNode

Final Year Project

This library was developed as a part of my Final Year Project for Web Development BSc at Staffordshire University. My report was titled Automatic track mixing using the Web Audio API and it researched the possibilities of using the Web Audio API to improving the experience of streaming music online.

You can’t perform that action at this time.