ARDFTSRC
A rust implementation of the Arbitrary Rate Discrete Fourier Transform Sample Rate Converter (ARDFTSRC) algorithm.
ardftsrc is a streaming audio sample-rate converter for interleaved audio streams, and is appropriate for both realtime and offline resampling.
Generally ardftsrc is preferred over other resamplers when quality is paramount. Although it is generic over both f32 and f64, it is highly recommended to use it with f64, even when processing an f32 audio stream.
It is more compute and memory intensive than other resamplers, so consider rubato if you want more efficiency.
Quick Start
Use InterleavedResampler::process_all to resample a complete interleaved audio stream for a single track.
use ;
Chunk Resampling
Use chunk resampling when you can control both read and write buffer sizes. Query input_chunk_size() and output_chunk_size() and size your input and output slices to the sizes required. The chunk API is more efficient than the streaming API and is preferred when you are not doing live resampling.
process_chunk(...)for each chunk, input and output slice sizes should matchinput_chunk_size()andoutput_chunk_size()- Call
process_chunk_final(...)for the final chunk, it can be undersized. finalize(...)must be called once per stream to emit delayed tail samples and reset stream state.
To end the stream early, you can always just stop and call reset() on the stream.
use ;
Gapless Context
For adjacent tracks, you can set edge context before processing:
pre(Vec<T>): tail frames from the previous trackpost(Vec<T>): head frames from the next track
post(...) may be called any time while the current stream is still active, but it must be
set before process_chunk_final(...).
This enables live gapless handoff: while track A is streaming, once track B is known you can
call post(...) on A with B's head samples so A's stop-edge uses real next-track context.
Streaming Resampler
Use the streaming resampler for live resampling. It accepts interleaved sample slices of any size and buffers internally until enough input is available for the underlying chunk resampler.
- Call
write_samples(...)with any incoming input size and callread_samples(...)to drain available output. - For multichannel streams, samples must be written interleaved.
- Call
new_span(input_sample_rate, channels)when the input sample rate or channel count changes. - Before calling
new_span(...)orfinalize_samples(...), the current span must be frame aligned. - Call
finalize_samples(...)once at end-of-stream, then keep callingread_samples(...)until it returns0.
Expect bursty read behavior. read_samples(...) accepts any output buffer size.
Spans
Streaming sources sometimes change format while they are still producing samples. For example, a playlist-like source may play one file at 44.1 kHz stereo and then another at 48 kHz mono. The streaming resampler models those format regions as spans. You can start a new span with new_span(). When a new span starts, writes go to the new span immediately, and reads continue draining the previous span first before switching to the next.
Input spans and output spans are non-synchronous. After calling new_span, you should query samples_left_in_span() to see how many samples are left on the output side before the output will switch to a new span.
To end the stream early, you can always just stop and call reset() on the stream.
use ;
Batching
Use batching when you have multiple full tracks to convert with the same configuration.
InterleavedResampler::batch(...): processes each interleaved input as an independent stream (no context shared between tracks).InterleavedResampler::batch_gapless(...): preserves adjacent-track context for gapless album-style playback.PlanarResamplerexposes the samebatch(...)andbatch_gapless(...)APIs for already-planar inputs.
Enable the rayon feature to parallelize work across tracks.
use ;
Quality Tuning and Presets
ARDFTSRC is built for quality over speed, and despite supporting both f32 and f64 should almost always be run as f64. To resample f32 audio, it is recommended to convert f32 samples to f64, resample them using InterleavedResampler<f64> or PlanarResampler<f64>, then convert back to f32.
If you want better performance than what this project offers, consider using a sinc resampler such as rubato.
Presets are pre-vetted Config for various quality levels.
let config = PRESET_GOOD
.with_input_rate
.with_output_rate
.with_channels;
| Preset | Parameters | Recommended use | Quality Metrics |
|---|---|---|---|
PRESET_FAST |
quality=512 bandwidth=0.832 |
Fast preset for realtime workloads. | f32, f64 |
PRESET_GOOD |
quality=1878 bandwidth=0.911 |
Balanced preset for realtime quality. | TODO |
PRESET_HIGH |
quality=73622 bandwidth=0.987 |
High quality for offline or quality-focused realtime use. | TODO |
PRESET_EXTREME |
quality=524514 bandwidth=0.995 |
Maximum quality, intended for offline use. | TODO |
Feature Flags
| Flag | Enables | Default |
|---|---|---|
audioadapter |
Experimental audioadapter support |
No |
rayon |
Parallel processing (channel and track parallelism) | No |
avx |
FFT AVX SIMD | Yes |
sse |
FFT SSE SIMD | Yes |
neon |
FFT NEON SIMD for ARM / Mac | Yes |
wasm_simd |
FFT WebAssembly SIMD | Yes |
Runtime feature detection is in place for all SIMD except webassembly.