← Back to Documentation Index

🔊 Audio System

Sound effects and music with Web Audio API synthesis

📋 Overview

The Audio System provides retro-style sound effect generation using the Web Audio API. Create classic game sounds with square waves, sine waves, sawtooth, and noise using simple parameters.

💡 Key Features
  • Waveform Synthesis - Square, sine, sawtooth, and noise
  • Frequency Sweep - Pitch changes over time (laser, explosion effects)
  • Multi-Channel - 8 simultaneous sound channels
  • Volume Control - Per-sound and master volume
  • Preset System - Pre-configured sound effects (0-2)

🎵 Main Function

sfx(options)

Plays a sound effect with custom parameters or preset ID.

options object or number - Sound parameters or preset ID (0-2)

Parameters (when options is an object):

wave string - Waveform: "square", "sine", "sawtooth", or "noise" (default: "square")
freq number (Hz) - Base frequency (default: 440)
dur number (seconds) - Duration (default: 0.2)
vol number (0-1) - Volume (default: 0.5)
sweep number (Hz/sec) - Frequency change rate (default: 0)
Example: Custom sound effects
// Jump sound (rising pitch)
sfx({ wave: 'square', freq: 200, dur: 0.15, sweep: 800, vol: 0.3 });

// Laser shot (falling pitch)
sfx({ wave: 'sine', freq: 1000, dur: 0.3, sweep: -1500, vol: 0.4 });

// Explosion (noise)
sfx({ wave: 'noise', dur: 0.5, vol: 0.6 });

// Power-up (major chord sweep)
sfx({ wave: 'sine', freq: 440, dur: 0.4, sweep: 400, vol: 0.3 });

Preset Sounds (ID-based)

sfx(id)

Plays a pre-configured sound effect by ID.

ID Sound Parameters
0 Blip/Menu Square wave, 880 Hz, 0.1s
1 Coin/Pickup Sine wave, 220 Hz → 120 Hz, 0.3s
2 Hit/Impact Noise, 0.2s
Example: Using presets
// Menu navigation
if (btnp(2)) {
  menuIndex--;
  sfx(0); // Blip sound
}

// Collect coin
if (collectedCoin) {
  score += 10;
  sfx(1); // Coin sound
}

// Take damage
if (hitByEnemy) {
  health -= 10;
  sfx(2); // Hit sound
}

🎼 Waveform Guide

Waveform Sound Character Best For
square Hollow, retro, chip-tune Blips, beeps, menu sounds, retro games
sine Pure, smooth, musical Lasers, power-ups, melodic effects
sawtooth Buzzy, harsh, aggressive Alarms, engines, intense action
noise Static, explosion-like Explosions, impacts, wind, crashes

🎨 Sound Design Examples

Classic Game Sounds
// Jump (8-bit platformer)
function playJumpSound() {
  sfx({ wave: 'square', freq: 300, dur: 0.1, sweep: 600, vol: 0.25 });
}

// Laser shoot
function playLaserSound() {
  sfx({ wave: 'sine', freq: 800, dur: 0.2, sweep: -1200, vol: 0.35 });
}

// Explosion
function playExplosionSound() {
  sfx({ wave: 'noise', dur: 0.6, vol: 0.7 });
  // Add bass rumble
  sfx({ wave: 'sine', freq: 60, dur: 0.4, vol: 0.5 });
}

// Power-up collected
function playPowerUpSound() {
  // Arpeggio effect
  sfx({ wave: 'sine', freq: 523, dur: 0.08, vol: 0.3 }); // C
  setTimeout(() => {
    sfx({ wave: 'sine', freq: 659, dur: 0.08, vol: 0.3 }); // E
  }, 80);
  setTimeout(() => {
    sfx({ wave: 'sine', freq: 784, dur: 0.15, vol: 0.3 }); // G
  }, 160);
}

// Enemy hit
function playHitSound() {
  sfx({ wave: 'noise', dur: 0.1, vol: 0.4 });
  sfx({ wave: 'square', freq: 150, dur: 0.15, sweep: -100, vol: 0.3 });
}

// Menu select
function playMenuSelectSound() {
  sfx({ wave: 'square', freq: 660, dur: 0.05, vol: 0.2 });
}

// Game over
function playGameOverSound() {
  // Descending notes
  const notes = [523, 494, 440, 392, 349];
  notes.forEach((freq, i) => {
    setTimeout(() => {
      sfx({ wave: 'square', freq, dur: 0.25, vol: 0.3 });
    }, i * 200);
  });
}

💡 Usage Tips

Best Practices
  • Volume Control: Keep vol between 0.2-0.5 to avoid overpowering music/other sounds
  • Frequency Range: 20 Hz (bass) to 20,000 Hz (high pitch). Use 200-2000 Hz for most game sounds
  • Duration: Short sounds (0.05-0.2s) for UI, longer (0.3-1.0s) for ambience
  • Sweep: Positive values = rising pitch (jump), negative = falling (laser)
  • Layering: Combine multiple sfx() calls for complex sounds (explosion = noise + bass)
  • Timing: Use setTimeout() for sequential notes (melodies, arpeggios)
Performance
  • Maximum 8 sounds playing simultaneously
  • Audio context initializes on first sfx() call (user interaction required)
  • Master volume set to 0.2 by default to prevent clipping

🎹 Frequency Reference (Musical Notes)

Note Frequency (Hz) Use Case
C3131Bass rumble
C4 (Middle C)262Low effects
A4440Standard reference pitch
C5523Medium effects
C61047High effects
C72093Very high, sharp sounds

📚 Related APIs