Audio ducking

오디오 더킹

Automatically lowering background audio volume when something important needs to cut through, then restoring it.

Also known as: Sidechain duckingAuto-gain reduction
···
html
<div class="wrap">
  <div class="meters">
    <div class="row"><span class="lbl">배경음</span><div class="meter"><i id="bgbar"></i></div></div>
    <div class="row"><span class="lbl">안내음</span><div class="meter"><i id="fgbar"></i></div></div>
  </div>
  <button class="play" id="play" type="button" aria-label="play sound"><span class="tri"></span></button>
</div>
css
.wrap{position:relative;width:94%;height:80%;display:flex;align-items:center;gap:6%}
.meters{flex:1;display:flex;flex-direction:column;justify-content:center;gap:16%}
.row{display:flex;align-items:center;gap:10px}
.lbl{width:34%;font:600 11px/1 monospace;color:var(--muted);text-align:right}
.meter{flex:1;height:22px;border-radius:11px;background:var(--line);overflow:hidden}
.meter i{display:block;height:100%;border-radius:11px;background:var(--accent);width:30%}
#fgbar{background:var(--accent-2);width:0}
.play{width:clamp(28px,15%,40px);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);flex-shrink:0}
@media (min-width:460px){
  .lbl{font-size:15px}
  .meter{height:34px;border-radius:17px}
  .meter i{border-radius:17px}
  .play{width:56px;height:56px}
  .play .tri{border-width:9px 0 9px 13px;margin-left:3px}
}
.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 bg = document.getElementById('bgbar');
const fg = document.getElementById('fgbar');
const CYCLE = 3000;
function idle(t) {
  const p = (t % CYCLE) / CYCLE;
  let bgLevel = 32 + Math.sin(t * 0.004) * 6;
  let fgLevel = 0;
  if (p > 0.4 && p < 0.6) {
    const dip = 1 - Math.abs(p - 0.5) / 0.1;
    bgLevel *= 1 - dip * 0.55;
    fgLevel = dip * 60;
  }
  bg.style.width = bgLevel + '%';
  fg.style.width = fgLevel + '%';
  requestAnimationFrame(idle);
}
requestAnimationFrame(idle);
document.getElementById('play').addEventListener('click', () => {
  const ctx = new (window.AudioContext || window.webkitAudioContext)();
  const now = ctx.currentTime;
  const bgGain = ctx.createGain();
  bgGain.connect(ctx.destination);
  bgGain.gain.setValueAtTime(0.05, now);
  bgGain.gain.linearRampToValueAtTime(0.018, now + 0.5);
  bgGain.gain.linearRampToValueAtTime(0.05, now + 0.9);
  bgGain.gain.linearRampToValueAtTime(0.0001, now + 1.2);
  const bgOsc = ctx.createOscillator();
  bgOsc.type = 'sine';
  bgOsc.frequency.value = 220;
  bgOsc.connect(bgGain);
  bgOsc.start(now);
  bgOsc.stop(now + 1.2);
  const fgGain = ctx.createGain();
  fgGain.connect(ctx.destination);
  fgGain.gain.setValueAtTime(0, now + 0.45);
  fgGain.gain.linearRampToValueAtTime(0.12, now + 0.5);
  fgGain.gain.exponentialRampToValueAtTime(0.0001, now + 0.85);
  const fgOsc = ctx.createOscillator();
  fgOsc.type = 'triangle';
  fgOsc.frequency.value = 660;
  fgOsc.connect(fgGain);
  fgOsc.start(now + 0.45);
  fgOsc.stop(now + 0.9);
  setTimeout(() => ctx.close(), 1400);
});

Music dipping while turn-by-turn directions play, or background music sinking under a radio DJ's voice — both are ducking. It comes from sidechain compression in broadcast and music mixing, where one track's (voice) level is detected and used to push down another track's (music) gain in real time. In Web Audio, you implement it by ramping a GainNode's gain down briefly (roughly 100-200ms) and back up.

Dropping the gain in a hard step sounds like a click, so always ramp down and back up smoothly over tens of milliseconds. A reduction of -6 to -12dB is usually enough to let the foreground cut through without burying the background completely — duck too hard and the music feels like it cut out. If the foreground sound (announcements, alerts) repeats often, ducking kicks in often too and the background warbles, so cutting the foreground's frequency is the first fix, not deeper ducking.

Used in navigation voice guidance, podcast app notification banners, and video call apps that duck background noise when someone else is detected speaking.

When to use

Use it only when a foreground sound overlaps background audio. Ramp gain down and back up smoothly — never a hard step.