API reference

Every public class, method, and event in @codexo/exojs. Generated from source.

C

classAudioSystem

@codexo/exojs / audio / stable

Per-Application owner of the audio mix: three pre-configured AudioBus instances (`master` ← `music` + `sound`), a single AudioListener for spatial audio, and a registry of any extra busses the user constructs. The `AudioContext` is shared process-wide, but each Application owns its own bus subtree, so multiple Applications mix independently. Access it via `app.audio`. Drives the per-frame `_tick()` on the listener and every spatial voice, and propagates visibility-driven mute when AudioSystem.muteOnHidden is enabled.

9
props
9
methods
1
events
Import
import { AudioSystem } from '@codexo/exojs'

Per-Application owner of the audio mix: three pre-configured AudioBus instances (`master` ← `music` + `sound`), a single AudioListener for spatial audio, and a registry of any extra busses the user constructs.

The `AudioContext` is shared process-wide, but each Application owns its own bus subtree, so multiple Applications mix independently. Access it via `app.audio`. Drives the per-frame `_tick()` on the listener and every spatial voice, and propagates visibility-driven mute when AudioSystem.muteOnHidden is enabled.

Constructors1
new(): AudioSystem
Methods9
destroy(): void
Tear the mix down: stop every voice still playing, then the listener and every bus. Terminal - AudioSystem.play and AudioSystem.open throw afterwards. Effects you attached to a bus or a voice are detached but not destroyed - they are yours (see AudioBus.addEffect), so destroy() each one yourself as part of your own teardown.
hasBus(name: string): boolean
true when a bus with name has been registered.
Play a Playable asset and return a Voice handle. Each call creates an independent playback instance. Call play() again to start another concurrent voice. The returned Voice lets you control this specific instance (stop(), volume, fade(), capabilities). When source is a Sound, options widens to SoundPlayOptions and additionally accepts replace: true, which stops all currently-playing instances of that sound before the new one starts (singleton-replace mode).
Play a Playable asset and return a Voice handle. Each call creates an independent playback instance. Call play() again to start another concurrent voice. The returned Voice lets you control this specific instance (stop(), volume, fade(), capabilities). When source is a Sound, options widens to SoundPlayOptions and additionally accepts replace: true, which stops all currently-playing instances of that sound before the new one starts (singleton-replace mode).
SystemMethods.preFrame phase, at SystemOrder.CoreAudio. The frame delta is unused here (hence _delta).
Register a user-constructed AudioBus so it can be looked up by name via AudioSystem.getBus. Throws if a bus with the same name is already registered.
Unregister and AudioBus.destroy a previously registered bus. Throws if you attempt to unregister one of the three built-ins (master, music, sound). No-op if the bus is unknown. Effects attached to that bus are only detached, never destroyed - they belong to whoever created them (see AudioBus.addEffect).
Properties9
Fires once when the AudioContext transitions to "running" - i.e. the first user gesture unlocks audio under the browser's autoplay policy. This is the canonical place to start anything that must play as soon as audio is available: ts app.audio.onUnlock.add(() => app.audio.play(music, { loop: true })); Every handler runs **exactly once, as soon as audio is usable**, whenever it subscribes: already unlocked replays it on a microtask, still locked (including a re-lock after an earlier unlock - an iOS audio-session interruption, a bfcache restore) registers it for the next unlock. A handler that has already run is never fired again by a later unlock, so looping music started here does not stack a second copy after an interruption. remove() cancels either case, and nothing fires once the system is destroyed. Check AudioSystem.locked for the current state. See AudioSystem.play for what each asset kind does when played before the gesture.
Tunable smoothing applied to per-frame panner/listener position updates, shared by the AudioListener and every spatial voice. Adjust smoothing (the setTargetAtTime time constant) or teleportThreshold (the snap-instead-of-ramp jump distance) to trade responsiveness against zipper-noise suppression (AU4). Reachable as app.audio.spatial.
Optional zone layer: regions of the world that contribute a parallel send while the listener is inside them - a reverb zone, a muffled corridor. Empty and inert until a zone is added; see SpatialZones.
locked: boolean
true while audio is blocked by the browser's autoplay policy - no user gesture has resumed the AudioContext yet. What a play call does while locked depends on the asset: an AudioStream is deferred and starts on the gesture, because a media element owns its own playhead and can simply be told to play later. A Sound or an AudioGenerator is **skipped** - it returns an already-ended voice and never makes a sound. Neither can be deferred honestly: a suspended context's currentTime stands still, so every source scheduled while locked lands on the same instant and the entire backlog would fire simultaneously on the gesture. Start such playback from AudioSystem.onUnlock instead.
muteOnHidden: boolean
When true, the master bus is muted while document.hidden is true. Wired to Application.onVisibilityChange via AudioSystem._applyVisibility; the application calls that hook automatically - set this flag to opt in to the behavior.
Events1
Fires when a play call was dropped because the autoplay policy still blocks audio - the moment a listener can act on, as opposed to AudioSystem.locked, which is merely true for most of a page's life and says nothing about whether anything wanted to be heard. Throttled with the accompanying warning: a game that plays a click every frame while locked reports once, not sixty times a second, and the next unlock re-arms it. The intended use is an interface that asks for the gesture the browser is waiting for - a play overlay - and then resumes through AudioSystem.onUnlock, which replays the handlers registered during the lock.
Source