Skip to main content

PlanarResampler

Struct PlanarResampler 

Source
pub struct PlanarResampler<T = f64>
where T: Float + FftNum,
{ /* private fields */ }
Expand description

Chunked sample-rate converter for planar audio buffers.

Use this resampler when you can control both read and write buffer sizes, and your audio is already in planar format. Query input_buffer_size() and output_buffer_size(), then size your input and output channel slices to those values.

  1. Construct with PlanarResampler::new(config).
  2. Query input_buffer_size() and output_buffer_size().
  3. Call process_chunk(...) for each full planar chunk.
  4. Call process_chunk_final(...) once for the final chunk (it may be undersized).
  5. Call finalize(...) once per stream to emit delayed tail samples and reset stream state.

To end a stream early, call reset().

This is the most direct chunked path because ardftsrc internally processes planar channels.

Implementations§

Source§

impl<T> PlanarResampler<T>
where T: Float + FftNum,

Source

pub fn new(config: Config) -> Result<Self, Error>

Constructs a resampler from config.

Returns a ready-to-use resampler instance, or an error if config is invalid or derived FFT geometry cannot be prepared.

Source

pub fn config(&self) -> &Config

Returns the configuration this instance was built with.

Source

pub fn input_sample_processed(&self) -> usize

Returns the total number of input samples processed across all channels.

Source

pub fn output_sample_processed(&self) -> usize

Returns the total number of output samples processed across all channels.

Source

pub fn input_buffer_size(&self) -> usize

Returns the required total input length for each process_chunk() call.

Divide by channel count to get the required frame count per channel.

Use this to allocate/read fixed-size streaming input buffers.

Source

pub fn output_buffer_size(&self) -> usize

Returns the recommended total per-call output capacity.

Divide by channel count to get the recommended frame capacity per channel.

For chunked streaming, size output slices passed to process_chunk() and process_chunk_final() to at least this value.

Source

pub fn output_delay_frames(&self) -> usize

Returns algorithmic latency to trim/flush, or zero in same-rate passthrough mode.

Source

pub fn expected_output_size(&self, input_size: usize) -> usize

Returns the expected output length for a given input length.

input_size can be expressed in either frames or samples; the returned value uses the same unit.

Source

pub fn process_all<'a>( &mut self, input: &[&[T]], ) -> Result<PlanarVecs<T>, Error>
where T: Send + Sync,

Resamples complete planar channel inputs and returns all output samples.

This is a convenience wrapper around the streaming API.

When the rayon feature is enabled, each channel is processed in parallel.

Source

pub fn reset(&mut self)

Resets internal streaming state so the next input is treated as a new, independent stream.

Call this between unrelated audio inputs (for example, between files) when reusing the same resampler instance, so edge/history state from one input cannot bleed into the next.

Source

pub fn process_chunk<'a>( &mut self, input: &[&[T]], output: &mut [&mut [T]], ) -> Result<usize, Error>

Processes a planar chunk.

input must provide one slice per channel, each with exactly input_buffer_size() / channels samples. output should provide one mutable slice per channel, each with at least output_buffer_size() / channels capacity.

The method returns the actual sample count written for this chunk, which may be smaller (for example while startup delay is being trimmed).

Returns the number of samples written to the output buffer across all channels. Divide by channel count to get frames written per channel.

Source

pub fn process_chunk_final<'a>( &mut self, input: &[&[T]], output: &mut [&mut [T]], ) -> Result<usize, Error>

Processes the final chunk, which may be shorter than the regular chunk size.

Call this exactly once at end-of-stream for the trailing partial chunk (it may be empty if each channel length is an exact multiple of input_buffer_size() / channels). After this call, no further chunk-processing calls should be made; call finalize() to drain remaining delayed tail.

input must provide one slice per channel, each with at most input_buffer_size() / channels samples. output should provide one mutable slice per channel, each with at least output_buffer_size() / channels capacity.

Returns the total number of samples written across all output channels. Divide by channel count to get frames written per channel.

Source

pub fn finalize<'a>(&mut self, output: &mut [&mut [T]]) -> Result<usize, Error>

Emits delayed tail samples, then resets stream state.

This flushes any remaining delayed samples that were held back by the chunked processing pipeline. It is the terminal step of a stream and should be called once per stream. If process_chunk_final() was not called, this treats the last accepted full chunk as terminal input.

output must provide one mutable slice per channel, each with at least output_buffer_size() / channels capacity.

Returns the total number of samples written across all output channels. Divide by channel count to get frames written per channel.

Source

pub fn pre<'a>(&mut self, pre: Vec<Vec<T>>) -> Result<(), Error>

Sets previous-track context.

Use this when resampling gapless material, for example an album where tracks are played back-to-back. In that case, pass the last chunk of the previous track.

The adapter must report the same channel count as this resampler.

Recommended size:

  • Pass one full input chunk from the end of the previous track.
  • Query chunk size with input_buffer_size().

Shorter buffers are still valid: any missing start context falls back to LPC extrapolation. Longer buffers are truncated to fit.

Source

pub fn post<'a>(&mut self, post: Vec<Vec<T>>) -> Result<(), Error>

Sets next-track context.

Use this when resampling gapless material, for example an album where tracks are played back-to-back. In that case, pass the first chunk of the next track.

You may call this at any time while the current stream is still active. It must be called before “process_chunk_final(…)”.

This is useful for live gapless handoff: while track A is streaming, once track B is known you can call post(...) on track A with B’s head samples so A’s stop-edge uses real next-track context.

The adapter must report the same channel count as this resampler.

Recommended size:

  • Pass one full input chunk from the start of the next track.
  • Query chunk size with input_buffer_size().

Shorter buffers are still valid: any missing stop context falls back to LPC extrapolation.

Source

pub fn batch( &self, inputs: Vec<PlanarVecs<T>>, ) -> Result<Vec<PlanarVecs<T>>, Error>
where T: Send + Sync,

Process multiple independent tracks.

Each input slice is treated as its own stream with no inter-track context. See batch_gapless() for gapless processing of multiple tracks.

Enable the rayon feature for parallel processing.

Source

pub fn batch_gapless( &self, inputs: Vec<PlanarVecs<T>>, ) -> Result<Vec<PlanarVecs<T>>, Error>
where T: Send + Sync,

Process multiple tracks as one gapless sequence.

Adjacent inputs are treated as tracks from the same album or other back-to-back material. Each track is returned separately, but the previous track’s tail and next track’s head are used as edge context to improve gapless playback.

Enable the rayon feature for parallel processing.

Auto Trait Implementations§

§

impl<T> Freeze for PlanarResampler<T>

§

impl<T = f64> !RefUnwindSafe for PlanarResampler<T>

§

impl<T> Send for PlanarResampler<T>

§

impl<T> Sync for PlanarResampler<T>

§

impl<T> Unpin for PlanarResampler<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for PlanarResampler<T>

§

impl<T = f64> !UnwindSafe for PlanarResampler<T>

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<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

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> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

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<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,