API reference

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

I

interfaceVoice

@codexo/exojs / audio / stable

A live playback instance in the audio graph with a control surface. A Voice is created by playing a Playable via AudioSystem.play (and, later, by opening an `AudioInput`). Each `play()` returns an independent Voice, so overlapping concurrent playback of the same asset is just multiple Voices. Concrete voices mix in the capability interfaces (Seekable, Pausable, Loopable, RatePitched) for whatever their backing Web Audio node actually supports - narrow with a capability check (`'seek' in voice`) before using one. Spatializable is not one of those: every voice carries it. The panner is inserted lazily, so a voice that is never positioned costs nothing, and PlayOptions already accepts the full spatial set at play time - a returned voice must be able to keep steering what the play call was allowed to start.

20
props
7
methods
0
events
Import
import { Voice } from '@codexo/exojs'

A live playback instance in the audio graph with a control surface.

A Voice is created by playing a Playable via AudioSystem.play (and, later, by opening an `AudioInput`). Each `play()` returns an independent Voice, so overlapping concurrent playback of the same asset is just multiple Voices.

Concrete voices mix in the capability interfaces (Seekable, Pausable, Loopable, RatePitched) for whatever their backing Web Audio node actually supports - narrow with a capability check (`'seek' in voice`) before using one.

Spatializable is not one of those: every voice carries it. The panner is inserted lazily, so a voice that is never positioned costs nothing, and PlayOptions already accepts the full spatial set at play time - a returned voice must be able to keep steering what the play call was allowed to start.

Methods7
Insert a per-voice AudioEffect into this voice's output chain (after the volume gain, before the bus). Effects are applied in insertion order.
Open a parallel send from this voice's output into bus at level (default 1). The dry path is untouched: the voice keeps playing into its own Voice.bus, and a copy of the same signal additionally reaches bus. Use it for shared ambience processing - one reverb serving many voices - which an insert effect cannot express, because an insert replaces the signal rather than duplicating it. The returned AudioSend is owned by this voice and torn down with it; remove one early with Voice.removeSend only to change the routing.
Ramp the volume to to (clamped to [0, 1]) over duration without stopping. Use Voice.stop with a fade argument to fade out and stop.
Track a SceneNode: the voice reads the node's global translation each frame. Pass null to stop following and fall back to Spatializable.position.
Remove a previously added per-voice effect. The caller still owns it and must destroy() it.
Stop playback and release this voice's resources. Pass fade to ramp the volume to zero over that duration before stopping; omit (or pass 0) to stop immediately. Idempotent - calling again is a no-op.
Properties20
coneInnerAngle: number
Full-gain cone half-angle in degrees. Default 360 (omnidirectional - no cone).
coneOuterAngle: number
Falloff-to-coneOuterGain cone half-angle in degrees. Default 360.
coneOuterGain: number
Gain applied outside coneOuterAngle. Default 0.
elevation: number
Height of the source above (positive) or below (negative) the world plane, in world units. Default 0. Independent of Spatializable.position, and preserved across a position change that does not carry a z. It contributes to distance attenuation, to the panner's own directionality, and to Doppler - a source rising straight up recedes.
elevationVelocity: number
Vertical component of Spatializable.velocity, in world units per second. Default 0. Only Doppler reads it.
ended: boolean
true once playback has ended naturally or been stopped.
maxDistance: number
For the 'linear' model: distance at which volume reaches zero. Default 1000.
occlusion: number
How obstructed the path from this source to the listener is, in [0, 1]. 0 (default) is a clear path; 1 is fully obstructed. Caller-supplied: the engine does not trace geometry, because what counts as an obstruction is a game's decision (a wall, a closed door, a crowd). Write an estimate as often as you like - it is ramped, not stepped, so a per-frame value does not click. Realized as a lowpass plus an attenuation, tuned by app.audio.spatial.occlusionCutoff / .occlusionAttenuation. A voice whose occlusion stays 0 builds neither node.
orientation: number
Facing direction for cone attenuation, in degrees - same convention as SceneNode.rotation (0° = local +X / "east", clockwise-positive on a Y-down screen). Has no audible effect unless coneInnerAngle/ coneOuterAngle are narrowed below 360°. Default 0.
output: AudioNode
The voice's output node - the last node before the AudioBus. Use it as a parallel tap for an analyser, or (later) as the insertion point for per-voice effects.
panningModel: PanningModelType | null
Per-voice panning model override. null (default) inherits the app-wide default from app.audio.spatial.panningModel.
refDistance: number
Distance below which volume is at full strength. Default 50.
rolloffFactor: number
Falloff rate. Higher = steeper attenuation. Default 1.
volume: number
Playback volume in the range [0, 1]. Bus volume (0..2) can amplify beyond this.
World-plane position of the source, or null when not spatialized. Two-dimensional, because the world plane is: the third axis lives on Spatializable.elevation, which Spatializable.follow cannot fill in and which most 2D games never touch.
World-space velocity of the source (world units/second), or null. Feeds the Doppler calculation (app.audio.spatial.dopplerFactor) - has no other effect. Explicit; when null and follow(node) is active, velocity is auto-derived each frame from the tracked node's position delta instead.
Source