Reverb

리버브

The trailing reflections a sound leaves as it bounces off surfaces — reverb is how your ears sense a space's size and material.

Also known as: ReverberationConvolution reverb
···
html
<div class="wrap">
  <div class="room">
    <span class="ring ra"></span><span class="ring rb"></span><span class="ring rc"></span>
    <span class="src"></span>
  </div>
  <canvas id="ir"></canvas>
  <button class="play" id="play" type="button" aria-label="play sound"><span class="tri"></span></button>
</div>
css
.wrap{position:relative;width:94%;height:88%;display:flex;align-items:center;justify-content:center;gap:6%}
.room{position:relative;height:100%;aspect-ratio:1;flex-shrink:1;border-radius:14px;border:1px solid var(--line);background:var(--surface);display:grid;place-items:center;overflow:hidden}
.src{width:10px;height:10px;border-radius:50%;background:var(--accent);z-index:2}
.ring{position:absolute;border-radius:50%;border:1.5px solid var(--accent-2);opacity:0;width:14%;aspect-ratio:1;animation:expand 2.6s ease-out infinite}
.rb{animation-delay:.7s}.rc{animation-delay:1.4s}
@keyframes expand{0%{width:14%;opacity:.7}100%{width:150%;opacity:0}}
canvas{flex:1;height:60%}
.play{position:absolute;right:0;bottom:0;width:clamp(26px,13%,38px);aspect-ratio:1;border-radius:50%;border:1px solid var(--line);background:var(--surface);display:grid;place-items:center;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.12)}
.play .tri{width:0;height:0;border-style:solid;border-width:6px 0 6px 9px;border-color:transparent transparent transparent var(--fg);margin-left:2px}
.play:active{transform:scale(.92)}
js
const cv = document.getElementById('ir');
const g2d = cv.getContext('2d');
const cs = getComputedStyle(document.documentElement);
const ACCENT2 = cs.getPropertyValue('--accent-2').trim() || '#f25c8a';
function resize() {
  const dpr = Math.min(devicePixelRatio || 1, 2);
  const w = cv.clientWidth, h = cv.clientHeight;
  cv.width = w * dpr; cv.height = h * dpr;
  g2d.setTransform(dpr, 0, 0, dpr, 0, 0);
}
addEventListener('resize', resize);
resize();
const N = 40;
const bars = Array.from({ length: N }, (_, i) => Math.exp(-i / 10) * (0.4 + Math.random() * 0.6));
function draw() {
  const w = cv.clientWidth, h = cv.clientHeight;
  g2d.clearRect(0, 0, w, h);
  const bw = w / N;
  bars.forEach((v, i) => {
    g2d.fillStyle = ACCENT2;
    g2d.globalAlpha = 0.5 + v * 0.5;
    const bh = v * h;
    g2d.fillRect(i * bw, h - bh, bw * 0.7, bh);
  });
  g2d.globalAlpha = 1;
}
draw();
function makeImpulse(ctx, seconds, decay) {
  const len = Math.floor(ctx.sampleRate * seconds);
  const buf = ctx.createBuffer(2, len, ctx.sampleRate);
  for (let ch = 0; ch < 2; ch++) {
    const d = buf.getChannelData(ch);
    for (let i = 0; i < len; i++) d[i] = (Math.random() * 2 - 1) * Math.pow(1 - i / len, decay);
  }
  return buf;
}
document.getElementById('play').addEventListener('click', () => {
  const ctx = new (window.AudioContext || window.webkitAudioContext)();
  const now = ctx.currentTime;
  const convolver = ctx.createConvolver();
  convolver.buffer = makeImpulse(ctx, 1.1, 2.5);
  const wet = ctx.createGain();
  wet.gain.value = 0.09;
  const dry = ctx.createGain();
  dry.gain.value = 0.07;
  convolver.connect(wet).connect(ctx.destination);
  dry.connect(ctx.destination);
  const clickBuf = ctx.createBuffer(1, Math.floor(ctx.sampleRate * 0.01), ctx.sampleRate);
  const d = clickBuf.getChannelData(0);
  for (let i = 0; i < d.length; i++) d[i] = (Math.random() * 2 - 1) * (1 - i / d.length);
  const src1 = ctx.createBufferSource();
  src1.buffer = clickBuf;
  src1.connect(dry);
  const src2 = ctx.createBufferSource();
  src2.buffer = clickBuf;
  src2.connect(convolver);
  src1.start(now);
  src2.start(now);
  setTimeout(() => ctx.close(), 1300);
});

A sound bounces off walls, ceilings, and floors thousands of times, each reflection layering on top of the original — this pattern of reflections is called an "impulse response." Convolution reverb records a short click in a real space (a cathedral, a bathroom, a concert hall) and mathematically convolves that recorded decay with any other sound to make it seem to ring in that same space. The Web Audio API's ConvolverNode does this math, and without a real recording you can synthesize an impulse response from exponentially decaying white noise instead.

A longer reverb time (RT60, time to decay -60dB) reads as "cathedral," a shorter one as "small room." Adding reverb to a UI sound makes it feel premium and spacious, but overdo it and it smears into the next sound, hurting clarity — so notification sounds that need to communicate fast should use little to none, or keep RT60 under 0.3s. The key is mixing dry (original) and wet (reverb) signal so it never overwhelms.

Used to create a sense of space in music production, to switch between indoor/outdoor game ambience, and to give brand sounds a polished finish.

When to use

Reach for it when you want a sense of space or polish. Keep it minimal or skip it for notifications that need to communicate fast.