cinder.audio
cinder.audio #
Source: cinder/audio/__init__.mojo
Audio over miniaudio: buses, decoded and streamed sounds, one-shots, 3D spatialisation, a listener, and the ECS bridge that follows entities and the camera.
cinder.audio.engine #
Source: cinder/audio/engine.mojo
Audio over miniaudio: buses, decoded and streamed sounds, one-shots, 3D spatialisation and a listener. The engine can run headless (no device) for tests and servers; frames are then pulled with read_frames. Sounds live in the shim (miniaudio structs are opaque to Mojo) and are tracked here with generational handles. Release sounds with release and destroy the buses you created with destroy_bus; live_sounds() and live_buses() must be zero before the engine is destroyed (the destructor still frees whatever is left). Sound-end and log callbacks post to the shim queue and are drained by update.
struct SoundHandle #
struct SoundHandle(Equatable, ImplicitlyCopyable, Movable)Generational handle to a sound owned by AudioEngine: a slot index and that slot's generation. It goes stale once the sound is released (one-shots are released by AudioEngine.update without any call of yours); AudioEngine.is_valid tells, and every method that takes a stale handle raises.
Fields:
-
index: Int -
generation: Int -
nullnull() -> SoundHandle
The invalid handle (index -1); it converts to False.
struct Attenuation #
struct Attenuation(Equatable, ImplicitlyCopyable, Movable)Distance attenuation model of a spatial sound, mapped to miniaudio's models by AudioEngine.set_attenuation.
Fields:
-
value: UInt8 -
nonenone() -> Attenuation
No distance attenuation. -
inverseinverse() -> Attenuation
miniaudio's inverse-distance model; theSoundDescdefault. -
linearlinear() -> Attenuation
miniaudio's linear model. -
exponentialexponential() -> Attenuation
miniaudio's exponential model.
struct SoundDesc #
struct SoundDesc(Copyable, Movable)How AudioEngine.load creates a sound. The constructor takes the file path, bus index, streamed, looping and spatial; the other fields keep their defaults until set on the value: volume 1, pitch 1, inverse attenuation with min_distance 1 m, max_distance 100 m and rolloff 1, not a one-shot. The attenuation settings apply only when spatial is set.
Fields:
-
path: String -
bus: Int -
streamed: Bool — Decode while playing (music); otherwise the whole file is decoded up front. -
looping: Bool -
spatial: Bool -
volume: Float32 -
pitch: Float32 -
attenuation: Attenuation -
min_distance: Float32 -
max_distance: Float32 -
rolloff: Float32 -
one_shot: Bool — Released automatically when it ends. -
__init____init__( out self, path: String, bus: Int = 0, streamed: Bool = False, looping: Bool = False, spatial: Bool = True, )
struct AudioEngine #
struct AudioEngine(Movable)Owns the miniaudio engine, its mixing buses and every loaded sound. Bus 0 is the master bus and lives as long as the engine; buses made with create_bus are destroyed with destroy_bus. Sounds are addressed by SoundHandle and freed with release (one-shots by update); the destructor frees whatever is left, but live_sounds() and live_buses() should be zero first. The NativePtr library must outlive the engine. Call every method from the main thread: miniaudio's threads only post events, which update drains. The constructor raises when the event queue or the miniaudio engine cannot be created (for example no audio device without headless).
Fields:
-
lib: NativePtr -
queue: Optional[Pointer[CnEventQueue, MutUntrackedOrigin]] -
engine: Optional[Pointer[ma_engine, MutUntrackedOrigin]] -
buses: List[Optional[Pointer[ma_sound_group, MutUntrackedOrigin]]] — One entry per bus index ever created; a destroyed bus leaves an empty entry so the other indices stay stable (indices are not reused). -
bus_names: List[String] -
bus_parents: List[Int] — Parent bus index of each bus (-1 for the master bus on the engine endpoint). -
slots: List[_Slot] -
free_slots: List[Int] -
diagnostics: List[LogRecord] -
ended: List[SoundHandle] — Sounds that finished since the lasttake_ended. -
headless: Bool -
sample_rate: Int -
channels: Int -
__init____init__( out self, lib: NativePtr, headless: Bool = False, sample_rate: Int = 48000, channels: Int = 2, ) raises -
create_buscreate_bus(mut self, name: String, parent: Int = 0) raises -> Int
A mixing bus underparent(0 = master, -1 = the engine endpoint). Returns its index; destroy it withdestroy_bus. Raises whenparentdoes not exist (or was destroyed) or miniaudio fails to create the group. -
destroy_busdestroy_bus(mut self, bus: Int) raises
Destroys a bus made withcreate_bus; its index stays invalid (indices are not reused) andlive_buses()drops by one. Raises for the master bus (0, owned by the engine), a bus that does not exist or was already destroyed, and a bus that still has sounds or live child buses routed into it: release or destroy those first. -
find_busfind_bus(self, name: String) -> Int
Index of the first live bus calledname(the master bus is 0), or -1 when there is none. -
set_bus_volumeset_bus_volume(self, bus: Int, volume: Float32) raises
Sets the linear volume of busbus(1 is unity), which scales every sound and bus routed through it. Raises when the bus does not exist. -
bus_volumebus_volume(self, bus: Int) raises -> Float32
Linear volume of busbus. Raises when the bus does not exist. -
set_master_volumeset_master_volume(self, volume: Float32)
Sets the engine's own output volume (linear), separate from the master bus volume; miniaudio's result code is ignored. -
live_buseslive_buses(self) -> Int
Buses created withcreate_busand not yet destroyed withdestroy_bus(the master bus is the engine's own); should be zero before the engine is destroyed. -
loadload(mut self, desc: SoundDesc) raises -> SoundHandle
Creates a sound from a file (WAV, FLAC, MP3, Vorbis). It starts stopped. -
play_one_shotplay_one_shot( mut self, var desc: SoundDesc, position: Vec3 ) raises -> SoundHandle
Loads, positions and starts a sound that is released when it ends. -
releaserelease(mut self, handle: SoundHandle) raises
Destroys the sound and invalidateshandleand its copies; the slot is reused with a new generation. Raises on a stale handle, so do not release a one-shot thatupdatealready released. -
is_validis_valid(self, handle: SoundHandle) -> Bool
Whetherhandlerefers to a live sound (in range, same generation, not released). Never raises. -
live_soundslive_sounds(self) -> Int
Number of sounds not yet released, one-shots included; should be zero before the engine is destroyed. -
playplay(self, handle: SoundHandle) raises
Starts the sound. Raises on a stale handle or when miniaudio fails to start it. -
stopstop(self, handle: SoundHandle) raises
Stops the sound without releasing it. Raises on a stale handle; miniaudio's result code is ignored. -
is_playingis_playing(self, handle: SoundHandle) raises -> Bool
Whether the sound is playing. Raises on a stale handle. -
at_endat_end(self, handle: SoundHandle) raises -> Bool
Whether the sound has reached the end of its data. Raises on a stale handle. -
seekseek(self, handle: SoundHandle, frame: Int) raises
Moves the playback cursor to PCM frameframe. Raises on a stale handle; miniaudio's result code is ignored. -
set_volumeset_volume(self, handle: SoundHandle, volume: Float32) raises
Sets the sound's linear volume (1 is unity). Raises on a stale handle. -
set_pitchset_pitch(self, handle: SoundHandle, pitch: Float32) raises
Sets the sound's pitch multiplier (1 is the original pitch). Raises on a stale handle. -
set_panset_pan(self, handle: SoundHandle, pan: Float32) raises
Sets the sound's stereo pan (-1 left, 0 centre, 1 right); the only positioning control of a non-spatial sound. Raises on a stale handle. -
set_loopingset_looping(self, handle: SoundHandle, looping: Bool) raises
Turns looping on or off. Raises on a stale handle. -
fadefade( self, handle: SoundHandle, from_volume: Float32, to_volume: Float32, milliseconds: Int, ) raises
Fades the sound's volume fromfrom_volumetoto_volumeovermilliseconds. Raises on a stale handle. -
set_positionset_position(self, handle: SoundHandle, p: Vec3) raises
Sets the sound's world position in metres (used while spatialisation is on). Raises on a stale handle. -
set_velocityset_velocity(self, handle: SoundHandle, v: Vec3) raises
Sets the sound's velocity in metres per second, used for the Doppler effect. Raises on a stale handle. -
set_spatialset_spatial(self, handle: SoundHandle, enabled: Bool) raises
Turns 3D spatialisation of the sound on or off. Raises on a stale handle. -
set_attenuationset_attenuation( self, handle: SoundHandle, model: Attenuation, min_distance: Float32, max_distance: Float32, rolloff: Float32, ) raises
Sets the distance attenuation: themodel,min_distanceandmax_distancein metres and therollofffactor. An unrecognised model value falls back to inverse. Raises on a stale handle. -
set_listenerset_listener( self, position: Vec3, forward: Vec3, up: Vec3 = Vec3.unit_y(), velocity: Vec3 = Vec3.zero(), )
Places miniaudio's listener 0:positionin metres, theforwarddirection it faces, the worldupand itsvelocityin metres per second (Doppler). The engine convention is -Z forward and +Y up;sync_audiocalls this from theAudioListenerentity. -
updateupdate(mut self) raises -> Int
Drains the shim queue: log messages become diagnostics, finished sounds are recorded (and one-shots released). Returns the number of sounds that ended. -
take_endedtake_ended(mut self) -> List[SoundHandle]
Returns the handles of sounds that ended since the last call and clears the list. Handles of one-shots are already stale when they are returned. -
error_counterror_count(self) -> Int
Number of error-level records indiagnostics(miniaudio log messages collected byupdate). -
read_framesread_frames(self, frames: Int) raises -> List[Float32]
Headless engines: mixesframesinterleaved float frames (tests, offline rendering).
cinder.audio.sync #
Source: cinder/audio/sync.mojo
ECS <-> audio: AudioSource entities position their sounds, AudioListener places the listener (attach it to the camera entity so the listener follows the camera).
comptime AUDIO_SOURCE_COMPONENT_ID = 10— ECS component id ofAudioSource.comptime AUDIO_LISTENER_COMPONENT_ID = 11— ECS component id ofAudioListener.
struct AudioSource #
struct AudioSource(Component)A spatial sound that follows its entity. velocity feeds the Doppler effect.
Fields:
-
sound: SoundHandle -
velocity: Vec3 -
component_idcomponent_id() -> Int
struct AudioListener #
struct AudioListener(Component)Marks the entity whose world transform drives the listener (position, -Z forward, +Y up). With several, the first one found wins.
Fields:
-
velocity: Vec3 -
component_idcomponent_id() -> Int
def sync_audio #
def sync_audio(world: World, audio: AudioEngine) raises -> IntPushes entity transforms to the sounds and the listener. Returns the number of sources positioned; stale handles are skipped.