Skip to main content

AudioEngine

Struct AudioEngine 

Source
pub struct AudioEngine { /* private fields */ }
Expand description

A mixing audio player backed by a platform output device.

The device is opened lazily, on the first call that actually makes sound, so an app that installs the engine but never plays anything costs no audio thread and no battery. Loading clips is not such a call: a clip load is a queue push, and the queue exists from construction, so a title screen can have its whole sound bank resident with the output device still shut.

The device does not stay open either. When nothing has sounded for IDLE_GRACE_SECONDS the mixer gives the stream up and the next play starts it again, so a silent screen costs nothing however it was reached.

Implementations§

Source§

impl AudioEngine

Source

pub fn new() -> AudioEngine

Creates an engine that opens the platform output device on first use.

Source

pub fn with_sink_opener( open_sink: Box<dyn Fn(MixerSeed) -> Result<Box<dyn AudioSink>, AudioError>>, ) -> AudioEngine

Creates an engine over a caller-supplied device opener. The platform backends and the crate’s own tests both go through this.

Source

pub fn take_last_error(&self) -> Option<AudioError>

The most recent failure, if the device refused to open or a call was rejected. Cleared by reading it.

Source

pub fn leaked_clips(&self) -> u32

How many clips the mixer could not hand back for dropping. Any value above zero means the app stopped calling the engine while clips were being replaced; it is reported rather than hidden.

Source

pub fn underruns(&self) -> u32

How many times the device asked for a buffer the mixer could not fill.

Source

pub fn is_running(&self) -> bool

Whether the output device is open.

Open is not the same as running: a device that has been open for a while spends most of a quiet screen stopped. See is_streaming.

Source

pub fn is_streaming(&self) -> bool

Whether the output stream is live rather than given up as idle.

false with is_running true is the steady state of a silent screen: the device object and every loaded clip are still there, the stream is not, and the next play starts it again. A stream paused by suspend still counts as live — the app took it away, not the mixer, and it comes back on resume.

Trait Implementations§

Source§

impl AudioPlayer for AudioEngine

Source§

fn load_clip(&self, clip: AudioClip) -> Result<SoundId, AudioError>

Takes a clip table slot and queues the clip for the mixer.

This deliberately does not open the output device. Loading a bank of cues is what an app does on the way into a screen, long before it plays anything, and opening the device there was costing a silent title screen an audio thread and an always-on DSP rail for as long as it was on display. The command ring outlives every mixer, so the load waits in it and is drained by the first mixer to start.

The consequence is a narrower error contract than this used to have. The only failure it can still report is the one it can determine here, AudioError::ClipTableFull; a device that is missing or refuses to open is no longer a load-time error, because finding that out means opening it. Callers that need to know ask is_available, and the failure itself is available from take_last_error once a play has tried. That also makes this agree with NoopAudioPlayer, which hands out real SoundIds on a machine with no audio at all so app logic does not have to branch.

Source§

fn unload(&self, id: SoundId)

Releases a clip. Voices already playing it are stopped.
Source§

fn play(&self, id: SoundId, params: PlaybackParams)

Starts a one-shot voice. Re-triggering the same clip layers a new voice rather than restarting the old one.
Source§

fn play_loop(&self, id: SoundId, params: PlaybackParams) -> VoiceId

Starts a looping voice and returns its handle.
Source§

fn stop(&self, id: SoundId)

Stops every voice playing id.
Source§

fn stop_voice(&self, voice: VoiceId)

Stops one voice.
Source§

fn stop_all(&self)

Stops every voice on every bus.
Source§

fn set_voice_params(&self, voice: VoiceId, params: PlaybackParams)

Retunes a voice while it plays — a looping engine note that follows speed, for instance.
Source§

fn set_master_volume(&self, volume: f32)

Sets the gain applied to every bus.
Source§

fn master_volume(&self) -> f32

The current master gain.
Source§

fn set_bus_volume(&self, bus: AudioBus, volume: f32)

Sets one bus’s gain.
Source§

fn bus_volume(&self, bus: AudioBus) -> f32

One bus’s gain.
Source§

fn set_bus_enabled(&self, bus: AudioBus, enabled: bool)

Mutes or unmutes a bus. This is the “sound on” / “music on” toggle; muting leaves voices running so unmuting resumes mid-track.
Source§

fn bus_enabled(&self, bus: AudioBus) -> bool

Whether a bus is audible.
Source§

fn suspend(&self)

Releases the output device without discarding loaded clips — call it when the app goes to the background.
Source§

fn resume(&self)

Re-acquires the output device after suspend.
Source§

fn is_available(&self) -> bool

Whether a real device is behind this handle. The no-op default reports false, so an app can honestly grey out its audio settings.
Source§

fn load(&self, bytes: &[u8]) -> Result<SoundId, AudioError>

Decodes bytes and loads the result. Read more
Source§

impl Default for AudioEngine

Source§

fn default() -> AudioEngine

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.