Sound Basics
Load and play audio files, synthesise tones, and react to microphone input with the p5.sound library.
Setting up p5.sound
p5.sound is an official add-on library. Include it alongside p5.js:
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/addons/p5.sound.min.js"></script>
In the p5.js web editor, p5.sound is already included by default.
Browser autoplay policy: Browsers require a user interaction (click, key press) before audio can start. Always begin audio in a click handler, not in
setup().
Loading and playing a sound file
let synth;
function preload() {
synth = loadSound('bass.mp3');
}
function setup() {
createCanvas(400, 200);
background(20);
fill(255);
textAlign(CENTER, CENTER);
text('Click to play', width / 2, height / 2);
}
function mouseClicked() {
if (synth.isPlaying()) {
synth.stop();
} else {
synth.play();
}
}
Sound file controls
synth.play(); // play from current position
synth.stop(); // stop and reset to start
synth.pause(); // pause at current position
synth.loop(); // loop indefinitely
synth.setLoop(true); // set loop mode
synth.isPlaying(); // returns true/false
synth.setVolume(0.5); // 0 (silent) to 1 (full)
synth.rate(1.5); // playback speed (1 = normal, 0.5 = half speed)
synth.pan(-1); // -1 = left, 0 = centre, 1 = right
synth.jump(2.5); // jump to 2.5 seconds
synth.duration(); // total length in seconds
synth.currentTime(); // current playback position
Sound amplitude (volume analysis)
p5.Amplitude measures the average volume of a sound:
let sound, amp;
function preload() {
sound = loadSound('music.mp3');
}
function setup() {
createCanvas(600, 400);
sound.loop();
amp = new p5.Amplitude();
amp.setInput(sound);
}
function draw() {
background(20);
let level = amp.getLevel(); // 0 to ~1 (peaks may exceed 1)
let size = map(level, 0, 0.5, 20, height * 0.9);
colorMode(HSB, 360, 100, 100);
fill(map(level, 0, 0.5, 200, 360), 80, 90);
noStroke();
circle(width / 2, height / 2, size);
}
FFT — frequency analysis
p5.FFT splits the audio into frequency bands, enabling spectrum visualisers:
let sound, fft;
function preload() {
sound = loadSound('music.mp3');
}
function setup() {
createCanvas(700, 400);
sound.loop();
fft = new p5.FFT(0.8, 256); // smoothing (0-1), number of bins
}
function draw() {
background(15);
let spectrum = fft.analyze(); // array of 256 amplitude values (0-255)
noStroke();
for (let i = 0; i < spectrum.length; i++) {
let x = map(i, 0, spectrum.length, 0, width);
let h = map(spectrum[i], 0, 255, 0, height);
colorMode(HSB, 360, 100, 100);
fill(map(i, 0, spectrum.length, 200, 360), 80, 90);
rect(x, height - h, width / spectrum.length, h);
}
}
Waveform display
let waveform = fft.waveform(); // returns 1024 values from -1 to 1
stroke(100, 200, 255);
strokeWeight(1.5);
noFill();
beginShape();
for (let i = 0; i < waveform.length; i++) {
let x = map(i, 0, waveform.length, 0, width);
let y = map(waveform[i], -1, 1, height, 0);
vertex(x, y);
}
endShape();
Microphone input
let mic, amp;
function setup() {
createCanvas(600, 200);
mic = new p5.AudioIn();
mic.start();
amp = new p5.Amplitude();
amp.setInput(mic);
}
function draw() {
background(20);
let level = amp.getLevel();
let w = map(level, 0, 0.5, 0, width);
fill(100, 200, 255);
noStroke();
rect(0, height / 2 - 20, w, 40, 0, 8, 8, 0);
}
Microphone access requires HTTPS (or localhost). The browser will show a permission prompt.
Synthesis with p5.Oscillator
Generate tones without audio files:
let osc;
function setup() {
createCanvas(400, 200);
osc = new p5.Oscillator('sine'); // 'sine', 'square', 'triangle', 'sawtooth'
osc.amp(0.5);
osc.freq(440); // Hz
}
function mouseClicked() {
if (osc.started) {
osc.stop();
} else {
osc.start();
}
}
function draw() {
background(20);
// Map mouse position to frequency
let freq = map(mouseX, 0, width, 100, 1000);
osc.freq(freq);
}
Theremin-style instrument
let osc, env;
function setup() {
createCanvas(600, 400);
osc = new p5.Oscillator('sine');
env = new p5.Envelope();
env.setADSR(0.05, 0.1, 0.7, 0.3);
env.setRange(0.8, 0);
osc.amp(env);
osc.start();
}
function draw() {
background(15);
let freq = map(mouseX, 0, width, 80, 880);
osc.freq(freq);
colorMode(HSB, 360, 100, 100);
fill(map(mouseX, 0, width, 180, 360), 80, mouseIsPressed ? 90 : 30);
noStroke();
circle(width / 2, height / 2, map(mouseY, 0, height, 200, 20));
}
function mousePressed() { env.play(); }
function mouseReleased() { env.stop(); }
Key takeaways
- Include p5.sound via CDN; audio must start from a user interaction
loadSound()inpreload()loads files;.play(),.stop(),.loop()control playbackp5.Amplitudemeasures volume level;p5.FFTprovides spectrum datap5.AudioIncaptures microphone inputp5.Oscillatorgenerates tones;p5.Envelopeshapes the amplitude over time- Map audio levels to visual properties (size, colour, position) for reactive visuals