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.
Usage
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:
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.
Methods
start
Starts the clock
stop
Stops the clock and resets the current step, beat and bar to 0
pause
Pauses the clock
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);
Metronome example
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();