Designing a Simple Interactive Soundboard with Howler.js and React

What We’re Building

Today I’m going to walk you through a step-by-step process of how to create a simple interactive soundboard (loaded up with drum samples) by using React and Howler.js.

Why use Howler.js?

Audio has had a very tricky relationship with web browsers over the years, which has paved the way for several new audio manipulation libraries to make our lives as programmers much easier. Whether you are incorporating sound effects into a game, adding background music to your website, or designing an interactive soundboard (like we’re doing today), there are now many options available for controlling audio in your app.

Howler.js is a relatively simple library, which takes away the complexity of using the Web Audio API to play your sound effects, background music, or samples. Although you wouldn’t want to use it for music production based apps (Tone.js may be a better fit in those circumstances), Howler.js works best when you are controlling and manipulating multiple independent sources of audio, which is perfect for designing an interactive soundboard.

How Does it Work?

With Howler.js, you are able to control all sources of audio by creating a Howler object, which is called a Howl. You essentially import the Howl object into your React component and then tie it into one of your function calls, depending on what you would like it to accomplish. Howls allow you individual control over each of your audio sprites (we’ll get to that in a second), which you can then initiate through an event (button click, keyboard press, etc.) or when a page loads (ComponentDidMount). These audio sprites can be faded in, faded out, looped, or manipulated in several different ways. Why use audio sprites? Because they make our lives so much easier! If you already know how to create audio sprites, feel free to skip the next section.

Creating Your First Audio Sprites

If you’ve ever worked with a game engine before like Pixie.js or Phaser.io, or even hard coded a game with vanilla Javascript, you should be familiar with the concept of “sprites”. Image sprites like those used for game animation are very similar to the idea of audio sprites. Essentially, all of your audio is contained into a single file and then referenced at certain points in order to play your sound. The reason for this is to reduce the network load of multiple files and speed up the process of playing your audio. Unfortunately, Howler doesn’t provide any outlets for sprite creation, so we need to handle this creation with another form of software. A good choice is FFmpeg, which can be used to convert audio or video files into single sprites. You can install it at their website here.

After FFmpeg is installed, you’re all set to create your first audio sprite. Inside your code editor, make sure to enter install audiosprite (npm install audiosprite). You will only be able to use this after installing FFmpeg on your machine. You will also want to create public folder to store your audio files (mkdir public) and any additional assets that you may need. To further organize your audio files, I would recommend creating another file inside of your public folder. In this case, we will be creating samples for the soundboard, so I would call this folder “samples” (mkdir samples).

Creating Your Audio Samples

Since you’re reading this in the first place, I’m sure you are familiar with the different outlets available to create audio snippets or samples. Audacity is a free digital audio workspace (DAW) that you can use to edit and create your files. Mac users will also likely have GarageBand already installed on their machines, which it another DAW that can be easily used to produce your samples. These can be anything you would like, but in this case we will use drum samples for our soundboard. In this example, we will be using the following files:

These nine mp3s will give us the simple setup that we need for the soundboard.

Creating your “samples.json” File.

Once you have all of your audio files ready, it’s time to generate the audio sprites. Make sure that you’re in the /samples folder, and then type this into your command line:

Now let’s break down this input so that we can better understand what it all means:

First off, the “-e” stands for export, and it specifies which file formats should be exported. You will need to give it at least two options, “Webm” is always the preferred option. The reason for this is that it is the highest quality web audio at the lowest storage size. If for whatever reason a user’s browser won’t support Webm, the fallback will be mp3 in this case. This is why two formats options are needed.

Next, the “-f” is the actual format for the file, which will simply be “howler” in our case.

Lastly, “-o” stands for output, and will be the name of the json file that will be created after the command finishes executing. You will also want to list all of your mp3 file names so that they will be part of the new sprite object that will be created.

You should now have a “samples.json” file inside of your samples folder that looks like this:

You can see that this contains an object called “sprite” that holds all of your audio files, which are now in Webm format. Each audio key now holds an array, with the first position representing where the sound begins, and the second position representing the duration of the audio. Congrats, you just created your first audio sprite! We can now use this when we incorporate our Howl object into our React component.

Installing Howler.js and Creating your Howl Object

Now it’s time to create our first Howl object! We’re going to name our React component “SoundBoard”, import our Howl object, and include the new sound object inside of the constructor.

In our case, we’re going to assign “this.samples” to our Howl object. Inside of the object, we need to include the source, which will point to our samples folder with the Webm source listed first, and then the mp3 source listed as a backup. Inside of the sprite object, we will need to pull the exact reference arrays from our samples.json file and list them here.

Now comes the easy part! Playing one of your samples (in this case, “crash1”) is as simple as coding:

Awesome! We have all of our samples loaded up in our React component and a simple way to play the audio! Now, let’s start adding these to our interactive soundboard.

Designing our SoundBoard

We have all of our audio samples, so now let’s design our soundboard and let our user click or input a keyboard command in order to play them. Let’s start by adding some simple buttons with OnClick functions inside of them. For example, our “crash1” button will look like this:

Depending on your current CSS, the button on your app should now look similar to this:

When a user clicks on this button, they should be able to hear your “crash1” sample. Awesome! Repeat this step for the following samples and you should have a full clickable soundboard that looks like this:

Cool! So users can now click any of these buttons to hear your samples. Let’s add to this a bit and allow them to control your soundboard with various key presses as well. To begin, let’s create an event listener on our document to be called once our React component mounts (ComponentDidMount). It will look like this:

This event listener will be listening for any “keydown” events, and will then call a function called “handleKeyPress”. Let’s design that function now:

Wow, that’s a lot of code! Okay, let’s break this down so that you can better understand it. Essentially, this function is waiting on the “keydown” event to trigger on the document. Once it does, it checks inside of the various “if” statements to see which keyCode is pressed, and then plays a sample that we assign to it. The keyCodes correlate directly to your keyboard input (for example, a keyCode of 81 means that “Q” was pressed on your keyboard). To find the keyCodes that you would like to use, you can easily find them on this helpful site: https://keycode.info/. You can also write this function as a switch statement if you prefer. Lastly, don’t forget to bind your “handleKeyPress” function to “this” inside of your constructor. This will ensure that the “this” is always referencing this correct class:

Next, let’s add these key commands to our buttons so that our users know which key presses correspond to which samples. Here is an example of how we would write the “crash1” code for the button:

Now our user knows that by pressing the “D” key, they’ll hear the “crash1” sample. We’ll wrap the “D” text in a <small> tag so that we can style it differently than the main button text. Repeat this process for all of your samples and you’ll end up with your full soundboard, which will now look like this:

Perfect! Now users can either click to hear your samples or jam away on their keyboards. The next step is giving them some background music to jam out with!

Incorporating Background Music

Adding background music will be very similar to how we added the audio samples but this time we won’t need to reference the starting and duration positions within an array.

Inside of your public folder, you should make another folder called “music” to hold your background music (mkdir music). In this case, my background file is called “theme.mp3”. Make sure that you are inside of your /music folder and input the following into the command line:

Again, we will use Webm as our primary format, with mp3 as a fallback. Now that we have our background music file created, we can benefit from the modularity aspect of React and create a new component to mount when the page loads. In order to do so, you should create a component called “BackgroundMusic”, which will look like this:

Looks familiar, right? The only difference here is that, as mentioned earlier, we will not be referencing the individual samples within this object. Instead, we will be playing the full audio file. We set “loop: true” so that the music continues to play on repeat, and set “html5: true” so that our music file is handled appropriately for its relative size.

When the component mounts, we will set it to play():

And when it unmounts, we will set it to fade():

This is where the audio manipulation aspect plays into Howler. We’re only just scratching the surface here, but there are several different ways to manipulate your audio files with Howler. In this case, we are making the music fade out by bringing the sound down to “0” after a total of 1000 milliseconds.

Now, let’s add this background music to our SoundBoard component:

We’ll store some local state here, and add a boolean value “false” to a key called “playBackgroundMusic”. We’ll also add a “togglePlay” method to switch our music from on to off (set the state to true or false), or vice versa:

Again, since we’re referencing “this”, make sure to bind your “togglePlay” method in the constructor:

The last thing we’re going to do is make a conditional statement within our JSX code to check if the music is currently playing or not. If it is, we will load our <BackgroundMusic> component and our button will display “Stop the Jams”. It if isn’t playing, our button will display “Start the Jams”. It should look like this:

Now, we can click this button to either start the music or stop the music. I also went ahead and added a<small> “space” text so that users will know that they can start and stop the music by pressing the space key as well.

We’ll add this to our “handleKeyPress” method with the following code:

And that’s it! Now we should have a fully functioning soundboard featuring background music that you can jam to with your drum samples. Amazing! The final version should look like this:

Share with your friends and jam away!

Using Howler.js in the Future

Wow, we learned a lot in a short amount of time! Now you know how to create and load up audio sprites, reference them within a Howl object, and incorporate them into interactive buttons or key presses for the users of your app. Again, we’re only just dipping our toes into everything that Howler.js can accomplish with your audio files. As you saw with our background music file, there are several different ways to manipulate your audio as well.

Howler.js is a great library to play and edit single sources of audio. Feel free to use it in when creating sounds for your games or making interactive music apps like this one. I hope I was able to teach you the basics today and that you are able to continue your musical journey deeper into Hower.js in the future. Thank you for reading!