Atom Engine

Audio State Manager (Web Audio System)

Purpose

This module provides a lightweight audio management layer built on the Web Audio API. It handles:

It is designed for browser environments where audio playback must be unlocked via user interaction.


Lifecycle

Creation → Update → Destruction

  1. Creation (createAudioState)
    • Instantiates an AudioContext
    • Creates a global GainNode for music volume control
    • Registers one-time event listeners to unlock audio on first user interaction
  2. Update (runtime usage)
    • Audio buffers are loaded into memory (loadAudio)
    • Sounds or music are played from cached buffers
    • Music can be stopped or volume-adjusted dynamically
  3. Destruction
    • Not explicitly implemented
    • Would require manual cleanup of:
      • AudioContext.close()
      • active nodes (musicSource, musicGain connections)

Public API

createAudioState(): AudioState

Initializes and returns the audio system state.


loadAudio(state, name, url): Promise<void>

Loads an audio file and stores it in memory.


playSound(state, name): void

Plays a one-shot sound effect.


playMusic(state, name, volume?): void

Plays looping background music.


stopMusic(state): void

Stops currently playing music.


setMusicVolume(state, volume): void

Adjusts global music volume.


playMusicAfterGesture(state, name, volume?): Promise<void>

Ensures audio is unlocked before playing music.


Internal Behavior

Audio Unlocking System

Modern browsers block audio until a user gesture occurs. This module handles it via:


Buffer Management


Music Routing Architecture

Music playback uses a dedicated signal chain:

AudioBufferSourceNode → GainNode (musicGain) → AudioContext.destination

This allows centralized volume control for music only, without affecting sound effects.


Sound vs Music Separation


Example

const audio = createAudioState();

await loadAudio(audio, "click", "/sounds/click.mp3");
await loadAudio(audio, "bgm", "/music/theme.mp3");

// Play sound effect
playSound(audio, "click");

// Start background music
playMusic(audio, "bgm", 0.5);

// Adjust volume later
setMusicVolume(audio, 0.2);

// Stop music
stopMusic(audio);