Working with Sound using p5.js

Authored by John Kuiphoff


As soon as we get things animating on the screen, it's only obvious to want to add sound to uhh, you know, make it better.

Before we can begin triggering sounds, we first need to find some sounds. One good place to find some free sounds: http://freesound.org/ - You will need to sign up for an account before you can download any sounds. They have a really good collection - it's worth signing up (and donating if you use them a lot)!

Or, feel free to download a few sounds to play with below:

Download Sounds (.zip)

Once you find a sound that you'd like to use, you'll want to save it as an ".mp3" file. If your sound isn't currently an mp3 file, you may be able to convert it using Audacity.

Place your ".mp3" sound files in your project folder (as you would an image or any other media file) - we'll be accessing the sounds in the next step.

Playing a Sound

Now let's type in the following code into "sketch.js" (adapted from http://p5js.org/learn/examples/Sound_Load_and_Play_Sound.php):

var sound;

function preload()
{
  // initialize sound
  sound = loadSound('pop.mp3');
}


function setup() 
{
  createCanvas(200, 200);
  
  // display instructions
  textAlign(CENTER);
  fill(100);
  noStroke();
  text("Click to play sound", width/2, height/2);
}

function draw()
{
  
}

function mousePressed() 
{
  // trigger sound
  sound.play();
  
  // change background color
  background(random(255), random(255), random(255));
  
}

Looping a Sound

When creating a sketch, you'll often find yourself wanting to loop a soundtrack. After all, adding a soundtrack to your sketch will instantly make your sketch so much cooler than it actually is. Especially Dubstep music - Dubstep makes everything super awesome.

The sketch below will preload our soundtrack to ensure that everything is loaded before the sketch begins. We will also add play and stop buttons to control playback. In addition, we will create a very simple music visualizer that maps the volume to the size of an ellipse.

Download Soundtrack (.zip)

var soundtrack;
var playbutton, stopbutton;
var analyzer;

function preload() 
{
  soundtrack = loadSound('soundtrack.mp3');
}

function setup() 
{
  createCanvas(400, 400);
  
  // loop sound
  soundtrack.loop();
  
  // stop sound to prevent it from playing automatically
  soundtrack.stop();
  
  // play button
  playbutton = createButton('Play');
  playbutton.position(25, 25);
  playbutton.mousePressed(playsound);
  
  // stop button
  stopbutton = createButton('Stop');
  stopbutton.position(75, 25);
  stopbutton.mousePressed(stopsound);
  
  // music visualizer
  analyzer = new p5.Amplitude();
  analyzer.setInput(soundtrack);
}

function draw()
{
  background(255);
  
  // draw an ellipse based on current volume level
  var vol = analyzer.getLevel();
  noStroke();
  fill(255, 0, 0);
  ellipse(width/2, height/2, map(vol, 0, 1, 0, width), map(vol, 0, 1, 0, height));
    
}

function playsound() 
{
  if(soundtrack.isPlaying() == false) 
  {
    soundtrack.play();
  } 
}

function stopsound() 
{
  if(soundtrack.isPlaying() == true) 
  {
    soundtrack.pause();
  } 
}

OK, now that you're slightly startled, let's talk through this in a little more detail.

The preload() function will run before the sketch starts. This is helpful if you need to load in large audio files or images. By preloading the sound file, we can be sure that it will be ready to go when we call on it.

function preload() 
{
  soundtrack = loadSound('soundtrack.mp3');
}

In the setup() function, we tell our soundtrack to loop. However, we immediately stop the sound so that it doesn't play automatically. Then, we create two buttons - one button to play the soundtrack; a second button to stop the sound track. The setup() also creates a listener that will read the current volume from the soundtrack.

In the draw() function, we draw an ellipse based on the current sound level. The number returned from analyzer.getLevel() ranges from 0 to 1. The map() function used inside of the ellipse() is a magical thing. It magically converts the volume level (a number from 0 to 1) to a number ranging from 0 to the width or height of the screen. You can use the map() anytime you need to magically increase or decrease a number.

The playsound() function is mapped directly to the play button's click event. If the sound track is not currently playing, we tell the soundtrack to play.

The stopsound() function is mapped directly to the stop button's click event. If the sound track is currently playing, we tell the soundtrack to pause.

Next steps

The sound library is capable of doing some very sophisticated things, such as: recording and saving sound, adding effects, etc. Please refer to the sound reference page on the p5.js website to learn more.