setup()
setup() runs once when the sketch starts. It is the only place you should create audio sources and UI elements, because creating them repeatedly in draw() would cause clicks and pops. Notice how the rain and thunder sources are disconnected from the master output and reconnected through filters—this routing lets us apply effects before the sound reaches your ears.
function setup() {
createCanvas(windowWidth, windowHeight);
noStroke();
noiseSeed(random(1000)); // Varied patterns each run
userStartAudio(); // Ensure audio can start after user gesture
// --- RAIN AUDIO: dull, muffled rain noise --- //
// White noise is a bright source; low-pass will dull it
rainNoise = new p5.Noise('white');
rainNoise.start();
rainNoise.amp(1); // Full level into the filter
rainFilter = new p5.LowPass();
rainFilter.freq(800); // Start around mid-lows
rainFilter.res(2); // Gentle resonance
// Route rain: noise -> rainFilter -> speakers
rainNoise.disconnect(); // Remove direct connection to master
rainNoise.connect(rainFilter);
rainFilter.amp(0.0); // Start silent; control in draw()
// --- THUNDER AUDIO: occasional low rumbles --- //
// Brown noise: more low-frequency energy, good for thunder
thunderNoise = new p5.Noise('brown');
thunderNoise.start();
thunderNoise.amp(1); // full level into its filter
thunderFilter = new p5.LowPass();
thunderFilter.freq(300); // Low cutoff for boomy sound
thunderFilter.res(3); // Some resonance for character
// Route thunder: noise -> thunderFilter -> speakers
thunderNoise.disconnect();
thunderNoise.connect(thunderFilter);
thunderFilter.amp(0); // Thunder is silent until triggered
// --- UI: volume & pitch sliders --- //
volumeLabel = createDiv('Volume');
volumeLabel.style('color', 'white');
volumeLabel.position(20, 5);
volumeSlider = createSlider(0, 100, 70); // 70% default
volumeSlider.position(20, 25);
volumeSlider.style('width', '150px');
pitchLabel = createDiv('Pitch (brightness)');
pitchLabel.style('color', 'white');
pitchLabel.position(20, 55);
pitchSlider = createSlider(0, 100, 40); // 40% default (rather dull)
pitchSlider.position(20, 75);
pitchSlider.style('width', '150px');
initRain();
}
Line-by-line explanation (12 lines)
🔧 Subcomponents:
rainNoise = new p5.Noise('white');
Creates a white noise source and routes it through a low-pass filter to create a dull, muffled rain sound
thunderNoise = new p5.Noise('brown');
Creates a brown noise source (richer in low frequencies) and routes it through a low-pass filter for boomy thunder
volumeSlider = createSlider(0, 100, 70);
Creates interactive HTML sliders for controlling volume and pitch, positioned in the top-left corner
createCanvas(windowWidth, windowHeight);- Creates a canvas that fills the entire browser window, so the rain spans your whole screen
noStroke();- Disables stroke outlines so only the raindrop lines themselves are drawn, not with extra borders
noiseSeed(random(1000));- Seeds the perlin noise generator with a random value so the wind drift pattern is different each time you run the sketch
userStartAudio();- Tells p5.sound that the user has clicked, so audio can actually play (browser security requirement)
rainNoise = new p5.Noise('white');- Creates a white noise source—bright and hissy, which we will dull down with a filter to sound like rain
rainNoise.disconnect();- Cuts off the direct connection to speakers so we can route the noise through our filter first
rainNoise.connect(rainFilter);- Plugs the white noise into the filter, so all the sound goes through it before reaching your ears
thunderNoise = new p5.Noise('brown');- Creates brown noise—naturally heavy in bass—which is perfect for thunder rumbles
thunderFilter.freq(300);- Sets the thunder filter's cutoff frequency to 300 Hz, keeping only the low, boomy part of the spectrum
volumeSlider = createSlider(0, 100, 70);- Creates a horizontal slider ranging from 0 to 100 with a default value of 70, for controlling overall volume
pitchSlider = createSlider(0, 100, 40);- Creates a horizontal slider ranging from 0 to 100 with a default value of 40, for controlling brightness/pitch
initRain();- Populates the rain array with 400 raindrop objects, each with a random position, depth, and speed