setup()
setup() runs once when the sketch starts. It prepares all 16 oscillators with their frequencies, assigns each pad a color, and initializes the state tracking array. The chromatic scale formula (baseFreq × 2^(noteIndex/12)) is the mathematical foundation of Western music tuning.
function setup() {
createCanvas(windowWidth, windowHeight);
// Tip: Use windowWidth/windowHeight for responsive canvas
// Enable audio playback. This is crucial for p5.sound.
// userStartAudio() must be called in response to a user gesture
// (like a mouse click or key press) to bypass browser autoplay policies.
userStartAudio();
// Calculate pad size based on window dimensions and desired spacing
padSizeX = (width - (cols + 1) * padSpacing) / cols;
padSizeY = (height - (rows + 1) * padSpacing) / rows;
// Generate musical frequencies (e.g., a chromatic scale over two octaves)
// Starting from C4 (261.63 Hz)
const baseFrequency = 261.63; // C4
for (let i = 0; i < rows * cols; i++) {
// Each pad corresponds to a note in a chromatic scale
// frequency = baseFreq * 2^(noteIndex / 12)
const freq = baseFrequency * pow(2, i / 12);
frequencies.push(freq);
// Create a sine oscillator for each frequency
let osc = new p5.Oscillator('sine'); // 'sine', 'triangle', 'sawtooth', 'square'
osc.freq(freq);
osc.amp(0); // Start with 0 amplitude (silent)
osc.start(); // Start the oscillator, but it won't be audible yet
oscillators.push(osc);
}
// Generate colorful pads using HSB color mode
colorMode(HSB, 360, 100, 100);
for (let i = 0; i < rows * cols; i++) {
// Vary hue for different colors
padColors.push(color(i * (360 / (rows * cols)), 80, 90));
}
colorMode(RGB, 255); // Switch back to RGB for background
// Initialize activePads 2D array to all false
for (let i = 0; i < rows; i++) {
activePads[i] = [];
for (let j = 0; j < cols; j++) {
activePads[i][j] = false;
}
}
}
Line-by-line explanation (12 lines)
🔧 Subcomponents:
for (let i = 0; i < rows * cols; i++) {
const freq = baseFrequency * pow(2, i / 12);
frequencies.push(freq);
let osc = new p5.Oscillator('sine');
osc.freq(freq);
osc.amp(0);
osc.start();
oscillators.push(osc);
}
Creates 16 oscillators tuned to consecutive chromatic notes; each frequency is calculated using the 12-tone equal temperament formula
for (let i = 0; i < rows * cols; i++) {
padColors.push(color(i * (360 / (rows * cols)), 80, 90));
}
Generates 16 unique colors distributed evenly across the hue spectrum using HSB mode
for (let i = 0; i < rows; i++) {
activePads[i] = [];
for (let j = 0; j < cols; j++) {
activePads[i][j] = false;
}
}
Creates a 4×4 2D array tracking which pads are currently playing (true) or silent (false)
createCanvas(windowWidth, windowHeight);- Creates a canvas that fills the entire browser window, making the grid responsive to screen size
userStartAudio();- Enables audio playback—this must be called in response to a user gesture (like the first click) to comply with browser autoplay policies
padSizeX = (width - (cols + 1) * padSpacing) / cols;- Calculates the width of each pad by subtracting spacing from total width and dividing by the number of columns
padSizeY = (height - (rows + 1) * padSpacing) / rows;- Calculates the height of each pad by subtracting spacing from total height and dividing by the number of rows
const freq = baseFrequency * pow(2, i / 12);- Calculates the frequency for each pad using the chromatic scale formula: each semitone multiplies the previous frequency by 2^(1/12) ≈ 1.0595
let osc = new p5.Oscillator('sine');- Creates a new oscillator that will generate a sine wave (smooth, pure tone)
osc.freq(freq);- Sets this oscillator's frequency to the calculated chromatic note frequency
osc.amp(0);- Sets the oscillator's initial amplitude to 0 (completely silent)—it won't make sound until amplitude increases
osc.start();- Starts the oscillator running in the background, but it remains silent because amplitude is 0
colorMode(HSB, 360, 100, 100);- Switches to HSB color mode to easily generate a rainbow of colors by varying hue
padColors.push(color(i * (360 / (rows * cols)), 80, 90));- Creates a color by distributing hues evenly across the 360-degree spectrum; each pad gets a different hue
colorMode(RGB, 255);- Switches back to RGB mode for the rest of the sketch