DocsAPI reference

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 #

mojo
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

  • null null() -> SoundHandle
    The invalid handle (index -1); it converts to False.

struct Attenuation #

mojo
struct Attenuation(Equatable, ImplicitlyCopyable, Movable)

Distance attenuation model of a spatial sound, mapped to miniaudio's models by AudioEngine.set_attenuation.

Fields:

  • value: UInt8

  • none none() -> Attenuation
    No distance attenuation.

  • inverse inverse() -> Attenuation
    miniaudio's inverse-distance model; the SoundDesc default.

  • linear linear() -> Attenuation
    miniaudio's linear model.

  • exponential exponential() -> Attenuation
    miniaudio's exponential model.

struct SoundDesc #

mojo
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 #

mojo
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 last take_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_bus create_bus(mut self, name: String, parent: Int = 0) raises -> Int
    A mixing bus under parent (0 = master, -1 = the engine endpoint). Returns its index; destroy it with destroy_bus. Raises when parent does not exist (or was destroyed) or miniaudio fails to create the group.

  • destroy_bus destroy_bus(mut self, bus: Int) raises
    Destroys a bus made with create_bus; its index stays invalid (indices are not reused) and live_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_bus find_bus(self, name: String) -> Int
    Index of the first live bus called name (the master bus is 0), or -1 when there is none.

  • set_bus_volume set_bus_volume(self, bus: Int, volume: Float32) raises
    Sets the linear volume of bus bus (1 is unity), which scales every sound and bus routed through it. Raises when the bus does not exist.

  • bus_volume bus_volume(self, bus: Int) raises -> Float32
    Linear volume of bus bus. Raises when the bus does not exist.

  • set_master_volume set_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_buses live_buses(self) -> Int
    Buses created with create_bus and not yet destroyed with destroy_bus (the master bus is the engine's own); should be zero before the engine is destroyed.

  • load load(mut self, desc: SoundDesc) raises -> SoundHandle
    Creates a sound from a file (WAV, FLAC, MP3, Vorbis). It starts stopped.

  • play_one_shot play_one_shot( mut self, var desc: SoundDesc, position: Vec3 ) raises -> SoundHandle
    Loads, positions and starts a sound that is released when it ends.

  • release release(mut self, handle: SoundHandle) raises
    Destroys the sound and invalidates handle and its copies; the slot is reused with a new generation. Raises on a stale handle, so do not release a one-shot that update already released.

  • is_valid is_valid(self, handle: SoundHandle) -> Bool
    Whether handle refers to a live sound (in range, same generation, not released). Never raises.

  • live_sounds live_sounds(self) -> Int
    Number of sounds not yet released, one-shots included; should be zero before the engine is destroyed.

  • play play(self, handle: SoundHandle) raises
    Starts the sound. Raises on a stale handle or when miniaudio fails to start it.

  • stop stop(self, handle: SoundHandle) raises
    Stops the sound without releasing it. Raises on a stale handle; miniaudio's result code is ignored.

  • is_playing is_playing(self, handle: SoundHandle) raises -> Bool
    Whether the sound is playing. Raises on a stale handle.

  • at_end at_end(self, handle: SoundHandle) raises -> Bool
    Whether the sound has reached the end of its data. Raises on a stale handle.

  • seek seek(self, handle: SoundHandle, frame: Int) raises
    Moves the playback cursor to PCM frame frame. Raises on a stale handle; miniaudio's result code is ignored.

  • set_volume set_volume(self, handle: SoundHandle, volume: Float32) raises
    Sets the sound's linear volume (1 is unity). Raises on a stale handle.

  • set_pitch set_pitch(self, handle: SoundHandle, pitch: Float32) raises
    Sets the sound's pitch multiplier (1 is the original pitch). Raises on a stale handle.

  • set_pan set_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_looping set_looping(self, handle: SoundHandle, looping: Bool) raises
    Turns looping on or off. Raises on a stale handle.

  • fade fade( self, handle: SoundHandle, from_volume: Float32, to_volume: Float32, milliseconds: Int, ) raises
    Fades the sound's volume from from_volume to to_volume over milliseconds. Raises on a stale handle.

  • set_position set_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_velocity set_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_spatial set_spatial(self, handle: SoundHandle, enabled: Bool) raises
    Turns 3D spatialisation of the sound on or off. Raises on a stale handle.

  • set_attenuation set_attenuation( self, handle: SoundHandle, model: Attenuation, min_distance: Float32, max_distance: Float32, rolloff: Float32, ) raises
    Sets the distance attenuation: the model, min_distance and max_distance in metres and the rolloff factor. An unrecognised model value falls back to inverse. Raises on a stale handle.

  • set_listener set_listener( self, position: Vec3, forward: Vec3, up: Vec3 = Vec3.unit_y(), velocity: Vec3 = Vec3.zero(), )
    Places miniaudio's listener 0: position in metres, the forward direction it faces, the world up and its velocity in metres per second (Doppler). The engine convention is -Z forward and +Y up; sync_audio calls this from the AudioListener entity.

  • update update(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_ended take_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_count error_count(self) -> Int
    Number of error-level records in diagnostics (miniaudio log messages collected by update).

  • read_frames read_frames(self, frames: Int) raises -> List[Float32]
    Headless engines: mixes frames interleaved 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 of AudioSource.
  • comptime AUDIO_LISTENER_COMPONENT_ID = 11 — ECS component id of AudioListener.

struct AudioSource #

mojo
struct AudioSource(Component)

A spatial sound that follows its entity. velocity feeds the Doppler effect.

Fields:

  • sound: SoundHandle

  • velocity: Vec3

  • component_id component_id() -> Int

struct AudioListener #

mojo
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_id component_id() -> Int

def sync_audio #

mojo
def sync_audio(world: World, audio: AudioEngine) raises -> Int

Pushes entity transforms to the sounds and the listener. Returns the number of sources positioned; stale handles are skipped.

View as MarkdownSource: docs/api/audio.md