Skip to content

create.audio

Sound: Sound (the asset), Audio (the playback device) and Voice (one playback).

Sound

struct Sound

Decoded samples, the asset, not a playing voice: 16-bit integers, channels interleaved, whatever the file held.

Decoding happens once, at load; Audio.play reads the samples without touching the file again. Copying one is cheap, like copying an Image: the copies share the samples, and so does every voice playing it.

Implements Copyable, Deinitable, ImplicitlyCopyable, Movable.

channels

def channels(self) -> Int

How many channels the samples interleave: 1 mono, 2 stereo.

sample_rate

def sample_rate(self) -> Int

Samples per second, per channel.

frame_count

def frame_count(self) -> Int

How many frames the sound holds: one sample of every channel.

duration

def duration(self) -> Float64

How long the sound plays, in seconds.

sample

def sample(self, frame: Int, channel: Int = Int(0)) -> Float64

The sample of channel in frame, from -1.0 to 1.0, as from_samples takes them. Outside the sound it is 0.0, silence.

load

@staticmethod
def load(path: String) raises -> Self

Load a WAV, OGG, FLAC, or MP3 file. Dispatches on the file's magic bytes, not its extension: RIFF (WAV) decodes via the zero-dependency SDL_LoadWAV path; everything else goes through libsndfile. Raises, naming path, when the file can't be read or holds no samples.

A relative path is resolved against the directory of the calling source file, not the working directory, as Image.load's is.

from_samples

@staticmethod
def from_samples(
    samples: List[Float64],
    channels: Int = Int(1),
    sample_rate: Int = Int(44100),
) raises -> Self

A sound of samples, from -1.0 to 1.0, such as a synthesized waveform. With more than one channel they interleave, a sample of each channel to a frame: left, right, left, right for stereo. A sample outside the range is clipped to it.

Raises unless channels and sample_rate are positive and samples is whole frames.

Audio

struct Audio

Program-owned playback device. Construct once, hold as a Program field, call play from update. Where no audio device can be opened, it plays silently rather than raising.

It needs nothing each frame: a looping voice is fed on SDL's audio thread, as the device asks, and a one-shot voice reads as stale once it has played to its end, its slot freed by the next play.

Implements Deinitable, Movable.

Constructors

@staticmethod
def __init__(out self) raises

__deinit__

def __deinit__(deinit self)

volume

def volume(self) -> Float64

The volume every voice plays at, 1.0 unless set.

def volume(mut self, volume: Float64) raises

Set the volume every voice plays at, 0.0 silent and 1.0 as recorded; above 1.0 amplifies, and below 0.0 is silent too. Applies at once, to the voices already playing as well as later ones; each voice's own volume(voice, ...) scales it.

def volume(self, voice: Voice) -> Float64

voice's own volume, 1.0 unless set; 0.0 once it is stale.

def volume(mut self, voice: Voice, volume: Float64) raises

Set voice's own volume, which volume() scales: a voice at 0.5 under a volume of 0.5 plays at a quarter. Below 0.0 is silent, as for volume(). No-op if stale.

play

def play(
    mut self,
    sound: Sound,
    volume: Float64 = 1,
    speed: Float64 = 1,
) raises -> Voice

Play sound once, as a new Voice at its own volume and speed; it is stale once the sound ends.

loop

def loop(
    mut self,
    sound: Sound,
    volume: Float64 = 1,
    speed: Float64 = 1,
) raises -> Voice

Play sound over and over until stopped, as a new Voice at its own volume and speed, as Animator.loop and Tween.loop repeat. The voice is fed as the device asks, from a copy of sound that shares its samples.

stop

def stop(mut self, voice: Voice) raises

Stop and release voice. No-op if it is already stale.

stop_all

def stop_all(mut self) raises

Stop and release every voice, playing or paused.

pause_all

def pause_all(mut self) raises

Pause every playing voice, as for a pause screen. Voices played afterwards play as usual, so the screen can have sounds of its own.

resume_all

def resume_all(mut self) raises

Resume every paused voice, whether pause_all or pause held it.

pause

def pause(mut self, voice: Voice) raises

Hold voice where it is; resume continues it.

speed

def speed(self, voice: Voice) -> Float64

voice's playback speed, 1.0 unless set; 0.0 once it is stale.

def speed(mut self, voice: Voice, speed: Float64) raises

Set voice's playback speed: 2.0 plays it twice as fast and an octave higher, 0.5 half as fast and an octave lower, as a record sped up or slowed down. Clamped to 0.01 to 100.0. No-op if stale.

resume

def resume(mut self, voice: Voice) raises

Continue a paused voice from where it was held.

is_playing

def is_playing(self, voice: Voice) -> Bool

Whether voice is sounding: false once paused or stale.

is_paused

def is_paused(self, voice: Voice) -> Bool

Whether voice is held by pause, waiting for resume. A voice neither playing nor paused is stale: it has ended or been stopped.

Voice

struct Voice

One playback of a Sound, as audio.play and audio.loop return it: the handle stop, pause, resume, volume, speed, is_playing and is_paused take.

A Sound can play as several voices at once. A voice that has ended or been stopped is stale: every call on it does nothing, even after its slot plays another sound. Voice.NONE is no voice, for a field before anything plays. A handle, like Sound, so not printable.

Implements Copyable, Deinitable, Equatable, ImplicitlyCopyable, Movable.

Constants

  • NONE = Voice(_id=Int(0))

__eq__

def __eq__(self, other: Self) -> Bool

__ne__

def __ne__(self, other: Self) -> Bool