Polyrhythmic Sequencer library for Web Audio API.
The sequencer can have multiple layers where each layer has a different step count. This feature allows the user to create complex polyrhythms and euclidean rhythms using a simple api.
You can install beet
from npm.
npm install beet.js
Or grab the latest version from build folder and include it in your html.
<script src='beet.min.js'></script>
var context = new AudioContext();
// initialize beet
var beet = new Beet({
context: context,
tempo: 100
});
// create a euclidean pattern - 5 pulses distrubted in 7 steps
var pattern = beet.pattern(5,7);
// create a beet layer - pass it the pattern and a callback
var layer = beet.layer(pattern, callback);
function callback(time){
var osc = context.createOscillator();
osc.connect(context.destination);
osc.start(time);
osc.stop(time + 0.1);
}
// add the layer
beet.add(layer);
// start the sequencer
beet.start();
Beet constructor. Returns a new instance of beet.
opts
(required) - an object containing the initialisation options- context (required) - an instance of AudioContext
- tempo (optional) - speed in BPM - defaults to 120
Starts the sequencer after a given time in seconds.
time
- a number in seconds - defaults to 0
Stops the sequencer after a given time in seconds and resets the current step number.
time
(optional) - a number in seconds - defaults to 0
Pauses the sequencer after a given time in seconds but keeps the current step number.
time
(optional) - a number in seconds - defaults to 0
Adds a given beet.layer
to the list of layers to play. Can also be used with multiple layers. beet.add(layer1, layer2)
layer
(Required) - abeet.layer
object.
Removes a given beet.layer
from the list of layers to play.
layer
(Required) - abeet.layer
object.
The pattern method will return a pattern
object based on the provided values. If pulses
and steps
are passed in as numbers, an equally distributed pattern will be generated and returned. Alternatively, you can use a custom pattern string. For example '1000101010'.
Returns a pattern
object containing a bjorklund sequence with equally distributed number of pulses
over steps
.
pulses
(required) - number of pulses (active steps) in the sequencesteps
(optional) - number of steps in the sequence - value ofpulses
will be used steps is not specified.
var pattern = beet.pattern(3, 7);
// a pattern object containing a sequence as below
// '1010100'
var pattern2 = beet.pattern(4);
// a pattern object with a sequence as below
// '1111'
Returns a pattern
object containing a the custom pattern. This can be used to generated custom sequences when neccessary.
patternString
(required) - a binary sequence string with an arbitrary length using1
's for pulses and0
's for empty slots.
var pattern = beet.pattern('100010010');
var pattern2 = beet.pattern('10001111');
Updates the pattern object with the new values. You can also update the values directly. See example below.
pulses
(required) - number of pulses (active steps) in the sequence.steps
(optional) - number of steps in the sequence. value ofpulses
will be used steps is not specified.
var pattern = beet.pattern(2, 5);
pattern.update(5,8); // updates the pattern to '10100'
// you can also set the values separately
pattern.pulses = 4;
pattern.steps = 8;
Shifts the sequence by the offset and returns the pattern object.
offset
(required) - number of steps to shift the sequence by
var pattern = beet.pattern(1, 4); // returns '1000'
pattern.shift(1) // updates the sequence to '0100'
Creates a beet.layer
object and returns it.
pattern
(required) - abeet.pattern
object.onCallback
(required) - a function to call on pattern's pulses e.g. 1'soffCallback
(optional) - a function to call on pattern's empty slots e.g. 0's.
var pattern = beet.pattern(1, 4); // returns '1000'
var layer = beet.layer(pattern, on, off);
// on will be called on 1
// off will be called on 0's
The callbacks are functions that will be called from the scheduler.
The functions will be called with time
, step
and timeFromScheduled
parameters.
You can use the time
parameter for web audio methods. step
can be used to change audio behaviour according to the current step.
timeFromScheduled
is a value in seconds which corresponds to the time it will take for an audio event to occur from the time it was scheduled (time - context.currentTime
). It can be used to schedule JS events using setTimeout
.
function callback (time, step, timeFromScheduled) {
var osc = context.createOscillator();
osc.connect(context.destination);
if(step === 1){
osc.frequency.value = 880;
}
osc.start(time);
osc.stop(time + 0.2);
setTimeout(function(){
// trigger some js event such as animation - will be synced to the audio
}, timeFromScheduled * 1000);
}
You can play and pause individual layers using:
var pattern = beet.pattern(1, 4); // returns '1000'
var layer = beet.layer(pattern, on, off);
layer.play()
layer.pause()
layer.stop()
Beet comes with a series of useful utilities for web audio api. These might me moved to a separate module in the future as these are not specific to beet's functionality. But for now, features will be added gradually.
Applies an envelope to the audio param given a series of options.
audioparam
(required) - an AudioParam object to be automated.now
(required) - the time for the automation to start, e.g. the time parameter inbeet
callback.opts
(optional) - an JavaScript object that contains the envelope parameters.start
(optional) - the start value for the automation curve. the audio param will be set to this value at the beginning of the automation.peak
(optional) - the maximum value for the automation curve that the attack stage will end up in.attack
(optional) - the time in seconds for the attack stage.decay
(optional) - the time in seconds for the decay stage.sustain
(optional) - the value for that the decay stage will end up in.release
(optional) - the time in seconds for the release stage.
var osc = context.createOscillator();
var gain = context.createGain();
osc.connect(gain);
gain.connect(context.destination);
beet.utils.envelope(gain.gain, time, {
start: 0,
peake: 1.0,
attack: 0.1,
decay: 0.2,
sustain: 0.8,
release: 0.5
});
osc.start(time);
osc.stop(time + 2);
Loads an audio file for a given path and returns a decoded AudioBuffer object.
path
(required) - the path to your audio file.success
(required) - function to be called on load success. The passed function will be called with abuffer
parameters which is an AudioBuffer object.failure
(required) - function to be called on load or decode error.context
(optional) - an instance of AudioContext, if not provided, global variablecontext
will be used
beet.utils.load('path/to/file.wav', function(buffer){
// do something with the buffer
}, failureHandler, context);
Converts a give midi note to a frequency value in hz.
midi_note
(required) - the midi note number (0 to 127).
beet.utils.mtof(69); // will return 440 for A4
Converts a given note name to a frequency value in hz.
note_name
(required) - the note name followed by octave e.g. 'a4'
beet.utils.ntof('a4'); // will return 440 for A4
Converts a given midi note to a value representing the playbackRate
.
midi_note
(required) - the midi note number (0 to 127).
beet.utils.mtop(60); // will return 1 for C4 - meaning the sample will be played in the original speed
beet.utils.mtop(72); // will return 2 for C3
beet.utils.mtop(48); // will return 0.5 for C2