Skip to content
/ wam Public

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

Notifications You must be signed in to change notification settings

danbovey/wam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

32 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

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 #, 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.

About

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

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published