Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Decibri Resampler

decibri-resampler

A streaming, anti-aliased sample-rate resampler for mono f32 audio.

crates.io version  Apache 2.0 License 

Properties

  • Streaming and stateful: processes successive chunks, carrying filter state across calls so chunk boundaries are invisible in the output.
  • Anti-aliased polyphase windowed-sinc conversion: over 80 dB of stopband attenuation and under 0.001 dB of passband ripple, measured on the 48000 to 16000 and 44100 to 16000 conversions.
  • Deterministic by construction: a fixed accumulation order, no fused multiply-add, and no platform-dependent transcendentals in the coefficient path.
  • Reports its algorithmic latency in output samples (106 for 48000 to 16000 and 44100 to 16000).
  • Identity bypass at equal input and output rates: byte-identical passthrough with zero added latency.
  • No per-call heap allocation in steady state.
  • Exact handling of common integer-Hz conversions, with an arbitrary-ratio path for other rates.
  • Optional tracing diagnostics at construction, flush, and reset, behind the off-by-default tracing feature; without the feature the crate has no dependency on tracing and the emit sites compile to nothing.

Usage

use decibri_resampler::{PolyphaseResampler, Resampler};

// Construct for an input and output rate in Hz. The rate pair is fixed for the
// lifetime of the instance.
let mut resampler = PolyphaseResampler::new(48_000, 16_000).unwrap();

// Feed successive chunks of any size; resampled output is appended to the buffer.
let mut output = Vec::new();
resampler.process(&[0.0_f32; 480], &mut output).unwrap();
resampler.process(&[0.0_f32; 320], &mut output).unwrap();

// Drain the filter tail at end of stream. To start another stream on the same
// instance, call reset first: process after flush without a reset is rejected.
resampler.flush(&mut output);

assert!(!output.is_empty());

API

The crate's public surface is the Resampler trait, implemented by PolyphaseResampler. Input and output are a single mono f32 channel; channel handling and sample-format conversion are out of scope.

  • PolyphaseResampler::new(in_rate, out_rate) constructs a resampler for a fixed input and output rate pair. It returns ResamplerError::ZeroSampleRate if either rate is zero, and ResamplerError::RatePairUnsupported if the pair would require an anti-aliasing filter beyond the supported maximum length (reachable only for pathological integer rates, never for real audio rates).
  • process(&[f32], &mut Vec<f32>) -> Result<(), ResamplerError> consumes an input chunk of any length and appends the resampled output, which is variable in length and may be empty for a small input. It returns ResamplerError::ProcessAfterFlush when called after flush with no intervening reset; the rejected call consumes nothing, appends nothing, and changes no state.
  • flush(&mut Vec<f32>) drains the group-delay tail into the output buffer at end of stream.
  • latency_samples() -> usize reports the constant algorithmic latency in output samples.
  • is_identity() -> bool is true when the input and output rates are equal.
  • reset() clears all streaming state, keeping the configured rates.

The streaming lifecycle: feed process for the life of a stream, call flush at end of stream, and call reset to start the next stream on the same instance. flush is idempotent (a repeated flush appends nothing) and appends nothing when no samples were processed. After a flush, a process call without an intervening reset is rejected with ResamplerError::ProcessAfterFlush, in release builds as well as debug; the rejected call consumes nothing, appends nothing, and changes no state, and the instance remains usable after a reset. The asymmetry is deliberate: a repeated flush restates that the stream has ended, which is redundant but not contradictory, while a process after flush contradicts it, and the contradiction is reported rather than silently resolved.

License

Apache-2.0 © 2026 Decibri.

About

A deterministic, streaming, anti-aliased polyphase sample-rate resampler for mono f32 audio, with bit-exact cross-platform output.

Topics

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages