Waveform types

파형의 종류

The four basic oscillator shapes — sine, square, sawtooth, triangle. A waveform's shape is literally its harmonic content, its timbre.

Also known as: Oscillator waveformsSine/Square/Saw/Triangle
···
html
<div class="wrap">
  <div class="grid">
    <div class="cell" id="c-sine"><canvas data-type="sine"></canvas><span>sine</span></div>
    <div class="cell" id="c-square"><canvas data-type="square"></canvas><span>square</span></div>
    <div class="cell" id="c-saw"><canvas data-type="sawtooth"></canvas><span>saw</span></div>
    <div class="cell" id="c-triangle"><canvas data-type="triangle"></canvas><span>triangle</span></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:88%}
.grid{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:6%;width:100%;height:100%}
.cell{position:relative;border:1px solid var(--line);border-radius:10px;background:var(--surface);overflow:hidden;transition:box-shadow .2s,border-color .2s}
.cell.go{border-color:var(--accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 30%,transparent)}
.cell canvas{position:absolute;inset:0;width:100%;height:100%}
.cell span{position:absolute;left:6px;bottom:4px;font:600 9px/1 monospace;color:var(--muted);z-index:2}
.play{position:absolute;right:0;bottom:0;width:clamp(26px,14%,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);z-index:3}
.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 TYPES = ['sine', 'square', 'sawtooth', 'triangle'];
const canvases = {};
TYPES.forEach((t) => { canvases[t] = document.querySelector('canvas[data-type="' + t + '"]'); });
const cs = getComputedStyle(document.documentElement);
const ACCENT = cs.getPropertyValue('--accent').trim() || '#5b5bf7';
function wave(type, phase) {
  const p = phase - Math.floor(phase);
  if (type === 'sine') return Math.sin(p * Math.PI * 2);
  if (type === 'square') return p < 0.5 ? 1 : -1;
  if (type === 'sawtooth') return p * 2 - 1;
  return p < 0.5 ? p * 4 - 1 : 3 - p * 4;
}
function draw(type, t) {
  const cv = canvases[type];
  const g2d = cv.getContext('2d');
  const dpr = Math.min(devicePixelRatio || 1, 2);
  const w = cv.clientWidth, h = cv.clientHeight;
  if (cv.width !== w * dpr || cv.height !== h * dpr) { cv.width = w * dpr; cv.height = h * dpr; }
  g2d.setTransform(dpr, 0, 0, dpr, 0, 0);
  g2d.clearRect(0, 0, w, h);
  g2d.beginPath();
  const cycles = 2.4, scroll = t * 0.00035;
  for (let x = 0; x <= w; x++) {
    const phase = (x / w) * cycles + scroll;
    const y = h / 2 - wave(type, phase) * (h * 0.34);
    if (x === 0) g2d.moveTo(x, y); else g2d.lineTo(x, y);
  }
  g2d.strokeStyle = ACCENT;
  g2d.lineWidth = 1.8;
  g2d.stroke();
}
function loop(t) {
  TYPES.forEach((type) => draw(type, t));
  requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
document.getElementById('play').addEventListener('click', () => {
  const ctx = new (window.AudioContext || window.webkitAudioContext)();
  const now = ctx.currentTime;
  TYPES.forEach((type, i) => {
    const t = now + i * 0.24;
    const osc = ctx.createOscillator();
    const gain = ctx.createGain();
    osc.type = type;
    osc.frequency.value = 261.63;
    gain.gain.setValueAtTime(0, t);
    gain.gain.linearRampToValueAtTime(0.1, t + 0.02);
    gain.gain.exponentialRampToValueAtTime(0.0001, t + 0.22);
    osc.connect(gain).connect(ctx.destination);
    osc.start(t);
    osc.stop(t + 0.23);
    const cellId = type === 'sawtooth' ? 'c-saw' : ('c-' + type);
    setTimeout(() => {
      const el = document.getElementById(cellId);
      el.classList.add('go');
      setTimeout(() => el.classList.remove('go'), 200);
    }, i * 240);
  });
  setTimeout(() => ctx.close(), 1100);
});

A synth oscillator makes sound by repeating a pattern of instantaneous amplitude over time — the waveform. A sine wave is the "purest" tone with zero harmonics; a square wave contains only odd harmonics for a hollow color; a sawtooth packs in every harmonic densely for the sharpest, richest tone; a triangle sits between sine and square, close to sine's softness with a touch of harmonic edge.

More harmonics (square, sawtooth) means a more aggressive, far-carrying sound — good for a notification that needs to grab attention briefly, but fatiguing over time. Sine and triangle stay soft and blend into the background, suited to gentle confirmation tones. Loud square/sawtooth waves in the low register (under 100Hz) clip easily on speakers and earbuds, so keep the gain lower there.

Used in synthesizers and 8-bit game sound (square), synth basslines and leads (sawtooth), woodwind emulation (square), and gentle UI tones (sine, triangle).

When to use

Pick square or sawtooth when a sound needs to grab attention (like a notification); pick sine or triangle for a gentle confirmation tone.