AudioInstance
audio/audio-instance.ts:42One playing voice in the audio graph — a single connection of an
AudioBuffer through per-instance gain and panner nodes into a category
bus on the AudioEngine.
AudioInstance is the handle the audio-playing components
(AudioSource, Music) work through. It exposes the standard
playback surface — play, pause, resume, stop, restart, volume, pan, loop
— and hides the Web Audio bookkeeping that makes them work (recreating
AudioBufferSourceNodes, tracking elapsed time across pause/resume).
Pause semantics
A Web Audio AudioBufferSourceNode cannot be paused once it has started
— it can only be stopped, and stopping is terminal. To implement
pause/resume, this class:
- Records
currentTimewhen AudioInstance.play starts the source, plus the buffer offset it was started at. - On AudioInstance.pause, computes the elapsed playback position, clamps or wraps it against the buffer duration depending on AudioInstance.loop, stores it, and stops the source.
- On the next AudioInstance.play, allocates a fresh source and starts it from the stored offset.
AudioInstance.stop resets the stored offset to zero, so the next AudioInstance.play resumes from the beginning.
Headless mode
When the AudioEngine has no AudioContext (a headless test
environment, an SSR build, a browser that has audio disabled), every
playback method is a no-op that updates the internal state flags but does
not allocate Web Audio nodes. This mirrors the engine's input-component
behaviour: code keeps running, audio is silently inert.
Constructors
constructor(engine: AudioEngine, buffer: AudioBuffer, _categoryGain: null | GainNode, options: AudioInstanceOptions): AudioInstance Parameters
-
engineAudioEngine -
bufferAudioBuffer -
_categoryGainnull | GainNode -
optionsAudioInstanceOptions
Properties
engine: AudioEngine The AudioEngine this instance plays through. Required for context access; the engine's master/category gain nodes own the bus this instance ultimately feeds.
Accessors
duration: number Duration of the underlying clip in seconds. Equivalent to AudioAsset.duration for the asset this instance was built from.
loop: boolean Whether the clip should loop back to its start on reaching the end. Changing this mid-play takes effect on the currently-running source — a clip that has not yet hit its end will start (or stop) looping from its next boundary.
pan: number Stereo pan from -1 (left) to 1 (right). Setting it during playback
applies instantly to the underlying StereoPannerNode.
paused: boolean Whether the clip is paused — AudioInstance.play will resume from the saved position. Mutually exclusive with AudioInstance.playing.
playing: boolean Whether the clip is currently advancing through the buffer (a source
node is active and unpaused). Flips back to false when the clip
finishes its last loop or is paused/stopped.
stopped: boolean Whether the clip is not currently emitting audio — true when idle,
stopped, or paused; false while AudioInstance.playing is
true.
volume: number Per-instance volume from 0 to 1. Setting it during playback ramps
the underlying gain instantly; setting it before AudioInstance.play
applies on the next start.
Methods
destroy(): void Tears the instance down completely: stops playback, disconnects every node from the audio graph, and drops them. The instance is not reusable after this call — discard the handle.
Called automatically by AudioSource when a one-shot SFX finishes and by Music.onDestroy when the host world tears down.
Returns
void onEnded(listener: () => void): () => void Subscribes to the natural end of playback — the moment the source
reports onended because it finished its last loop (or because it was
stopped). Returns an unsubscribe function. Fires at most once per
play(), so call after each play if you want repeated notifications.
AudioSource uses this to prune finished one-shot voices.
Parameters
-
listener() => void
Returns
() => void pause(): void Pauses playback in place. The next AudioInstance.play resumes from this point. A no-op when the instance is not currently playing.
Returns
void play(): void Starts playback from the saved position — zero on a fresh or stopped instance, the pause offset on a paused one. Calling AudioInstance.play on an already-playing instance is a no-op (use AudioInstance.restart to restart from the beginning).
In headless mode this transitions the state flags but allocates no Web Audio nodes.
Returns
void restart(): void Stops the clip if it is running, resets the resume offset, then plays from the start. Equivalent to AudioInstance.stop followed by AudioInstance.play and the standard way to "play this sound again from scratch."
Returns
void stop(): void Stops playback and resets the resume offset to zero, so the next AudioInstance.play starts from the beginning of the clip. Idempotent — stopping an already-stopped instance is a no-op.
Returns
void