Skip to main content

Audio

Struct Audio 

Source
pub struct Audio<S> { /* private fields */ }
Expand description

Generic audio pipeline running in a separate thread.

Provides a simple interface for reading decoded PCM audio, compatible with cpal and rodio audio backends.

§Example

use kithara_audio::{Audio, AudioConfig};
use kithara_hls::{Hls, HlsConfig};
use kithara_stream::Stream;

let config = AudioConfig::<Hls>::new(hls_config)
    .hint("mp3");
let audio = Audio::<Stream<Hls>>::new(config).await?;

// Get audio format
let spec = audio.spec();
println!("{}Hz, {} channels", spec.sample_rate, spec.channels);

// Read PCM samples
let mut buf = [0.0f32; 1024];
loop {
    match audio.read(&mut buf)? {
        ReadOutcome::Frames { count, .. } => play_samples(&buf[..count]),
        ReadOutcome::Eof { .. } => break,
    }
}

Implementations§

Source§

impl<S> Audio<S>

Source

pub fn abr_handle(&self) -> Option<AbrHandle>

Runtime ABR handle (cloned from the stream’s source at construction). Some for adaptive sources (HLS), None for file/non-adaptive sources.

Source

pub fn current_variant(&self) -> Option<VariantInfo>

Current variant’s metadata. Pulled live from the ABR peer on every call — no caching — so the UI never sees a stale label after an ABR switch. None for non-adaptive sources or peers that have not yet registered variants.

Source

pub fn duration(&self) -> Option<Duration>

Get total duration of the audio stream.

Returns None for streaming sources where duration is unknown.

Source

pub fn is_preloaded(&self) -> bool

Whether non-blocking recv is active.

Returns false after seek() until preload() is called again.

Source

pub fn metadata(&self) -> &TrackMetadata

Get track metadata (title, artist, album, artwork).

Source

pub fn position(&self) -> Duration

Get current playback position.

Calculated from samples read since last seek plus the seek base.

Source

pub fn preload(&mut self) -> Result<(), DecodeError>

Enable non-blocking mode for read() and prime the first chunk.

After calling this, read() returns immediately from buffered data without blocking. Must be called after construction so that fill_buffer() calls from JS (via requestAnimationFrame) don’t hang.

Returns Err(DecodeError) if the producer channel closed during the initial fill_buffer (e.g. upstream decoder reported TrackStep::Failed before any data). Natural EOF encountered during preload is not surfaced here — the subsequent read() / next_chunk() call will report ReadOutcome::Eof.

§Errors

Returns DecodeError::Io if the producer channel closed during preload.

Source

pub fn read(&mut self, buf: &mut [f32]) -> Result<ReadOutcome, DecodeError>

Read decoded PCM samples into buffer.

Samples are interleaved f32 (e.g., LRLRLR for stereo).

Returns ReadOutcome::Frames with a non-zero count when the reader produced data, ReadOutcome::Pending with a typed PendingReason when the reader is alive but produced no frames this tick (buffering, seek-in-progress), or ReadOutcome::Eof on natural end-of-stream. Decoder / channel failures surface as DecodeError via the Err arm.

§Errors

Returns DecodeError::Io when the producer channel closed / reported a failure (ConsumerPhase::Failed) before any frames could be flushed.

Source

pub fn seek(&mut self, position: Duration) -> Result<SeekOutcome, DecodeError>

Seek to position in the audio stream.

This method never blocks. Seek coordination flows entirely through Timeline atomics (FLUSH_START/FLUSH_STOP pattern). The worker thread reads the seek target and epoch from Timeline and applies the seek.

Returns SeekOutcome::Landed when the reader is now parked at position; SeekOutcome::PastEof when the target is beyond a known duration() (the subsequent read returns ReadOutcome::Eof).

§Errors

Propagated from the underlying stream (currently infallible at this layer — the worker thread surfaces errors lazily via FetchKind::Failure, which becomes Err from a subsequent read() / next_chunk()).

Source

pub fn spec(&self) -> PcmSpec

Subscribe to audio events.

Get current audio specification.

Returns sample rate and channel count for audio output setup.

Source§

impl<T> Audio<Stream<T>>
where T: StreamType<Events = EventBus>,

Specialized impl for Stream-based audio pipelines.

Provides async constructor that creates Stream internally. Uses StreamAudioSource for automatic format change detection on ABR switch.

Source

pub async fn new(config: AudioConfig<T>) -> Result<Self, DecodeError>

Create audio pipeline from AudioConfig.

This is the target API for Stream sources. Uses StreamAudioSource for automatic decoder recreation on format change.

§Errors

Returns DecodeError if the stream cannot be created, the initial probe fails, or the decoder cannot be initialized.

§Example
let config = AudioConfig::<Hls>::new(hls_config);
let audio = Audio::new(config).await?;
sink.append(audio);
Source

pub fn event_bus(&self) -> &EventBus

Get a reference to the underlying EventBus.

Useful for passing to downstream components that also publish events.

Source

pub fn events(&self) -> EventReceiver

Subscribe to unified events via the EventBus.

Returns a receiver for all events published to the bus.

Trait Implementations§

Source§

impl<S> Drop for Audio<S>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl<S: MaybeSend> PcmReader for Audio<S>

Source§

fn abr_handle(&self) -> Option<AbrHandle>

Runtime ABR handle for the underlying stream. Read more
Source§

fn duration(&self) -> Option<Duration>

Get total duration (if known).
Source§

fn event_bus(&self) -> &EventBus

Access the unified event bus for subscribing to all pipeline events.
Source§

fn metadata(&self) -> &TrackMetadata

Get track metadata.
Source§

fn next_chunk(&mut self) -> Result<ChunkOutcome, DecodeError>

Read the next decoded chunk with full metadata. Read more
Source§

fn position(&self) -> Duration

Get current playback position.
Source§

fn preload(&mut self) -> Result<(), DecodeError>

Preload initial chunks into internal buffers. Read more
Source§

fn preload_notify(&self) -> Option<Arc<Notify>>

Get notify for async preload (first chunk available).
Source§

fn read(&mut self, buf: &mut [f32]) -> Result<ReadOutcome, DecodeError>

Read interleaved PCM samples. Read more
Source§

fn read_planar<'a>( &mut self, output: &'a mut [&'a mut [f32]], ) -> Result<ReadOutcome, DecodeError>

Read deinterleaved (planar) PCM samples. Read more
Source§

fn seek(&mut self, position: Duration) -> Result<SeekOutcome, DecodeError>

Seek to the given position. Read more
Source§

fn set_host_sample_rate(&self, sample_rate: NonZeroU32)

Set the target sample rate of the audio host. Read more
Source§

fn set_playback_rate(&self, rate: f32)

Set the playback rate for timeline scaling. Read more
Source§

fn set_service_class(&self, class: ServiceClass)

Update the scheduling priority hint for the shared worker. Read more
Source§

fn spec(&self) -> PcmSpec

Get the current PCM specification.

Auto Trait Implementations§

§

impl<S> !Freeze for Audio<S>

§

impl<S> !RefUnwindSafe for Audio<S>

§

impl<S> Send for Audio<S>
where S: Send,

§

impl<S> !Sync for Audio<S>

§

impl<S> Unpin for Audio<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for Audio<S>

§

impl<S> !UnwindSafe for Audio<S>

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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

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