p5: Sounds

Sounds in p5 work like images: they are assets, not code. You need to reference them as external files, and preload them before you play them.

To make this example work download an mp3 file from the internet and upload it in an “audio” folder inside your project.

Then change the path and filename accordingly:
mySound = loadSound('audio/mySound.mp3');

You can go to freesound or download mp3 from youtube.

var mySound;

function preload() {
mySound = loadSound('audio/mySound.mp3');
}

function setup() {
mySound.setVolume(0.1);
mySound.play();
//also try looping
//mySound.loop();
}

function draw() {
if(mySound.isPlaying())
print("PLAYING");
}

//sound mode
function mouseClicked() {
mySound.playMode('sustain');
mySound.play();
}

function keyPressed() {
mySound.playMode('restart');
mySound.play();
}

How to add assets

Assets remain associated to your account and to the sketch that uses them.
However they can be shared between sketches by referencing the URL.
Click on my account > my assets > view an asset.
That address is publicly accessible and can be used as loading path, eg:
https://assets.editor.p5js.org/5b89771e9626750015ce585b/ca431e58-cf81-479f-9e18-0f909018e015.mp3

Dynamic Filters

P5 is not great at realtime sound processing but the sound library has some nice features.

This example requires the caribou.mp3 audio file to work.

//the song
var tune;
//the filter
var audioFilter;

//run before start
function preload() {
tune = loadSound('audio/caribou.mp3');

//in order to hear only the filter output I have to
//disconnect the unfiltered one
tune.disconnect();
audioFilter = new p5.LowPass();
tune.connect(audioFilter);

/*
https://p5js.org/reference/#/p5.Filter
p5.LowPass, p5.HighPass, p5.BandPass
*/
}

function setup() {
createCanvas(windowWidth, windowHeight);
tune.setVolume(0.5);
tune.loop();
}

function draw() {
colorMode(HSB);

//set filter frequency dynamically
var freq = map(mouseX, 0, width, 20, 10000);
audioFilter.freq(freq);

//set reproduction speed dynamically
var speed = map(mouseY, 0.1, height, 0, 2);
speed = constrain(speed, 0.01, 4);
tune.rate(speed);
}

function mousePressed() {
//set volume to 0, fade in 3 seconds
tune.setVolume(0, 3);
}

p.s. note the full window canvas createCanvas(windowWidth, windowHeight);

Keyboard template

This example shows sound event and visual timed events triggered by keystroke.
You need to download the sound files referenced in the program HERE

And then upload them to your assets in the editor:


var bgColor;
var sustain;

function preload() {
c2 = loadSound("audio/c2.wav");
e2 = loadSound("audio/e2.wav");
g1 = loadSound("audio/g1.wav");

myLoop = loadSound("audio/autumn_mushrooms.mp3");

pad1 = loadSound("audio/enoPad.mp3")
pad2 = loadSound("audio/enoPad2.mp3")

pad1.playMode('sustain');
pad2.playMode('restart');

}

function setup() {
createCanvas(windowWidth, windowHeight);
bgColor = color(255,255,255);
myLoop.loop();
}

function draw() {
background(bgColor);

//draw the square
if(sustain>0)
{
fill("#e2ce8f");
rectMode(CENTER);
noStroke();
rect(width/2, height/2, sustain*30,sustain*30);
sustain--;
}

var vol = map(mouseY, 0, height, 1, 0);
myLoop.setVolume(vol);

fill(0);
text("keys A S D F G H", 12,16);

}

function keyPressed() {

if (key == "a") {
c2.play();
bgColor = color("#965374");
sustain = 20;
}
else if (key == "s") {
e2.play();
bgColor = color("#ec4e81");
sustain = 20;
}
else if (key == "d") {
g1.play();
bgColor = color("#f18a81");
sustain = 20;
}
else if (key == "f") {
pad1.play();
}
else if (key == "g") {
pad2.play();
}

}

Checking a sound state
You can always check the reproduction state of a sound to perform tighter synchronizations.


var sound1;

var sound2;

//run before start
function preload() {
sound1 = loadSound('https://assets.editor.p5js.org/5b89771e9626750015ce585b/ca431e58-cf81-479f-9e18-0f909018e015.mp3');
sound2 = loadSound('https://assets.editor.p5js.org/5b89771e9626750015ce585b/febe6e32-6270-4405-a059-7ac5ca585537.mp3');
}

function setup() {
createCanvas(600, 600);
noStroke();
}

//run continuously
function draw() {
background(0);
colorMode(HSB);


if (sound2.isPlaying()) {
noStroke();
fill("#ec4e81");
ellipse(width / 2, height / 2, 300, 300);
}

//create a variable that represents the position of the playhead
var s = map(sound1.currentTime(), 0, sound1.duration(), 0, 600);

stroke("#965374");
strokeWeight(10);
line(s, 0, s, height);

}

function keyPressed() {
if (key == "a") {
sound1.play();
} else if (key == "s") {
sound2.play();
}
}

Spectrum analysis

Real time spectrum analysis via Fast Fourier Transform.
You can analyze the sounds that are currently playing and draw something based on the frequencies like you did with the sound responsive face.


//global variables

//the song
var sound1;
var sound2;
var fft;

//run before start
function preload() {
sound1 = loadSound('https://assets.editor.p5js.org/5b89771e9626750015ce585b/ca431e58-cf81-479f-9e18-0f909018e015.mp3');
sound2 = loadSound('https://assets.editor.p5js.org/5b89771e9626750015ce585b/febe6e32-6270-4405-a059-7ac5ca585537.mp3');

//prepare the fft analysis (smoothing, sample)
//smoothing: 0-1
//sample: Must be a power of two between 16 and 1024
fft = new p5.FFT(0.8, 16);
}

//run once
function setup() {
createCanvas(800, 600);
noStroke();
}

//run continuously
function draw() {
background(0);
colorMode(HSB);

//take the current sound and analyze it
var spectrum = fft.analyze();

//extract one frequency (0 to 200) and remap it to a variable
var diameter = map(spectrum[4], 0, 255, 0, 300);

fill(255);
ellipse(width/2, height/2, diameter, diameter/2);
}

function keyPressed() {
if (key == "a") {
sound1.play();
} else if (key == "s") {
sound2.play();
}
}

A more complex example.


//global variable

//the song
var tune;
var fft;

//run before start
function preload() {
tune = loadSound('https://assets.editor.p5js.org/5b89771e9626750015ce585b/75124972-17a7-470f-a6f0-21b3f49cb5d9.mp3');

//prepare the fft analysis (smoothing, sample)
//smoothing: 0-1
//sample: Must be a power of two between 16 and 1024
fft = new p5.FFT(0.8, 16);
}

//run once
function setup() {
createCanvas(800, 600);
noStroke();

tune.setVolume(0.5);
tune.loop();
}

//run continuously
function draw() {
colorMode(HSB);

//fft transform
var spectrum = fft.analyze();

var bgHue = map(spectrum[1], 0, 255, 150, 200);

background(bgHue, 255, 100)

var diameter = map(spectrum[4], 0, 255, 2, 300);

fill(bgHue, 255, 40);
ellipse(200, 300, diameter,diameter);

var diameter2 = map(spectrum[13], 0, 255, 2, 300);
var bright = map(spectrum[13], 0, 255, 2, 255);

fill(255, 255, bright);
ellipse(400, 300, diameter2,diameter2);

//find an interesting threshold
if(spectrum[10] > 101)
{
colorMode(RGB);
fill(255, 255, 255);
ellipse(600, 300, 100, 100);
}
}