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 buffer (yes I'm lazy). Have a look at the JavaScript code in the embedded Pen below. The downside of using fetch() is that it is not supported in all browsers (I told you I'm lazy).

Drum Loop

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,
  • The BufferSource is an mp3 player created like this: source = context.createBufferSource();
  • Load the mp3 file in the mp3 player: source.buffer = buffer;
  • context.destination is the speakers.
  • The .connect() method is the wire,
  • Connect the mp3 player to the speakers: source.connect(context.destination);

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 source.start().

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 stop() says:

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.

Exit Planet Dust

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 start().

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.

Aphex Twin

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. =)

If you look in the JavaScript console you will see how many AudioBufferSourceNode's were used to create the particular sound effect you created.

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:

Other blog posts I have written about Web Audio API:

I also have a CodePen Collection with all my Web Audio Pens.


3,533 0 56