Skip to main content

AudioRenderer

Struct AudioRenderer 

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

Mixes a project’s audio tracks into one project-rate block.

Implementations§

Source§

impl AudioRenderer

Source

pub fn new( snapshot: &EngineProject, channels: usize, max_block: usize, ) -> Result<Self, EngineError>

Builds every track and master processor for a project snapshot, and measures every clip’s; a clip’s are built when it is mixed.

§Errors

Returns EngineError::InvalidAudioConfiguration for an unsupported channel count, a zero sample rate, or an oversized block.

Source

pub const fn sample_rate(&self) -> u32

Returns the project sample rate every block uses.

Source

pub const fn channels(&self) -> usize

Returns the channel count of every mixed block.

Source

pub fn track_ids(&self) -> Vec<&TrackId>

Returns the audio tracks this renderer mixes, in bus order.

Source

pub const fn max_block(&self) -> usize

Returns the largest block this renderer accepts.

Source

pub fn channel(&self, index: usize) -> &[f32]

Returns one mixed output channel from the most recent render.

Source

pub fn required_lookahead_samples(&self) -> u32

How far ahead of a block, in samples, the renderer reads its sources.

A lookahead effect (a compressor’s lookahead_ms) delays what passes through it. Rather than delay the mix, the renderer reads each path’s input early by the latency between it and the output, so the output lines up with the timeline. Use Self::audio_needs for source supply: a cold seek also needs recursive-state history, beyond this delay.

Source

pub fn audio_needs( &self, snapshot: &EngineProject, start_sample: i64, frames: usize, ) -> Result<Vec<AudioNeed>, EngineError>

The source intervals rendering frames samples from start_sample reads, for a host to decode first.

They are what Self::render would read, found the way it reads them: the same blocks (on a discontinuity it does not continue across (AudioContinuity), the replay of each stage’s settling history, which stops at timeline zero, then the block), the same clips (heard, on a bus the mix hears, once their stages have begun settling), and the same source window per read, interpolation neighbours included. A host that holds them needs no margin.

Clips reading one source share a need where their intervals overlap or touch; disjoint intervals of one source stay separate needs, so two clips cut from far apart in one source do not ask for everything between them.

§Errors

Returns EngineError::InvalidAudioConfiguration for a negative start, an empty block, one larger than Self::max_block, or a block whose timeline span does not fit in ticks, and an evaluation error when the snapshot cannot be evaluated over a block’s span.

Source

pub const fn required_history_samples(&self) -> i64

Finite state-settling history requested on discontinuities, in samples. This is separate from latency; Self::audio_needs includes the history each clip’s stages replay. It is at most MAX_SETTLING_SECONDS of samples.

Source

pub fn set_continuity(&mut self, continuity: AudioContinuity)

Chooses what Self::render does with a block that does not start where the previous one ended (AudioContinuity); new renderers are AudioContinuity::Exact. Choosing another policy than the current one resets the renderer (Self::reset), so no state mixed under one carries into the other: an exact renderer mixes what a fresh one would from its next block on.

Source

pub const fn continuity(&self) -> AudioContinuity

The policy Self::set_continuity last chose.

Source

pub fn reset(&mut self)

Clears every processor history without changing authored parameters.

Self::render does this itself whenever a block does not continue the previous one. A host calls it only to start fresh at the very position the last block ended, such as an export beginning where preview stopped.

Source

pub fn render( &mut self, snapshot: &EngineProject, start_sample: i64, frames: usize, provider: &dyn AudioBlockProvider, transport: TransportState, ) -> Result<AudioRenderStatus, EngineError>

Mixes frames samples starting at an absolute project-rate sample index.

A block that does not start where the previous one ended, a seek or an export after preview, first resets every processor, so its output is what a fresh renderer would produce and no reverb tail, compressor envelope, or ducking gain carries over from elsewhere on the timeline. That is the default policy, AudioContinuity::Exact; under AudioContinuity::ContinueSmallGaps, which live preview may choose (Self::set_continuity), a block at most Self::max_block samples from where the previous one ended continues instead, and only a longer jump resets.

After a reset it replays the history Self::audio_needs asks for in bounded blocks, cut where each stage starts, so the mix after a seek does not depend on the block size. Recursive effects use a finite settling horizon (32 exponential time constants, with filter/feedback margins, and no stage leads by more than MAX_SETTLING_SECONDS), not a bit-exact promise for arbitrary infinite-history DSP. Each stage joins the replay only when its own horizon, plus everything downstream of it, begins: a long reverb on one track replays that track, not every track. A block that continues the previous one resets and replays nothing.

§Errors

Returns EngineError::InvalidAudioConfiguration for a negative start, a block larger than Self::max_block, or a block whose timeline span does not fit in ticks, and an evaluation error when the snapshot cannot be evaluated over the block’s timeline span.

Source

pub fn set_normalization_gain_db( &mut self, gain_db: f64, ) -> Result<(), EngineError>

Applies a static gain, in dB, after the master gain and before the limiter: loudness normalization. Zero removes it, and so does starting to meter (Self::set_loudness_metering). It takes any gain alpha2_audio::LoudnessNormalization::plan gives.

§Errors

Returns EngineError::InvalidNormalizationGain for a non-finite gain, or one whose linear factor a 32-bit float cannot hold as a finite, positive number (past about 760 dB either way).

Source

pub const fn set_hold_incomplete_blocks(&mut self, hold: bool)

Whether a block a source is missing from is held: mixed as silence with nothing advanced, so that rendering it again once the host has supplied the source continues exactly as an uninterrupted render would. Off (the default), such a block mixes the clips it has and moves on, as live playback wants; an export turns it on.

Source

pub fn set_loudness_metering( &mut self, enabled: bool, ) -> Result<(), EngineError>

Starts (or restarts, from empty) measuring the loudness of what reaches the limiter, over the blocks rendered from now on; false stops. The measurement is of the complete requested blocks only: never of the history the renderer replays after a seek, nor of a block a source was missing from, which the host renders again.

Starting removes the normalization gain (Self::set_normalization_gain_db), so a measurement is of the mix as authored however many times one is planned from: a gain set after starting is measured, which checks a normalized mix.

§Errors

Returns EngineError::InvalidAudioConfiguration for a layout or rate the meter does not support.

Source

pub fn loudness_report(&self) -> Option<LoudnessReport>

What the meter has measured, if metering is on.

Source

pub fn limiter_threshold(&self) -> Option<f64>

The linear threshold of the master limiter the meter reads in front of, or None for a project without one. A loudness plan takes it (alpha2_audio::LoudnessNormalization::plan) so the gain it plans stops short of the limiter, which would otherwise cut it back.

Source

pub fn set_output_loudness_metering( &mut self, enabled: bool, ) -> Result<(), EngineError>

Starts (or restarts, from empty) measuring the loudness of what the renderer outputs, after the limiter and the normalization gain, over the blocks rendered from now on; false stops. It measures the same blocks Self::set_loudness_metering does, and leaves the gain as it is: an export measures what it hands its encoder.

§Errors

Returns EngineError::InvalidAudioConfiguration for a layout or rate the meter does not support.

Source

pub fn output_loudness_report(&self) -> Option<LoudnessReport>

What the output meter has measured, if output metering is on.

Source

pub fn block(&self, status: &AudioRenderStatus) -> AudioBlock

Copies the most recent render into an owned block for offline sinks.

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,