AudioManager
AudioManager is a singleton that manages all audio playback using the Web Audio API, with an automatic HTML5 Audio fallback for environments without Web Audio support.
It is mounted automatically by Game — you do not need to set it up manually.
import { getAudioManager } from "@carverjs/core/systems";How It Works #
On
Gamemount, theAudioContextis created and unlock listeners are attached to the document.On first user gesture (click, tap, keypress), the
AudioContextis resumed and a silent buffer is played to satisfy iOS Safari requirements. Queued music begins playing.Each frame (at priority -48, after input flush),
flush()runs:Pauses/resumes the context based on game phase
Updates spatial sound positions from
Object3DrefsSyncs the Web Audio listener to the active camera
On
Gameunmount, all sounds stop, theAudioContextcloses, and all resources are freed.
Audio Backend Detection #
The system auto-detects the best available backend:
| Backend | When Used | Features |
|---|---|---|
| Web Audio API | AudioContext is available (98%+ of browsers) | Full features: spatial audio, gain automation, AudioParam scheduling |
| HTML5 Audio | AudioContext unavailable | Basic playback, volume via audio.volume, no spatial audio |
The fallback is transparent — the public API is identical regardless of backend.
Volume Routing (Web Audio) #
[Source] → [Instance Gain] → [Channel Gain] → [Master Gain] → destination
│
One per channel:
sfx, music, ui,
ambient, voiceChannel gains are created once and persist for the lifetime of the AudioContext. Mute is implemented by setting gain to 0 and restoring on unmute.
API #
getAudioManager() #
Returns the singleton AudioManager instance. Creates one if it doesn't exist.
destroyAudioManager() #
Stops all sounds, closes the AudioContext, and destroys the singleton. Called automatically when Game unmounts.
Sound Registration #
| Method | Description |
|---|---|
registerSound(name, def) | Register a sound definition. Preloads by default |
unregisterSound(name) | Unregister and stop all instances |
Playback #
| Method | Description |
|---|---|
play(name, options?) | Play a registered sound. Returns SoundHandle |
stopByName(name) | Stop all instances of a sound |
pauseByName(name) | Pause all instances |
resumeByName(name) | Resume paused instances |
isSoundPlaying(name) | Check if any instance is playing |
Music #
| Method | Description |
|---|---|
playMusic(src, options?) | Play a music track with crossfade |
stopMusic(fadeOut?) | Stop music with optional fade-out |
pauseMusic() | Pause the music |
resumeMusic() | Resume the music |
isMusicPlaying() | Check if music is playing |
Volume #
| Method | Description |
|---|---|
setChannelVolume(channel, volume) | Set channel volume (0–1) |
getChannelVolume(channel) | Get channel volume |
setChannelMute(channel, muted) | Mute/unmute a channel |
isChannelMuted(channel) | Check mute state |
setMasterMute(muted) | Mute/unmute all audio |
Preloading #
| Method | Description |
|---|---|
preload(name) | Preload a registered sound |
preloadAll(names) | Preload multiple sounds |
unloadBuffer(name) | Free a sound's buffer from memory |
Listener #
| Method | Description |
|---|---|
setListenerSource(obj) | Set the default listener (camera). Called by AudioFlush |
setCustomListener(obj) | Override the listener. Called by AudioListener component |
Usage #
Most game code should use the useAudio hook. Direct manager access is useful for systems-level code:
import { getAudioManager } from "@carverjs/core/systems";
import { useGameLoop } from "@carverjs/core/hooks";
function AmbientSystem() {
useGameLoop(() => {
const mgr = getAudioManager();
if (mgr.isSoundPlaying("rain")) return;
mgr.play("rain", { loop: true });
});
return null;
}Type Definitions #
See Types for AudioChannel, SoundDefinition, PlaySoundOptions, SoundHandle, MusicOptions, and SoundState.