This is a webaudio event scheduler inspired by the article: https://html5rocks.com/en/tutorials/audio/scheduling/
Supports different time divisions: 4/4 or 3/4 for example.
Install Beatstepper:
npm install @errozero/beatstepper
Create an instance and pass in a web audio context, a callback function to trigger audio and an optional animation callback function:
import { Beatstepper, IBeatstepperCallbackData } from "@errozero/beatstepper";
const ctx = new AudioContext();
//Schedule your audio events for the step here
const audioCallback = (data: IBeatstepperCallbackData) => {
console.log("Audio Step!", data);
};
//Animation callback is optional, will run at the same time as the scheduled audio events start time for the step
const animationCallback = (data: IBeatstepperCallbackData) => {
console.log("Animation Step!", data);
};
const beatstepper = new Beatstepper(ctx, audioCallback, animationCallback);Now that is setup, call the start method to begin scheduling:
beatstepper.start();This will run at the default tempo of 130bpm, with 4/4 time division.
Your callback function will run on every step and receive an object with the following structure:
{
step: number, //The current step, starting at 0, default max is 15
beat: number, //The current beat, starts at 0, default max is 3
bar: number, //Current bar, starts at 0, default max is 3
startTime: number, //The webaudio clock time that events for this step should start
stepLength: number //Calculated length of one step, useful for sub-step timing
}Your callback function could be used to trigger notes or samples from a pattern array etc.
start
Starts the clock
beatstepper.start();
stop
Stops the clock and resets the current step, beat and bar to 0
beatstepper.stop();
pause
Pauses the clock
beatstepper.pause();
setTempo
Sets the tempo in bpm
Param: tempo:number
beatstepper.setTempo(160);
setStepsPerBeat
Sets the number of steps that make up a beat, default is 4.
This works together with beatsPerBar to set the timing of the clock.
It represents the first 4 in 4/4.
Param: steps:number
beatstepper.setStepsPerBeat(4);
setBeatsPerBar
Sets the number of beats that make up a bar.
This works together with stepPerBeat to set the timing of the clock.
It represents the second 4 in 4/4.
Param: beats:number
beatstepper.setBeatsPerBar(4);import { Beatstepper, IBeatstepperCallbackData } from "@errozero/beatstepper";
const context = new AudioContext();
const stepsPerBeat = 4;
const tempo = 90;
const callback = (data: IBeatstepperCallbackData) => {
const freq = data.step % stepsPerBeat == 0 ? 880 : 440;
const oscillator = context.createOscillator();
oscillator.type = "square";
oscillator.frequency.setValueAtTime(freq, context.currentTime); // value in hertz
oscillator.connect(context.destination);
oscillator.start(data.startTime);
oscillator.stop(data.startTime + data.stepLength / 2);
};
const animCallback = (data: IBeatstepperCallbackData) => {
//Update any visual position markers etc in here and it will be synced to the audio
};
const beatstepper = new Beatstepper(context, callback, animCallback);
beatstepper.setTempo(tempo);
beatstepper.setStepsPerBeat(stepsPerBeat);
beatstepper.start();