16.2. Audio playback, mixing, 3D spatial audio, and effects

Module audio_boost

16.2.1. Type aliases

SID = uint64

Sound ID — a unique handle for every playing sound. Returned by all play functions.

AudioSystemChannels = tuple<command:Stream?;next_sid:Atomic64?>

typedef AudioSystemChannels = tuple<command:jobque::Stream?;next_sid:jobque::Atomic64?> aka AudioSystemChannels

16.2.2. Constants

SPEED_OF_SOUND = 343.3f

SPEED_OF_SOUND:float const

MAX_SPEED_OF_OBJECT = 171.65f

MAX_SPEED_OF_OBJECT:float const

MA_CHANNELS = 2

MA_CHANNELS:int const

MA_HRTF = true

MA_HRTF:bool const

INVALID_SID = 0x0

INVALID_SID:uint64 aka SID const

16.2.3. Enumerations

AudioChannelState
Values:
  • stopped = 0 - Channel has finished playing.

  • stopping = 1 - Channel is fading out and will stop.

  • playing = 2 - Channel is actively playing audio.

  • paused = 3 - Channel is paused.

  • starting = 4 - Channel has been created but has not started playing yet.

ReverbPreset

enum ReverbPreset

16.2.4. Structures

AudioChannelStatus
Fields:
  • state : AudioChannelState - Current playback state.

  • playback_position : uint64 - Current playback position in PCM frames.

  • consumed_position : uint64 - Frames of actual audio consumed (excludes silence padding).

  • stream_queued_frames : uint64 - Number of PCM frames currently buffered for stream playback.

  • stream_underrun_frames : uint64 - Cumulative PCM frames requested after the stream queue ran dry.

  • stream_underruns : uint64 - Number of stream reads that could not fill the requested output.

  • stream_que_length : int - Number of pending PCM chunks in the stream queue.

PlaybackBufferStats

Threaded browser audio-device counters, timings and buffering state; unavailable fields are zero.

Fields:
  • callbacks : uint64 - AudioWorklet callback count.

  • underrun_frames : uint64 - Frames requested while PCM was unavailable.

  • underruns : uint64 - Callbacks that entered recovery after a ring read ran short.

  • recovery_frames : uint64 - Output frames held in recovery while the PCM ring refills.

  • recoveries : uint64 - Transitions from unavailable PCM back to playback.

  • refills : uint64 - Producer refill count.

  • wait_timeouts : uint64 - Producer waits that timed out.

  • max_mix_us : uint64 - Largest producer mix duration in microseconds.

  • max_wake_us : uint64 - Largest producer wake delay in microseconds.

  • max_callback_gap_us : uint64 - Largest interval between device callbacks in microseconds.

  • queued_frames : uint64 - Queued PCM frames sampled at the start of the last device callback.

  • capacity_frames : uint64 - PCM ring capacity in frames.

AudioSystemStats
Fields:
  • callbacks : uint64 - Number of audio callbacks observed since the current stats-box registration began.

  • max_mix_ms : double - Longest mixer execution time observed during the current registration, in milliseconds.

  • max_callback_gap_ms : double - Longest interval between audio callbacks during the current registration, in milliseconds; focus suspension can make this large.

  • utilization_pct : float - Mixer CPU utilization over the last ~1 second, in percent (0..100+).

  • hrtf_count : int - Number of channels currently routed through HRTF.

  • total_3d : int - Total active is3D channels (denominator of the HRTF/simulated split).

Attenuation

struct Attenuation

16.2.5. Audio system lifecycle

audio_system_create(): AudioSystemChannels

Low-level: creates the audio system. Prefer with_audio_system. Applies audio_user_args to the user args (after – interpreted, argv[1..] as a standalone exe - get_user_args picks).

audio_system_finalize(s: Stream?&; next_sid: Atomic64? )

Low-level: shuts down the audio system. A null stream in the caller’s copy - a reload zeroed it, or init never reached audio_system_create - shuts down whatever the module holds, so nothing stays up past the real shutdown.

Arguments:
audio_system_release_context()

Release the mixer context reference. Commands buffered in the stream are drained on the mixer context.

audio_user_args(args: array<string> ): tuple<null_device:bool;volume:float>

The audio knobs every app gets from its user args: –null-audio (run on the null backend, no device) and –volume V (master volume, clamped 0..1). volume < 0 means not given or not a number.

Arguments:
  • args : array<string>

with_audio_system(blk: block<():void> )

Initializes the audio system, runs the block, then shuts down. All audio API calls must happen inside this block.

Arguments:
  • blk : block<void>

16.2.6. Sound playback

play_3d_sound_from_file(filename: string; position: float3; attenuation: Attenuation; rate: int; channels: int; sid: SID = INVALID_SID; loop: bool = false ): uint64

plays 3D sound from file. If sid is INVALID_SID, a new SID is generated. note - this function is blocking for the duration of the decoder creation

Arguments:
  • filename : string

  • position : float3

  • attenuation : Attenuation

  • rate : int

  • channels : int

  • sid : SID

  • loop : bool

play_3d_sound_from_pcm(position: float3; attenuation: Attenuation; rate: int; channels: int; samples: array<float>; sid: SID = INVALID_SID ): uint64

plays 3D sound from PCM data. If sid is INVALID_SID, a new SID is generated.

Arguments:
  • position : float3

  • attenuation : Attenuation

  • rate : int

  • channels : int

  • samples : array<float>

  • sid : SID

play_3d_sound_from_pcm_stream(position: float3; attenuation: Attenuation; rate: int; channels: int; sid: SID = INVALID_SID ): uint64

Create a 3D PCM streaming channel. Feed it samples with append_to_pcm. If sid is INVALID_SID, a new SID is generated.

Arguments:
  • position : float3

  • attenuation : Attenuation

  • rate : int

  • channels : int

  • sid : SID

play_3d_sound_loop_from_pcm(position: float3; attenuation: Attenuation; rate: int; channels: int; samples: array<float>; sid: SID = INVALID_SID ): uint64

plays 3D looping sound from PCM data. If sid is INVALID_SID, a new SID is generated.

Arguments:
  • position : float3

  • attenuation : Attenuation

  • rate : int

  • channels : int

  • samples : array<float>

  • sid : SID

play_sound_from_file(filename: string; rate: int; channels: int; sid: SID = INVALID_SID; loop: bool = false ): uint64

plays sound from file. If sid is INVALID_SID, a new SID is generated. note - this function is blocking for the duration of the decoder creation

Arguments:
  • filename : string

  • rate : int

  • channels : int

  • sid : SID

  • loop : bool

play_sound_from_pcm(rate: int; channels: int; samples: array<float>; sid: SID = INVALID_SID ): uint64

plays sound from PCM data. If sid is INVALID_SID, a new SID is generated.

Arguments:
  • rate : int

  • channels : int

  • samples : array<float>

  • sid : SID

play_sound_from_pcm_stream(rate: int; channels: int; sid: SID = INVALID_SID ): uint64

Create a PCM streaming channel. Feed it samples with append_to_pcm. If sid is INVALID_SID, a new SID is generated.

Arguments:
  • rate : int

  • channels : int

  • sid : SID

play_sound_loop_from_pcm(rate: int; channels: int; samples: array<float>; sid: SID = INVALID_SID ): uint64

plays looping sound from PCM data. If sid is INVALID_SID, a new SID is generated.

Arguments:
  • rate : int

  • channels : int

  • samples : array<float>

  • sid : SID

16.2.7. Sound control

set_global_pause(pause: bool )

set global pause of sounds

Arguments:
  • pause : bool

set_global_pitch(pitch: float )

set global pitch of sounds

Arguments:
  • pitch : float

set_global_volume(volume: float )

Set global master volume (multiplier for all currently-playing sounds).

Arguments:
  • volume : float

set_ignore_global_volume(sid: SID; value: bool )

Make a specific channel ignore the global master volume (used by editor preview so muting the game’s master volume does not silence the asset preview).

Arguments:
  • sid : SID

  • value : bool

set_pan(sid: SID; pan: float ): uint64

set pan of sound

Arguments:
  • sid : SID

  • pan : float

set_pause(sid: SID; paused: bool; time: float = 0.002f ): uint64

pause or unpause sound; time is the fade duration in seconds (default ~2ms to avoid clicks)

Arguments:
  • sid : SID

  • paused : bool

  • time : float

set_pitch(sid: SID; pitch: float ): uint64

set pitch of sound

Arguments:
  • sid : SID

  • pitch : float

set_playback_position(sid: SID; position: uint64 ): uint64

set playback position for sound (in frames)

Arguments:
  • sid : SID

  • position : uint64

set_volume(sid: SID; volume: float; time: float = 0.002f ): uint64

set volume of sound

Arguments:
  • sid : SID

  • volume : float

  • time : float

stop(sid: SID; time: float = 0f ): uint64

stop sound

Arguments:
  • sid : SID

  • time : float

16.2.8. 3D audio

set_head_position(pos: float3; dir: float3; vel: float3 = float3(0f,0f,0f) )

set head position for 3D sound

Arguments:
  • pos : float3

  • dir : float3

  • vel : float3

set_position(sid: SID; pos: float3; dir: float3 = float3(0f,0f,0f) ): uint64

set sound position for 3D sound

Arguments:
  • sid : SID

  • pos : float3

  • dir : float3

16.2.9. HRTF

hrtf_budget_classify(rank: int; budget: int; wasHrtf: bool ): bool

Decide whether a 3D channel at the given closest-to-head rank should run HRTF or simulated 3D, given the current budget and whether the channel was HRTF on the previous frame. Applies a sticky-rank margin to prevent flapping when two channels swap rank between frames, while clamping to 0 when budget is 0 so “all simulated” actually clears in-flight HRTF channels.

Arguments:
  • rank : int

  • budget : int

  • wasHrtf : bool

set_hrtf_budget(n: int )

Set the maximum number of 3D channels routed through HRTF each frame; the rest run simulated 3D (constant-power pan + distance attenuation, no convolution). Use 0 for all-simulated, or a large value (e.g. 999) for all-HRTF. Default is 32. The closest-to-head channels win the HRTF slots.

Arguments:
  • n : int

16.2.10. Reverb

set_reverb(sid: SID; reverb: I3DL2ReverbProperties ): uint64

set reverb for sound

Arguments:
set_reverb_preset(sid: SID; preset: ReverbPreset ): uint64

set reverb from preset for sound

Arguments:

16.2.11. Chorus

set_chorus(sid: SID; config: ma_chorus_config ): uint64

set chorus effect for sound

Arguments:
set_chorus_default(sid: SID ): uint64

set chorus effect with default settings for sound

Arguments:

16.2.12. Attenuation

compute_attenuation(attn: Attenuation; d: float ): float

compute attenuation given distance

Arguments:
default_attenuation(): Attenuation

default attenuation 1 / (d + 1)

inverse_distance_attenuation(dmin: float ): Attenuation

DEFAULT ATTENUATION MODEL fades with inverse distance, i.e. dmin / (d + dmin)

Arguments:
  • dmin : float

inverse_square_attenuation(dmin: float ): Attenuation

fades with inverse square distance, i.e. dmin^2 / (d^2 + dmin^2)

Arguments:
  • dmin : float

linear_attenuation(dmax: float ): Attenuation

fades linearly with distance, i.e 1 - d / dmax

Arguments:
  • dmax : float

quadratic_attenuation(dmax: float ): Attenuation

fades quadratically with distance, i.e 1 - d^2 / dmax^2

Arguments:
  • dmax : float

16.2.13. Status monitoring

clear_status(status: SeqBox? )

Drop the stored snapshot; the box reads back empty until the next publish.

Arguments:
get_playback_diagnostics(): PlaybackBufferStats

Samples threaded browser device counters; unavailable counters are zero. Values are read independently and do not form an atomic transaction.

set_audio_memory_box(box: SeqBox? )

Publish ContextMemory once per second, independently of the optional stats box.

Arguments:
set_audio_stats_box(box: SeqBox? )

Register a box to receive periodic AudioSystemStats updates from the audio thread. Each non-null registration starts a fresh measurement session. The audio thread publishes one snapshot per ~1-second window; read it on demand with box |> read() $(s : AudioSystemStats) { ... }. Reading consumes nothing, so the same box serves any number of reads. Pass null to stop.

Arguments:
set_status_update(sid: SID; status: SeqBox? ): uint64

Publish this sound’s status into status until unset_status_update. The box is seeded with starting here, on the calling thread, so it reads sensibly the instant this returns. Reading it never makes the mixer wait, and releasing it needs no ordering with the audio thread — see seq_box_release.

Arguments:
unset_status_update(sid: SID ): uint64

unset status for sound

Arguments:

16.2.14. Command batching

batch(cb: block<():void> )

Execute a block of audio commands as a single atomic batch.

Arguments:
  • cb : block<void>

begin_batch()

Warning

use batch(cb) instead

Deprecated. Use batch() { ... } instead.

end_batch()

Warning

use batch(cb) instead

Deprecated. Use batch() { ... } instead.

16.2.15. PCM stream

append_box_to_pcm(sid: SID; box: LockBox?; samples: array<float> ): uint64

append samples from lock box to PCM stream. Box is grabbed and released on audio thread. samples buffer must outlive the grab — caller keeps it alive until box.isReady.

Arguments:
append_to_pcm(sid: SID; samples: array<float> ): uint64

append samples to PCM stream

Arguments:
  • sid : SID

  • samples : array<float>

16.2.16. Decoding

decode_audio(data: array<uint8>|array<uint8>#; channels: int&; rate: int& ): array<float>

Decode an audio file (MP3, WAV, FLAC, Vorbis) from raw bytes to PCM float samples. Returns interleaved sample data; sets channels and rate.

Arguments:
  • data : option<array<uint8>| array<uint8>#>

  • channels : int&

  • rate : int&

16.2.17. Sound ID

generate_sound_sid(): uint64

generate unique ID for sound

16.2.18. Internal stream management

adopt_audio_thread_command_stream(ch: void? )

Warning

This is unsafe operation.

A reload’s restore: the reference the old context’s global held on the stream passes to this context’s global, none is taken - the old context is gone without a release, so set_audio_thread_command_stream here would leave one reference per reload behind and the real finalize would refuse to delete the stream. Its caller is the restore of a fresh context, whose global holds nothing yet.

Arguments:
  • ch : void?

get_audio_command_stream(): void?

def get_audio_command_stream () : void?

get_sound_sid(): void?

def get_sound_sid () : void?

set_audio_thread_command_stream(ch: void? )

Warning

This is unsafe operation.

def set_audio_thread_command_stream (ch: void?)

Arguments:
  • ch : void?

set_sound_sid(next_sid: void? )

def set_sound_sid (next_sid: void?)

Arguments:
  • next_sid : void?