Before we start, just a note: you might want to read this introductory post first if you are new to Web Audio API.
OK, now let's create some drum loops 🥁🔧🔨🔊! First we need to load a drum sound clip. By using
fetch() and promises to load and decode an audio file the code becomes easy to read. The audio data is stored in a global variable called
fetch() is that it is not supported in all browsers (I told you I'm lazy).
Let's do something we can hear: play a looping beat.
To play the audio buffer we loaded we need a
BufferSource which we connect to the output. Continuing the studio analogy from my other blog post:
- AudioContext is the sound studio where all the equipment lives,
buffer(that we already loaded) is an mp3 file,
BufferSourceis an mp3 player created like this:
source = context.createBufferSource();
- Load the mp3 file in the mp3 player:
source.buffer = buffer;
context.destinationis the speakers.
.connect()method is the wire,
- Connect the mp3 player to the speakers:
Good, all hooked up!
The sound clip is just 1.8 seconds long but looping is as easy as:
source.loop = true;. Now it will play in a gapless loop until you click Stop.
Hit the play button on the mp3 player with
Trivia: do you know what the beat is called and where it comes from? (It's not the whole sample, I just took a bar/measure.) Answer in the comments below :)
"But hey! Why are we recreating, connecting and configuring all of this stuff from scratch every time Start is clicked?!"
Good question! You see, once a
BufferSource is stopped you can't start it again. The MDN documentation about
If this method is called twice or more, an exception is raised.
Recreating everything over and over again is totally OK, it's the intended way of working. Those operations are cheap, don't be afraid, later we are going to trigger a whole slew of
BufferSources to play... 😈 But first:
The Phaser Effect
Back in 1996, I was a big fan of Chemical Brothers. I must have listened to their album "Exit Planet Dust" a thousand times. On the track "Song To The Siren", at 2.01, there is this phaser effect on the drum loop that I thought sounded very cool.
We can easily create the same sort of effect with Web Audio API by starting two loops of the same beat but setting the playback rate on one slightly faster than the other. Over time they will drift away from each other, going from phaser to echo to chaos to headache. 🙉
To get the two loops to start at the exact same time I'm reading the
currentTime property on the
AudioContext and using it as a parameter in the two calls to
If you listen for a while you will hear the two loops becoming more and more out of synch. I think the Chemical Brothers adjusted the playback rate continuously so that the two loops drifted back together again.
The Aphex Twin Effect
Aphex Twin is an artist that experiments a lot with sounds. Sometimes to a point where the result is more abstract sound art than a song. To me, his signature effect is triggering drums tightly and aggressively creating a metallic robotic stutter effect.
We are going to use the same drum beat as we did before. It is sliced in short peaces and scheduled to be played with a for loop in the code. You can control the slice size, delay, overlap and slice duration with the sliders.
To the AudioBufferSourceNode.start() method you can specify three parameters (all three are optional):
- When to start
- Offset - where in the audio buffer to start
- Duration - for how long we should play the sound
With these three parameters we can get the slices to be played with a slight overlap to create a stuttering effect.
Note that you can click the Result button to hide the result tab and automatically expand the JS tab. It's easier to read the code that way. =)
That's it for now, thank you for reading. Go ahead and f0rk my Pens and start experimenting. Share the result in the comments below.
My inspiration for doing some more Web Audio API Pens and writing this post came from:
- Sounds fun by Jake Archibald
Other blog posts I have written about Web Audio API:
- Fun with Web Audio API - already mentioned in the begining.
- More Fun with Web Audio API - creating reverb with ConvolverNode and more.
I also have a CodePen Collection with all my Web Audio Pens.