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_que_length : int - Number of pending PCM chunks in the stream queue.
- AudioSystemStats
- Fields:
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.
- 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:
sid : SID
reverb : I3DL2ReverbProperties
- set_reverb_preset(sid: SID; preset: ReverbPreset ): uint64
set reverb from preset for sound
- Arguments:
sid : SID
preset : ReverbPreset
16.2.11. Chorus
- set_chorus(sid: SID; config: ma_chorus_config ): uint64
set chorus effect for sound
- Arguments:
sid : SID
config : ma_chorus_config
- set_chorus_default(sid: SID ): uint64
set chorus effect with default settings for sound
- Arguments:
sid : SID
16.2.12. Attenuation
- compute_attenuation(attn: Attenuation; d: float ): float
compute attenuation given distance
- Arguments:
attn : Attenuation
d : float
- 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:
status : SeqBox?
- set_audio_stats_box(box: SeqBox? )
Register a box to receive periodic AudioSystemStats updates from the audio thread.
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:
box : SeqBox?
- 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.
- unset_status_update(sid: SID ): uint64
unset status for sound
- Arguments:
sid : SID
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.
- 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
- 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?