웹 오디오 API로 실시간 오디오 비주얼라이저를 구축한 방법

작성자

카테고리:

← 피드로
DEV Community · Pulak Nayak · 2026-06-29 개발(SW)
Cover image for How I Built a Real-Time Audio Visualizer with the Web Audio API

Pulak Nayak

What is a browser-based audio visualizer?

A browser-based audio visualizer is a real-time graphical display that converts live audio signals into visual patterns — waveforms, frequency spectrums, or spectrograms — using the Web Audio API and HTML5 Canvas, entirely on the client side with zero server processing.

I built Octaveview, a free, professional-grade online tone generator that includes four visualization modes: Waveform (Oscilloscope), Spectrum Analyzer, Dual View, and Heatmap Spectrogram. In this article, I’ll walk through the core architecture and techniques I used.

The Web Audio API Architecture

The Web Audio API uses a node graph model. You connect audio nodes together in a chain, from a source to a destination (your speakers). Here’s the simplified signal flow I used:

OscillatorNode → GainNode → StereoPannerNode → AnalyserNode → AudioDestination

Enter fullscreen mode Exit fullscreen mode

Step 1: Create the Audio Context and Oscillator

The AudioContext is the entry point for all Web Audio operations. The OscillatorNode generates periodic waveforms (sine, square, sawtooth, triangle) at a specified frequency.

const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioCtx.createOscillator();

oscillator.type = 'sine'; // Options: 'sine', 'square', 'sawtooth', 'triangle'
oscillator.frequency.setValueAtTime(440, audioCtx.currentTime); // A4 = 440 Hz

Enter fullscreen mode Exit fullscreen mode

Step 2: Add Gain (Volume) and Panning Controls

const gainNode = audioCtx.createGain();
gainNode.gain.setValueAtTime(0.5, audioCtx.currentTime); // 50% volume

const pannerNode = audioCtx.createStereoPanner();
pannerNode.pan.setValueAtTime(0, audioCtx.currentTime); // Center

Enter fullscreen mode Exit fullscreen mode

Step 3: Connect the AnalyserNode for Visualization

The AnalyserNode is the key to real-time visualization. It performs a Fast Fourier Transform (FFT) on the audio signal, giving you both time-domain (waveform) and frequency-domain (spectrum) data.

const analyser = audioCtx.createAnalyser();
analyser.fftSize = 2048; // Higher = more frequency resolution

// Connect the signal chain
oscillator.connect(gainNode);
gainNode.connect(pannerNode);
pannerNode.connect(analyser);
analyser.connect(audioCtx.destination);

Enter fullscreen mode Exit fullscreen mode

Step 4: Render the Waveform on Canvas

const canvas = document.getElementById('viz-canvas');
const ctx = canvas.getContext('2d');
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);

function drawWaveform() {
  requestAnimationFrame(drawWaveform);
  analyser.getByteTimeDomainData(dataArray);

  ctx.fillStyle = '#0a0b14';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  ctx.lineWidth = 2;
  ctx.strokeStyle = '#00e5ff'; // Cyan accent
  ctx.beginPath();

  const sliceWidth = canvas.width / bufferLength;
  let x = 0;

  for (let i = 0; i < bufferLength; i++) {
    const v = dataArray[i] / 128.0;
    const y = (v * canvas.height) / 2;

    if (i === 0) ctx.moveTo(x, y);
    else ctx.lineTo(x, y);

    x += sliceWidth;
  }

  ctx.lineTo(canvas.width, canvas.height / 2);
  ctx.stroke();
}

drawWaveform();

Enter fullscreen mode Exit fullscreen mode

Step 5: Render the Spectrum Analyzer

For the frequency spectrum, use getByteFrequencyData() instead:

function drawSpectrum() {
  requestAnimationFrame(drawSpectrum);
  analyser.getByteFrequencyData(dataArray);

  ctx.fillStyle = '#0a0b14';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  const barWidth = (canvas.width / bufferLength) * 2.5;
  let x = 0;

  for (let i = 0; i < bufferLength; i++) {
    const barHeight = dataArray[i];

    // Gradient from cyan to purple based on amplitude
    const hue = 180 + (barHeight / 255) * 100;
    ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
    ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);

    x += barWidth + 1;
  }
}

Enter fullscreen mode Exit fullscreen mode

Adding Colored Noise Generators

Beyond periodic waveforms, I added white, pink, and brown noise using AudioBuffer with custom-generated random samples:

function createWhiteNoise(audioCtx) {
  const bufferSize = audioCtx.sampleRate * 2;
  const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
  const data = buffer.getChannelData(0);

  for (let i = 0; i < bufferSize; i++) {
    data[i] = Math.random() * 2 - 1; // Random values between -1 and 1
  }

  const source = audioCtx.createBufferSource();
  source.buffer = buffer;
  source.loop = true;
  return source;
}

Enter fullscreen mode Exit fullscreen mode

  • White noise has equal energy per frequency (flat spectrum).
  • Pink noise has equal energy per octave — it sounds more natural and is used for speaker calibration.
  • Brown noise rolls off at 6 dB/octave, producing a deep rumble ideal for sleep and relaxation.

ADSR Envelope for Natural Sound Shaping

To prevent harsh clicks and create musically natural sounds, I implemented an ADSR (Attack, Decay, Sustain, Release) volume envelope:

function applyADSR(gainNode, audioCtx, { attack, decay, sustain, release }) {
  const now = audioCtx.currentTime;
  gainNode.gain.cancelScheduledValues(now);
  gainNode.gain.setValueAtTime(0, now);
  gainNode.gain.linearRampToValueAtTime(1, now + attack);         // Attack
  gainNode.gain.linearRampToValueAtTime(sustain, now + attack + decay); // Decay → Sustain
}

Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  1. The Web Audio API is incredibly powerful for real-time audio synthesis and analysis without any plugins or server dependencies.
  2. The AnalyserNode with FFT gives you both time-domain and frequency-domain data for rich visualizations.
  3. Custom AudioBuffer nodes let you generate any sound algorithmically — noise, custom waveforms, or even sampled instruments.
  4. Client-side audio generation means zero latency, full offline support, and complete user privacy.

Try It Live

You can try all of these features — waveform visualization, spectrum analyzer, ADSR envelopes, noise generators, and WAV export — for free at Octaveview.

For binaural beats with independent left/right ear frequency control, check out the Binaural Beats Studio.

Built with vanilla JavaScript, the Web Audio API, HTML5 Canvas, and Astro. No frameworks, no dependencies, no tracking.

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다