🎹 Web Audio API Speedrun

🎹 Web Audio API Speedrun #

Your ultra-quick guide to making sound in the browser.

πŸ›οΈ 1. The Core Concept: The Audio Context & Graph #

Everything in the Web Audio API happens inside an AudioContext. Think of it as your sound studio. Inside this studio, you connect different audio components, called AudioNodes, to create a processing pipeline, or an “audio graph.”

  • AudioContext: The central object that manages all audio operations.
  • AudioNode: A single audio processing unit. Examples include:
    • Source Nodes: Generate sound (e.g., from an oscillator, an audio file).
    • Effect Nodes: Modify sound (e.g., GainNode for volume, StereoPannerNode for panning).
    • Destination Node: The final output, usually your computer’s speakers (audioContext.destination).

The flow is always: Source β†’ (Zero or More Effects) β†’ Destination

// 1. Create the Audio Context
const audioContext = new AudioContext();

🎢 2. Example A: Generating a Tone with an Oscillator #

An OscillatorNode is a source that generates a constant, periodic waveform (a tone).

// 2. Create an Oscillator Node
const oscillator = audioContext.createOscillator();

// 3. Configure it
oscillator.type = 'sine'; // or 'square', 'sawtooth', 'triangle'
oscillator.frequency.setValueAtTime(440, audioContext.currentTime); // 440 Hz = 'A4'

// 4. Connect it to the destination (your speakers)
oscillator.connect(audioContext.destination);

// 5. Start the sound!
oscillator.start();

// You can also stop it after a delay
// oscillator.stop(audioContext.currentTime + 2); // Stop after 2 seconds

🎧 3. Example B: Playing an Audio File #

To play an existing audio file (like an MP3), you first need an <audio> element in your HTML.

HTML:

<audio src="path/to/your/track.mp3"></audio>
<button id="playButton">Play</button>

JavaScript:

const audioElement = document.querySelector('audio');
const playButton = document.querySelector('#playButton');

// 2. Create a MediaElementAudioSourceNode from the <audio> element
const track = audioContext.createMediaElementSource(audioElement);

// 3. Connect the source to the destination
track.connect(audioContext.destination);

// --- Play/Pause Control ---
playButton.addEventListener('click', () => {
  // The AudioContext must be resumed by a user gesture
  if (audioContext.state === 'suspended') {
    audioContext.resume();
  }

  // Use the <audio> element's native play/pause
  if (playButton.dataset.playing === 'false') {
    audioElement.play();
    playButton.dataset.playing = 'true';
  } else {
    audioElement.pause();
    playButton.dataset.playing = 'false';
  }
}, false);

// Reset button when track ends
audioElement.addEventListener('ended', () => {
  playButton.dataset.playing = 'false';
}, false);

πŸ”Š 4. Adding an Effect: The GainNode (Volume) #

You can insert effect nodes into your graph. A GainNode controls the volume.

// Create a Gain Node
const gainNode = audioContext.createGain();

// Connect: Source -> Gain -> Destination
track.connect(gainNode).connect(audioContext.destination);

// Now you can control the volume!
gainNode.gain.value = 0.5; // Set volume to 50%
gainNode.gain.setValueAtTime(0, audioContext.currentTime + 2); // Fade to mute over 2s