Skip to content

@aosengine/audio ​

Interfaces ​

AudioBuses ​

The bus gain nodes, keyed by name.

Properties ​

master ​
ts
readonly master: GainNode;

Sums sfx, music and voice; connected to context.destination.

music ​
ts
readonly music: GainNode;

Music beds.

sfx ​
ts
readonly sfx: GainNode;

One-shot gameplay sounds.

voice ​
ts
readonly voice: GainNode;

Dialogue and say lines.


AudioEngine ​

The audio service: everything the host needs to run a frame of sound.

Properties ​

buses ​
ts
readonly buses: AudioBuses;

The bus gain nodes. Adjust bus.gain.value for mixer sliders.

context ​
ts
readonly context: AudioContext;

The context the graph lives on.

ended ​
ts
readonly ended: number[];

Handles of sounds that ran to their natural end since the host last cleared this array. AudioEngine.update appends to it; the host turns each entry into a sound-ended event and then clears it with ended.length = 0.

A voice the game stopped itself — AudioEngine.stop, or a AudioEngine.play reusing a live handle — is not listed: the game already knows, and reporting it would claim a completion that never happened. Capped at 256 entries so a host that never drains it cannot grow the array without bound.

Methods ​

decode() ​
ts
decode(id, data): Promise<AudioBuffer>;

Decode encoded audio bytes, memoised by id.

Parameters ​
ParameterTypeDescription
idstringManifest asset id, the cache key.
dataArrayBufferEncoded bytes.
Returns ​

Promise<AudioBuffer>

The decoded buffer. Repeat calls with the same id share a promise.

dispose() ​
ts
dispose(): void;

Stop everything, drop the graph, and close a context this engine created.

Returns ​

void

play() ​
ts
play(args): void;

Start a voice.

Parameters ​
ParameterTypeDescription
argsPlayArgsWhat to play, where and how loud.
Returns ​

void

resume() ​
ts
resume(): Promise<void>;

Resume a context the browser suspended. Safe to call repeatedly.

Returns ​

Promise<void>

Resolves once the context is running.

setListener() ​
ts
setListener(pos, rotQuat): void;

Move the listener.

Parameters ​
ParameterTypeDescription
posVec3World position.
rotQuatQuatOrientation; forward is local -Z, up is local +Y.
Returns ​

void

setVolume() ​
ts
setVolume(id, v): void;

Change a playing voice's gain.

Parameters ​
ParameterTypeDescription
idnumberThe sound handle. Unknown ids are ignored.
vnumberLinear gain, 0..1.
Returns ​

void

stop() ​
ts
stop(id): void;

Stop a voice now. Nothing is added to AudioEngine.ended: the caller asked for this, so it is not a completion.

Parameters ​
ParameterTypeDescription
idnumberThe handle passed to AudioEngine.play. Unknown ids are ignored.
Returns ​

void

update() ​
ts
update(): void;

Retire every voice whose buffer has run out and drain them into ended.

Timing comes from context.currentTime, the clock the voices themselves run on, not from the caller's frame delta: a long frame, a background tab or a timeScale change cannot drift the two apart. A suspended context does not advance, and neither does playback, so nothing ends early.

Returns ​

void


AudioEngineOptions ​

Options for createAudioEngine.

Extended by ​

Properties ​

context? ​
ts
optional context?: AudioContext;

An existing context to drive. When omitted a new AudioContext is constructed, which requires a DOM environment. Pass one in tests.

masterVolume? ​
ts
optional masterVolume?: number;

Linear gain on the master bus, 0..1. Defaults to 1.


AudioModule ​

The 'audio' module. Its service is the AudioEngine it owns.

Extends ​

Properties ​

id ​
ts
readonly id: string;

Unique id. Also the service id when init returns a service.

Inherited from ​

EngineModule.id

order? ​
ts
readonly optional order?: number;

Sort key. Lower runs first; equal keys keep registration order.

Rough convention: input -100, gameplay -50, physics 0, rendering helpers 200. Gameplay runs before physics so that the commands a guest tick emits are simulated by the step that follows rather than the next one.

Inherited from ​

EngineModule.order

service ​
ts
readonly service: AudioEngine | null;

The audio engine this module owns, or null before init and after dispose.

The engine is built by init, not by audio: constructing an AudioContext is a side effect on the page — browsers count them, and an unlocked one logs a warning — so a module that is never registered must never make one. init returns the engine, so the registry publishes it under 'audio' and engine.get('audio') hands back this same object.

Methods ​

beginFrame()? ​
ts
optional beginFrame(): void;

Run before the frame's fixed steps. Input capture lives here.

Returns ​

void

Inherited from ​

EngineModule.beginFrame

decodeAsset() ​
ts
decodeAsset(idOrHandle): Promise<AudioBuffer>;

Decode the bytes behind an asset id or handle, memoised.

This is the bridge from a play-sound command — which carries an asset handle, never a URL — to the AudioBuffer AudioEngine.play wants. The asset must already be loaded; type: 'audio' entries load as an ArrayBuffer.

Parameters ​
ParameterTypeDescription
idOrHandlestring | numberManifest asset id, or the handle the guest minted for it.
Returns ​

Promise<AudioBuffer>

The decoded buffer; rejects when the asset is missing or not audio.

decodedAsset() ​
ts
decodedAsset(idOrHandle): AudioBuffer | undefined;

The already-decoded buffer for an asset, without awaiting anything.

This is what lets the host play a repeated sound — a footstep, a shot — inside the frame that asked for it instead of a microtask later. A miss means "not decoded yet"; fall back to AudioModule.decodeAsset.

Handles and ids share one cache entry: a handle is normalised through the asset registry first, so decodedAsset(7) and decodedAsset('sfx.shot') hit the same buffer.

Parameters ​
ParameterTypeDescription
idOrHandlestring | numberManifest asset id, or the handle the guest minted for it.
Returns ​

AudioBuffer | undefined

The decoded buffer, or undefined when no decode has finished.

dispose() ​
ts
dispose(): void;

Release everything this module took.

Returns ​

void

Inherited from ​

EngineModule.dispose

endFrame()? ​
ts
optional endFrame(): void;

Run after rendering. Input's end-of-frame bookkeeping lives here.

Returns ​

void

Inherited from ​

EngineModule.endFrame

fixedUpdate()? ​
ts
optional fixedUpdate(dt): void;

Run once per fixed step.

Parameters ​
ParameterTypeDescription
dtnumberAlways ctx.config.fixedDt, whatever time.timeScale is; time scale changes how many steps a frame runs, not their length.
Returns ​

void

Inherited from ​

EngineModule.fixedUpdate

init() ​
ts
init(ctx): AudioEngine;

Build the engine and publish it as the 'audio' service.

Parameters ​
ParameterTypeDescription
ctxEngineContextThe host surface; only ctx.assets is read.
Returns ​

AudioEngine

The audio engine.

Overrides ​

EngineModule.init

update() ​
ts
update(dt, alpha): void;

Pump the engine: retire finished voices and fill service.ended. A no-op before init.

Always present on this module, so callers need no optional call.

Parameters ​
ParameterTypeDescription
dtnumberWall-clock seconds since the previous frame; unused, because the engine times voices on the audio context's own clock.
alphanumberInterpolation factor; unused by audio.
Returns ​

void

Overrides ​

EngineModule.update


AudioModuleOptions ​

Options for audio.

Extends ​

Properties ​

context? ​
ts
optional context?: AudioContext;

An existing context to drive. When omitted a new AudioContext is constructed, which requires a DOM environment. Pass one in tests.

Inherited from ​

AudioEngineOptions.context

masterVolume? ​
ts
optional masterVolume?: number;

Linear gain on the master bus, 0..1. Defaults to 1.

Inherited from ​

AudioEngineOptions.masterVolume

order? ​
ts
optional order?: number;

Position in the module order. Lower runs first. Defaults to 30.

unlockTarget? ​
ts
optional unlockTarget?: EventTarget;

Where the one-time unlock listener is installed. Defaults to the global object; pass the canvas to scope it, or a stub in tests.


PlayArgs ​

One call to AudioEngine.play.

Properties ​

buffer ​
ts
buffer: AudioBuffer;

The decoded buffer to play, normally from AudioEngine.decode.

bus? ​
ts
optional bus?: BusName;

Bus to route through. Defaults to 'sfx'.

id ​
ts
id: number;

Guest-minted sound handle. Replaces any sound already using this handle.

loop? ​
ts
optional loop?: boolean;

Loop until stopped. Looping voices never end on their own. Defaults to false.

pos? ​
ts
optional pos?: Vec3;

World position. When given the voice gets an HRTF PannerNode.

volume? ​
ts
optional volume?: number;

Linear gain, 0..1. Defaults to 1.

Type Aliases ​

BusName ​

ts
type BusName = "master" | "sfx" | "music" | "voice";

The buses a voice can be routed to. master is the sum of the other three.


Quat ​

ts
type Quat = readonly [number, number, number, number];

A rotation, as a plain [x, y, z, w] quaternion (three.js / Jolt order).


Vec3 ​

ts
type Vec3 = readonly [number, number, number];

A world-space position, as a plain [x, y, z] array.

Variables ​

PACKAGE ​

ts
const PACKAGE: "@aosengine/audio";

Package identity marker.

Example ​

ts
import { PACKAGE } from '@aosengine/audio';

console.log(PACKAGE); // '@aosengine/audio'

Functions ​

audio() ​

ts
function audio(options?): AudioModule;

Create the audio module.

Register it in the engine's module list. init builds the AudioEngine and returns it, so it becomes the 'audio' service: the host maps play-sound / stop-sound / set-listener straight onto its methods and drains ended into sound-ended events each frame. Until then AudioModule.service is null and no AudioContext exists.

Browsers keep an AudioContext suspended until the page sees a user gesture, so init installs a single pointerdown + keydown listener that calls resume() once and then removes itself.

Parameters ​

ParameterTypeDescription
optionsAudioModuleOptionsEngine options, plus the unlock target and module order.

Returns ​

AudioModule

The module, ready to register.

Example ​

ts
import { audio } from '@aosengine/audio';

const mod = audio({ masterVolume: 0.8 });
const engine = mod.init(ctx);

const buffer = await mod.decodeAsset('pistol');
engine.play({ id: 1, buffer, pos: [0, 1, -3] });
mod.update(1 / 60, 0);

// The next shot needs no await: the decode has already settled.
const again = mod.decodedAsset('pistol');
if (again) engine.play({ id: 2, buffer: again });

createAudioEngine() ​

ts
function createAudioEngine(options?): AudioEngine;

Create the audio engine.

The graph is voice -> [panner] -> bus -> master -> destination. Nothing is allocated per frame: voices are pooled, the listener basis is written into scratch arrays, and ended is reused.

Parameters ​

ParameterTypeDescription
optionsAudioEngineOptionsContext to adopt and initial master gain.

Returns ​

AudioEngine

The engine, which is also the 'audio' module's service.

Example ​

ts
import { createAudioEngine } from '@aosengine/audio';

const engine = createAudioEngine({ masterVolume: 0.8 });
const buffer = await engine.decode('pistol', bytes);

engine.play({ id: 1, buffer, pos: [3, 0, -4], bus: 'sfx' });
engine.update();
for (const id of engine.ended) console.log('ended', id);
engine.ended.length = 0;