Crate rubato

source ·
Expand description

An audio sample rate conversion library for Rust.

This library provides resamplers to process audio in chunks.

The ratio between input and output sample rates is completely free. Implementations are available that accept a fixed length input while returning a variable length output, and vice versa.

Rubato can be used in realtime applications without any allocation during processing by preallocating a Resampler and using its input_buffer_allocate and output_buffer_allocate methods before beginning processing. The log feature feature should be disabled for realtime use (it is disabled by default).

§Input and output data format

Input and output data are stored in a non-interleaved format.

Input and output data are stored as slices of references, &[AsRef<[f32]>] or &[AsRef<[f64]>]. The inner references (AsRef<[f32]> or AsRef<[f64]>) hold the sample values for one channel each.

Since normal vectors implement the AsRef trait, Vec<Vec<f32>> and Vec<Vec<f64>> can be used for both input and output.

§Asynchronous resampling

The asynchronous resamplers are available with and without anti-aliasing filters.

Resampling with anti-aliasing is based on band-limited interpolation using sinc interpolation filters. The sinc interpolation upsamples by an adjustable factor, and then the new sample points are calculated by interpolating between these points. The resampling ratio can be updated at any time.

Resampling without anti-aliasing omits the cpu-heavy sinc interpolation. This runs much faster but produces a lower quality result.

§Synchronous resampling

Synchronous resampling is implemented via FFT. The data is FFT:ed, the spectrum modified, and then inverse FFT:ed to get the resampled data. This type of resampler is considerably faster but doesn’t support changing the resampling ratio.

§SIMD acceleration

§Asynchronous resampling with anti-aliasing

The asynchronous resampler supports SIMD on x86_64 and on aarch64. The SIMD capabilities of the CPU are determined at runtime. If no supported SIMD instruction set is available, it falls back to a scalar implementation.

On x86_64, it will try to use AVX. If AVX isn’t available, it will instead try SSE3.

On aarch64 (64-bit Arm), it will use Neon if available.

§Synchronous resampling

The synchronous resamplers benefit from the SIMD support of the RustFFT library.

§Cargo features

§fft_resampler: Enable the FFT based synchronous resamplers

This feature is enabled by default. Disable it if the FFT resamplers are not needed, to save compile time and reduce the resulting binary size.

§log: Enable logging

This feature enables logging via the log crate. This is intended for debugging purposes. Note that outputting logs allocates a std::string::String and most logging implementations involve various other system calls. These calls may take some (unpredictable) time to return, during which the application is blocked. This means that logging should be avoided if using this library in a realtime application.

§Example

Resample a single chunk of a dummy audio file from 44100 to 48000 Hz. See also the “process_f64” example that can be used to process a file from disk.

use rubato::{Resampler, SincFixedIn, SincInterpolationType, SincInterpolationParameters, WindowFunction};
let params = SincInterpolationParameters {
    sinc_len: 256,
    f_cutoff: 0.95,
    interpolation: SincInterpolationType::Linear,
    oversampling_factor: 256,
    window: WindowFunction::BlackmanHarris2,
};
let mut resampler = SincFixedIn::<f64>::new(
    48000 as f64 / 44100 as f64,
    2.0,
    params,
    1024,
    2,
).unwrap();

let waves_in = vec![vec![0.0f64; 1024];2];
let waves_out = resampler.process(&waves_in, None).unwrap();

§Included examples

The examples directory contains a few sample applications for testing the resamplers. There are also Python scripts for generating simple test signals as well as analyzing the resampled results.

The examples read and write raw audio data in 64-bit float format. They can be used to process .wav files if the files are first converted to the right format. Use sox to convert a .wav to raw samples:

sox some_file.wav -e floating-point -b 64 some_file_f64.raw

After processing, the result can be converted back to new .wav. This examples converts to 16-bits at 44.1 kHz:

sox -e floating-point -b 64 -r 44100 -c 2 resampler_output.raw -e signed-integer -b 16 some_file_resampled.wav

Many audio editors, for example Audacity, are also able to directly import and export the raw samples.

§Compatibility

The rubato crate requires rustc version 1.61 or newer.

§Changelog

  • v0.15.0
    • Make FFT resamplers optional via fft_resampler feature.
    • Fix calculation of input and output sizes when creating FftFixedInOut resampler.
    • Fix panic when using very small chunksizes (less than 5).
  • v0.14.1
    • More bugfixes for buffer allocation and max output length calculation.
    • Fix building with log feature.
  • v0.14.0
    • Add argument to let input/output_buffer_allocate() optionally pre-fill buffers with zeros.
    • Add convenience methods for managing buffers.
    • Bugfixes for buffer allocation and max output length calculation.
  • v0.13.0
    • Switch to slices of references for input and output data.
    • Add faster (lower quality) asynchronous resamplers.
    • Add a macro to help implement custom object safe resamplers.
    • Optional smooth ramping of ratio changes to avoid audible steps.
    • Add convenience methods for handling last frames in a stream.
    • Add resampler reset method.
    • Refactoring for a more logical structure.
    • Add helper function for calculating cutoff frequency.
    • Add quadratic interpolation for sinc resampler.
    • Add method to get the delay through a resampler as a number of output frames.
  • v0.12.0
    • Always enable all simd acceleration (and remove the simd Cargo features).
  • v0.11.0
    • New api to allow use in realtime applications.
    • Configurable adjust range of asynchronous resamplers.
  • v0.10.1
    • Fix compiling with neon feature after changes in latest nightly.
  • v0.10.0
    • Add an object-safe wrapper trait for Resampler.
  • v0.9.0
    • Accept any AsRef<[T]> as input.

Modules§

Macros§

  • A macro for implementing wrapper traits for when a Resampler must be object safe. The wrapper trait locks the generic type parameters or the Resampler trait to specific types, which is needed to make the trait into an object.

Structs§

  • An asynchronous resampler that accepts a fixed number of audio frames for input and returns a variable number of frames.
  • An asynchronous resampler that returns a fixed number of audio frames. The number of input frames required is given by the input_frames_next function.
  • A synchronous resampler that needs a fixed number of audio frames for input and returns a variable number of frames.
  • A synchronous resampler that accepts a fixed number of audio frames for input and returns a fixed number of frames.
  • A synchronous resampler that needs a varying number of audio frames for input and returns a fixed number of frames.
  • Error raised when trying to use a CPU feature which is not supported.
  • An asynchronous resampler that accepts a fixed number of audio frames for input and returns a variable number of frames.
  • An asynchronous resampler that returns a fixed number of audio frames. The number of input frames required is given by the input_frames_next function.
  • A struct holding the parameters for sinc interpolation.

Enums§

  • An identifier for a cpu feature.
  • Degree of the polynomial used for interpolation. A higher degree gives a higher quality result, while taking longer to compute.
  • The error type used by rubato.
  • The error type returned when constructing Resampler.
  • Interpolation methods that can be selected. For asynchronous interpolation where the ratio between input and output sample rates can be any number, it’s not possible to pre-calculate all the needed interpolation filters. Instead they have to be computed as needed, which becomes impractical since the sincs are very expensive to generate in terms of cpu time. It’s more efficient to combine the sinc filters with some other interpolation technique. Then, sinc filters are used to provide a fixed number of interpolated points between input samples, and then, the new value is calculated by interpolation between those points.
  • Different window functions that can be used to window the sinc function.

Traits§

  • A resampler that is used to resample a chunk of audio to a new sample rate. For asynchronous resamplers, the rate can be adjusted as required.
  • The trait governing a single sample.
  • This is an wrapper trait implemented via the implement_resampler macro. The generic input and output types &[AsRef<[T]>] and &mut [AsMut<[T]>] are locked to &[Vec<T>] and &mut [Vec<T>].

Functions§

  • Convenience method for getting the current allocated capacity of a buffer in frames. Checks the capacity of the vector for each channel and returns the smallest.
  • Convenience method for getting the current length of a buffer in frames. Checks the length of the vector for each channel and returns the smallest.
  • Calculate a suitable relative cutoff frequency for the given sinc length using the given window function. The result is based on an approximation, which gives good results for sinc lengths from 32 to 2048.
  • Convenience method for allocating a buffer to hold a given number of channels and frames. The filled argument determines if the vectors should be pre-filled with zeros or not. When false, the vectors are only allocated but returned empty.
  • Convenience method for resizing a buffer to a new number of frames. If the new number of frames is no larger than the buffer capacity, no reallocation will occur. If the new length is smaller than the current, the excess elements are dropped. If it is larger, zeros are inserted for the missing elements.

Type Aliases§