### Robust Real-time Setup with Error Handling Source: https://github.com/henquist/rubato/blob/master/_autodocs/05-errors-and-results.md For real-time applications, validate resampler creation and configuration before entering time-critical loops. This example demonstrates pre-allocating buffers and using the `?` operator for initial setup, assuming the real-time loop will not produce errors. ```rust // Setup (before real-time) let resampler = Async::::new_poly(...)?; // Can error let max_in = resampler.input_frames_max(); let max_out = resampler.output_frames_max(); let mut input_buf = vec![0.0; max_in]; let mut output_buf = vec![0.0; max_out]; // ... convert to adapter ... // Real-time loop (bounded, no errors expected) let needed_in = resampler.input_frames_next(); let needed_out = resampler.output_frames_next(); // Copy data into input_buf (first needed_in samples) // Process (should not error if setup was correct) resampler.process_into_buffer(&input, &mut output, None).unwrap(); ``` -------------------------------- ### Process All Into Buffer Example Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md Example demonstrating the use of process_all_into_buffer for processing a complete audio buffer. This method handles the entire input, including potential delays and partial frames, writing the resampled audio to a pre-allocated output buffer. ```rust use rubato::{Resampler, Fft, FixedSync}; use audioadapter_buffers::direct::InterleavedSlice; let mut resampler = Fft::::new(48000, 44100, 1024, 2, 2, FixedSync::Both)?; let input = vec![0.0f64; 88200]; // 2 seconds at 44.1 kHz, stereo let input_len = input.len() / 2; let output_len = resampler.process_all_needed_output_len(input_len); let mut output = vec![0.0f64; output_len]; let input_adapter = InterleavedSlice::new(&input, 2, input_len)?; let mut output_adapter = InterleavedSlice::new_mut(&mut output, 2, output_len)?; let (in_frames, out_frames) = resampler.process_all_into_buffer( &input_adapter, &mut output_adapter, input_len, None, )?; ``` -------------------------------- ### SincInterpolationParameters Examples Source: https://github.com/henquist/rubato/blob/master/_autodocs/04-types-and-enums.md Illustrates different configurations for SincInterpolationParameters, ranging from high-quality to fast settings. These examples show how to adjust parameters like sinc_len, f_cutoff, interpolation, oversampling_factor, and window for various use cases. ```rust use rubato::{SincInterpolationParameters, SincInterpolationType, WindowFunction}; // High-quality settings (higher CPU) let high_quality = SincInterpolationParameters { sinc_len: 512, f_cutoff: 0.95, interpolation: SincInterpolationType::Cubic, oversampling_factor: 256, window: WindowFunction::BlackmanHarris2, }; // Balanced settings let balanced = SincInterpolationParameters { sinc_len: 256, f_cutoff: 0.95, interpolation: SincInterpolationType::Cubic, oversampling_factor: 128, window: WindowFunction::BlackmanHarris2, }; // Fast settings (lower quality) let fast = SincInterpolationParameters { sinc_len: 64, f_cutoff: 0.95, interpolation: SincInterpolationType::Linear, oversampling_factor: 32, window: WindowFunction::Blackman, }; ``` -------------------------------- ### Typical Log Output Example Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Illustrates the format and content of log messages generated when the `log` feature is enabled. ```log [TRACE] Create new Fast with fixed FixedAsync::Input, ratio: 1.088, chunk_size: 1024, channels: 2 [DEBUG] resamping 44100 input frames to 48000 output frames, delay to trim off 512 frames [DEBUG] process, 42000 input frames left [DEBUG] process the last partial chunk, len 2100 ``` -------------------------------- ### Indexing Struct Usage Example Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md Demonstrates how to instantiate and use the Indexing struct with process_into_buffer. ```rust use rubato::Indexing; let indexing = Indexing { input_offset: 512, // Skip first 512 frames output_offset: 512, // Start writing at frame 512 in output partial_len: Some(100), // Only read 100 frames (treat rest as silence) active_channels_mask: Some(vec![true, false]), // Process only first channel }; resampler.process_into_buffer(&input, &mut output, Some(&indexing))?; ``` -------------------------------- ### Development Dependencies and Test Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Setup for development dependencies and defining test configurations for the project. ```toml [dev-dependencies] test-log = "0.2.16" test-case = "3" env_logger = "0.11.0" [[test]] name = "tests" path = "tests/..." ``` -------------------------------- ### Configure Sinc Interpolation Parameters Source: https://github.com/henquist/rubato/blob/master/_autodocs/04-types-and-enums.md Example of setting up SincInterpolationParameters, choosing SincInterpolationType::Cubic for the best balance of quality and performance. ```rust use rubato::SincInterpolationType; let params = SincInterpolationParameters { sinc_len: 256, f_cutoff: 0.95, interpolation: SincInterpolationType::Cubic, // Best balance oversampling_factor: 128, window: WindowFunction::BlackmanHarris2, }; ``` -------------------------------- ### Real-Time Code Example with Pre-allocation Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Pre-allocate buffers before real-time processing. Ensure the 'log' feature is disabled in release builds to maintain real-time safety. ```rust // Pre-allocate everything before real-time let mut resampler = Fft::::new(44100, 48000, 1024, 2, 2, FixedSync::Both)?; let max_in = resampler.input_frames_max(); let max_out = resampler.output_frames_max(); let mut input_buf = vec![0.0f64; max_in * 2]; let mut output_buf = vec![0.0f64; max_out * 2]; // Ensure logging is disabled in release builds #[cfg(feature = "log")] compile_error!("log feature must be disabled for real-time builds"); ``` -------------------------------- ### Benchmarking Setup in Cargo.toml Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Configuration in Cargo.toml to specify benchmark name and disable the built-in test harness when using criterion. ```toml [[bench]] name = "resamplers" harness = false # Uses criterion, not built-in test harness ``` -------------------------------- ### Convert WAV to 64-bit Float Raw Samples using SoX Source: https://github.com/henquist/rubato/blob/master/README.md Use this command to convert a .wav file to 64-bit float raw samples, which can be processed by Rubato examples. Ensure SoX is installed and accessible in your PATH. ```sh sox some_file.wav -e floating-point -b 64 some_file_f64.raw ``` -------------------------------- ### Configure Async Resampler with PolynomialDegree Source: https://github.com/henquist/rubato/blob/master/_autodocs/04-types-and-enums.md Example of creating an Async resampler using the PolynomialDegree::Cubic variant for a typical balance between quality and speed. ```rust use rubato::{Async, FixedAsync, PolynomialDegree}; let resampler = Async::::new_poly( 1.0, 2.0, PolynomialDegree::Cubic, // Typical choice 1024, 2, FixedAsync::Input, )?; ``` -------------------------------- ### Process into Buffer Example Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md Resample audio into a pre-allocated output buffer using the process_into_buffer method. This is suitable for real-time applications as it avoids heap allocations. Input and output buffers utilize the audioadapter crate for flexible layout and sample format support. ```rust use rubato::{Resampler, Fft, FixedSync, Indexing}; use audioadapter_buffers::direct::InterleavedSlice; let mut resampler = Fft::::new(48000, 44100, 1024, 2, 2, FixedSync::Both)?; let input_data = vec![0.0f64; 4096]; let mut output_data = vec![0.0f64; 5000]; let input = InterleavedSlice::new(&input_data, 2, 2048)?; let mut output = InterleavedSlice::new_mut(&mut output_data, 2, 2500)?; let (frames_in, frames_out) = resampler.process_into_buffer(&input, &mut output, None)?; println!("Consumed {} frames, produced {} frames", frames_in, frames_out); ``` -------------------------------- ### Channel Masking Example Source: https://github.com/henquist/rubato/blob/master/_autodocs/02-async-resampler.md Demonstrates how to use the `active_channels_mask` to selectively process specific audio channels. Masked channels are skipped during input and their output buffers remain unchanged. ```rust let indexing = Indexing { active_channels_mask: Some(vec![true, false]), // Process only channel 0 ..Default::new() }; resampler.process_into_buffer(&input, &mut output, Some(&indexing))?; ``` -------------------------------- ### Usage Example for MissingCpuFeature Error Source: https://github.com/henquist/rubato/blob/master/_autodocs/04-types-and-enums.md Demonstrates how to handle a MissingCpuFeature error, printing the specific unavailable CPU feature or a success message if all features are detected. ```rust match error { Some(err) => eprintln!("Missing CPU feature: {}", err.0), None => println!("All CPU features available"), } ``` -------------------------------- ### Configure Sinc Interpolation with WindowFunction Source: https://github.com/henquist/rubato/blob/master/_autodocs/04-types-and-enums.md Example of setting the WindowFunction for SincInterpolationParameters. BlackmanHarris2 is used for maximum quality, offering the slowest rolloff and excellent attenuation. ```rust use rubato::{WindowFunction, SincInterpolationParameters}; let params = SincInterpolationParameters { window: WindowFunction::BlackmanHarris2, // Maximum quality .. }; ``` -------------------------------- ### High-Quality Sinc-Based Resampling with Async Source: https://github.com/henquist/rubato/blob/master/_autodocs/07-usage-patterns.md This pattern is for audio processing where quality is paramount, using the Async resampler with SincInterpolationType::Cubic. Configure SincInterpolationParameters for optimal results. The resampler can be used normally after setup. ```rust use rubato::{ Resampler, Async, FixedAsync, SincInterpolationParameters, SincInterpolationType, WindowFunction, }; let params = SincInterpolationParameters { sinc_len: 256, f_cutoff: 0.95, interpolation: SincInterpolationType::Cubic, oversampling_factor: 128, window: WindowFunction::BlackmanHarris2, }; let mut resampler = Async::::new_sinc( 1.088, // 48000 / 44100 1.05, // Small adjustment range (no clock drift correction needed) ¶ms, 2048, // Larger chunk for better efficiency 2, FixedAsync::Input, )?; // Use as normal let (in_frames, out_frames) = resampler .process_into_buffer(&input, &mut output, None)?; ``` -------------------------------- ### Resample Audio File from 44100 to 48000 Hz Source: https://github.com/henquist/rubato/blob/master/README.md This snippet demonstrates how to resample an audio file from a source sample rate of 44100 Hz to a target rate of 48000 Hz. It involves setting up the resampler, creating dummy audio data, and processing it through the resampler in chunks. For processing entire files from disk, refer to the 'process_f64' example. ```rust use rubato::{ Resampler, Fft, FixedSync, Indexing }; use audioadapter_buffers::direct::InterleavedSlice; let mut resampler = Fft::::new(48000, 44100, 1024, 2, 2, FixedSync::Both).unwrap(); // create a short dummy audio clip, assuming it's stereo stored as interleaved f64 values let audio_clip = vec![0.0; 2*10000]; // wrap it with an InterleavedSlice Adapter let nbr_input_frames = audio_clip.len() / 2; let input_adapter = InterleavedSlice::new(&audio_clip, 2, nbr_input_frames).unwrap(); // create a buffer for the output let mut outdata = vec![0.0; 2*2*10000]; let outdata_capacity = outdata.len() / 2; let mut output_adapter = InterleavedSlice::new_mut(&mut outdata, 2, outdata_capacity).unwrap(); // Preparations let mut indexing = Indexing { input_offset: 0, output_offset: 0, active_channels_mask: None, partial_len: None, }; let mut input_frames_left = nbr_input_frames; let mut input_frames_next = resampler.input_frames_next(); // Loop over all full chunks. // There will be some unprocessed input frames left after the last full chunk. // see the `process_f64` example for how to handle those // using `partial_len` of the indexing struct. // It is also possible to use the `process_all_into_buffer` method // to process the entire file (including any last partial chunk) with a single call. while input_frames_left >= input_frames_next { let (frames_read, frames_written) = resampler .process_into_buffer(&input_adapter, &mut output_adapter, Some(&indexing)) .unwrap(); indexing.input_offset += frames_read; indexing.output_offset += frames_written; input_frames_left -= frames_read; input_frames_next = resampler.input_frames_next(); } ``` -------------------------------- ### Benchmarking Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Command to run benchmarks using the criterion crate with the 'fft_resampler' feature. ```bash cargo bench --features "fft_resampler" ``` -------------------------------- ### Get Current Resampling Ratio Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md Retrieve the current resampling ratio, which is calculated as the output sample rate divided by the input sample rate. ```rust fn resample_ratio(&self) -> f64 ``` -------------------------------- ### Calculate Resampling Ratio Source: https://github.com/henquist/rubato/blob/master/_autodocs/03-fft-resampler.md Demonstrates how to construct an FFT resampler and verify its resampling ratio. The ratio is computed once at construction and is immutable. ```rust let resampler = Fft::::new(44100, 48000, 1024, 2, 2, FixedSync::Both)?; assert_eq!(resampler.resample_ratio(), 48000.0 / 44100.0); ``` -------------------------------- ### Set Rust Version Requirement Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Specify the minimum Rust version required for the project in Cargo.toml. Verify the installed Rust version using the command line. ```toml [package] rust-version = "1.85" ``` ```bash rustc --version # Should output: rustc 1.85.0 or newer ``` -------------------------------- ### Real-Time Processing with Fixed Input Size (Async Resampler) Source: https://github.com/henquist/rubato/blob/master/_autodocs/07-usage-patterns.md Use this pattern when capturing audio from a source that provides fixed-size chunks, such as an audio interface callback. Ensure the resampler is configured with `FixedAsync::Input` and the correct chunk size. ```rust use rubato::{Resampler, Async, FixedAsync, PolynomialDegree}; use audioadapter_buffers::direct::InterleavedSlice; // Setup (before real-time) let mut resampler = Async::::new_poly( 48000.0 / 44100.0, 1.02, // Allow ±2% clock drift PolynomialDegree::Cubic, 256, // Chunk size from audio interface 2, // Stereo FixedAsync::Input, )?; let max_out = resampler.output_frames_max(); let max_channels = resampler.nbr_channels(); let mut output_buffer = vec![0.0f64; max_out * max_channels]; // Real-time loop (audio capture callback) fn audio_callback(input: &[f64]) { // input.len() == 256 * 2 (256 frames, stereo, interleaved) let input_adapter = InterleavedSlice::new(input, 2, 256).unwrap(); let mut output_adapter = InterleavedSlice::new_mut(&mut output_buffer, 2, max_out).unwrap(); let (in_frames, out_frames) = resampler .process_into_buffer(&input_adapter, &mut output_adapter, None) .unwrap(); // Send out_frames to output at 48 kHz send_to_playback(&output_buffer[..out_frames * 2]); } ``` -------------------------------- ### Batch Processing with FFT Resampler Source: https://github.com/henquist/rubato/blob/master/_autodocs/03-fft-resampler.md Demonstrates how to use the FFT resampler for batch audio processing. This is suitable for fixed sample rate conversions, such as converting audio files from one rate to another. ```rust use rubato::{Fft, FixedSync, Resampler}; use audioadapter_buffers::direct::InterleavedSlice; // Create resampler for 44.1 → 48 kHz, stereo let mut resampler = Fft::::new(44100, 48000, 1024, 2, 2, FixedSync::Both)?; // Process a 1-second audio clip let input_data = vec![0.0f64; 88200]; // 44.1 kHz stereo = 44100 samples/channel let input_len = input_data.len() / 2; let output_len = resampler.process_all_needed_output_len(input_len); let mut output_data = vec![0.0f64; output_len]; let input = InterleavedSlice::new(&input_data, 2, input_len)?; let mut output = InterleavedSlice::new_mut(&mut output_data, 2, output_len)?; let (in_frames, out_frames) = resampler.process_all_into_buffer( &input, &mut output, input_len, None, )?; println!("Processed {} input frames → {} output frames", in_frames, out_frames); ``` -------------------------------- ### Get Next Input/Output Frame Counts Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md Retrieve the number of frames required for the next input or produced by the next output, per channel. This is crucial for determining buffer sizes before processing. ```rust fn input_frames_next(&self) -> usize; fn output_frames_next(&self) -> usize; ``` -------------------------------- ### Create FFT Resampler Instance Source: https://github.com/henquist/rubato/blob/master/_autodocs/03-fft-resampler.md Instantiates a new Fft resampler for fixed sample rate conversions. Ensure the 'fft_resampler' Cargo feature is enabled. The 'blocks' parameter influences quality and latency. ```rust use rubato::{Fft, FixedSync}; let mut resampler = Fft::::new( 44100, // Input sample rate 48000, // Output sample rate 1024, // Chunk size (frames) 2, // Stereo 2, // Number of blocks FixedSync::Both, // Both input and output fixed )?; ``` -------------------------------- ### Get Maximum Input/Output Frame Counts Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md Obtain the maximum possible number of frames per channel that could be required for input or produced for output over the resampler's lifetime. Use these for pre-allocating buffers. ```rust fn input_frames_max(&self) -> usize; fn output_frames_max(&self) -> usize; ``` -------------------------------- ### Get Output Delay (Latency) Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md Determine the number of output frames that correspond to the resampler's internal delay or latency. This value represents how many output frames are produced after an input event before it appears in the output. ```rust fn output_delay(&self) -> usize ``` -------------------------------- ### Async Resampler Constructor: new_sinc Source: https://github.com/henquist/rubato/blob/master/_autodocs/02-async-resampler.md Creates a high-quality asynchronous resampler using sinc-based interpolation with anti-aliasing filtering. This method offers superior audio quality compared to polynomial methods but incurs a higher CPU cost. ```rust pub fn new_sinc( resample_ratio: f64, max_resample_ratio_relative: f64, parameters: &SincInterpolationParameters, chunk_size: usize, nbr_channels: usize, fixed: FixedAsync, ) -> Result ``` ```rust use rubato::{Async, FixedAsync, SincInterpolationParameters, SincInterpolationType, WindowFunction}; let params = SincInterpolationParameters { sinc_len: 256, f_cutoff: 0.95, interpolation: SincInterpolationType::Cubic, oversampling_factor: 128, window: WindowFunction::BlackmanHarris2, }; let mut resampler = Async::::new_sinc( 1.087, 2.0, ¶ms, 1024, 2, FixedAsync::Input, )?; ``` -------------------------------- ### Adapting to Clock Drift with Async Resampler Source: https://github.com/henquist/rubato/blob/master/_autodocs/07-usage-patterns.md Configure the Async resampler with a wide ratio adjustment range to handle real-time streaming where input and output clocks may drift. Monitor frame counts and adjust the resample ratio dynamically to correct for drift. ```rust use rubato::Resampler; // Setup with wide ratio adjustment range let mut resampler = Async::::new_poly( 1.0, // Initial ratio 10.0, // Allow up to 10× ratio adjustment PolynomialDegree::Cubic, 1024, 2, FixedAsync::Input, )?; // Monitoring loop let mut frames_in = 0; let mut frames_out = 0; let mut last_check = 0; let check_interval = 48000 * 10; // Every 10 seconds at 48 kHz for _ in 0..processing_iterations { let (in_f, out_f) = resampler.process_into_buffer(...)?; frames_in += in_f; frames_out += out_f; if frames_out - last_check >= check_interval { // Check actual ratio let measured_ratio = frames_out as f64 / frames_in as f64; let target_ratio = resampler.resample_ratio(); let error = measured_ratio / target_ratio; // Adjust if drift detected if error > 1.01 { // Output is fast, slow it down resampler.set_resample_ratio(target_ratio * 0.99, true)?; } else if error < 0.99 { // Output is slow, speed it up resampler.set_resample_ratio(target_ratio * 1.01, true)?; } last_check = frames_out; } } ``` -------------------------------- ### Full-Featured Rubato Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Enable this configuration for maximum functionality, including both Async and Fft resamplers, and logging for debugging. ```toml [dependencies] rubato = { version = "3.0", features = ["fft_resampler", "log"] } ``` -------------------------------- ### Minimal Rubato Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Use this configuration for the smallest binary size and fastest compile times. It disables the FFT resampler and logging support. ```toml [dependencies] rubato = { version = "3.0", default-features = false } ``` -------------------------------- ### Real-Time Processing with Fixed Output Size (Async Resampler) Source: https://github.com/henquist/rubato/blob/master/_autodocs/07-usage-patterns.md This pattern is suitable for audio playback where a fixed chunk size is required for each callback, such as a playback buffer. Configure the resampler with `FixedAsync::Output` and the desired output chunk size. ```rust use rubato::{Resampler, Async, FixedAsync, PolynomialDegree}; // Setup let mut resampler = Async::::new_poly( 44100.0 / 48000.0, 1.02, PolynomialDegree::Cubic, 512, // Output chunk size (samples per playback callback) 2, // Stereo FixedAsync::Output, )?; let max_in = resampler.input_frames_max(); let mut input_buffer = vec![0.0f64; max_in * 2]; // Real-time playback callback fn playback_callback(output: &mut [f64]) { // output.len() == 512 * 2 (512 frames, stereo, interleaved) // Get input from some capture source let input_frames = resampler.input_frames_next(); let captured = capture_frames(input_frames * 2); // May be < or > input_frames*2 let input_adapter = InterleavedSlice::new(&captured, 2, input_frames).unwrap(); let mut output_adapter = InterleavedSlice::new_mut(output, 2, 512).unwrap(); let (_, out_frames) = resampler .process_into_buffer(&input_adapter, &mut output_adapter, None) .unwrap(); assert_eq!(out_frames, 512); // Always 512 frames with FixedAsync::Output } ``` -------------------------------- ### Running Tests with Logging Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Commands to run Rust tests with different logging levels for debugging. ```bash RUST_LOG=debug cargo test --lib RUST_LOG=trace cargo test -- --nocapture RUST_LOG=rubato=debug cargo test process_all ``` -------------------------------- ### Blackman2 (Squared Blackman) Window Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/06-window-functions.md Use Blackman2 for higher quality than the standard Blackman, providing better attenuation at the cost of a slower rolloff. ```rust let params = SincInterpolationParameters { window: WindowFunction::Blackman2, sinc_len: 256, .. }; ``` -------------------------------- ### Async Resampler Constructor: new_poly Source: https://github.com/henquist/rubato/blob/master/_autodocs/02-async-resampler.md Creates a fast asynchronous resampler using polynomial interpolation. Suitable for applications prioritizing speed over absolute audio fidelity, as it lacks anti-aliasing filtering. ```rust pub fn new_poly( resample_ratio: f64, max_resample_ratio_relative: f64, interpolation_type: PolynomialDegree, chunk_size: usize, nbr_channels: usize, fixed: FixedAsync, ) -> Result ``` ```rust use rubato::{Async, FixedAsync, PolynomialDegree}; let mut resampler = Async::::new_poly( 1.1, // 48 kHz / 44.1 kHz ≈ 1.087 2.0, // Ratio can be adjusted ±2× PolynomialDegree::Cubic, // Balance speed/quality 1024, // Chunk size 2, // Stereo FixedAsync::Input, // Input size fixed at 1024 )?; ``` -------------------------------- ### Hann Window Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/06-window-functions.md Use the Hann window when speed is critical and some aliasing is acceptable. It offers fast rolloff but lower attenuation. ```rust let params = SincInterpolationParameters { window: WindowFunction::Hann, sinc_len: 128, .. }; ``` -------------------------------- ### Mobile Build Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md This configuration enables automatic SIMD detection for mobile targets like iOS and Android. ```toml [dependencies] rubato = "3.0" # Uses NEON on aarch64 ``` -------------------------------- ### Low-Latency Real-Time Processing with Async Resampler Source: https://github.com/henquist/rubato/blob/master/_autodocs/07-usage-patterns.md Use the Async resampler with PolynomialDegree::Linear and a small chunk size for real-time synthesis or effects with minimal delay. The output delay should be approximately 200-400 frames. ```rust use rubato::{Resampler, Async, FixedAsync, PolynomialDegree}; let mut resampler = Async::::new_poly( 1.0, 1.1, PolynomialDegree::Linear, // Fast, acceptable quality 64, // Very small chunk for low latency 1, // Mono FixedAsync::Input, )?; let output_delay = resampler.output_delay(); println!("Latency: {} frames", output_delay); // Should be ~200-400 frames // Use in audio loop let (_, out_frames) = resampler .process_into_buffer(&input, &mut output, None)?; ``` -------------------------------- ### Enable Logging for Tests Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Configure `dev-dependencies` in Cargo.toml to enable the `log` feature specifically for testing environments. ```toml # Enable for tests only [dev-dependencies] rubato = { version = "3.0", features = ["log"] } ``` -------------------------------- ### Process All Into Buffer Signature Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md The process_all_into_buffer method is designed for processing entire audio clips. It internally calls process_into_buffer repeatedly, managing resampler delay and partial frames at the end. ```rust fn process_all_into_buffer<'a, 'b>( &mut self, buffer_in: &dyn Adapter<'a, T>, buffer_out: &mut dyn AdapterMut<'b, T>, input_len: usize, active_channels_mask: Option<&[bool]>, ) -> ResampleResult<(usize, usize)> ``` -------------------------------- ### Internal Buffer Structure (Async) Source: https://github.com/henquist/rubato/blob/master/_autodocs/09-advanced-topics.md Illustrates the layout of the internal buffer for asynchronous processing. It includes samples kept from the previous chunk, new input data, and padding for safety. ```text [overlap][interpolator_len] [interpolator_len] [2*interpolator_len] ↑ kept from ↑ new input data ↑ padding previous chunk added here for safety ``` -------------------------------- ### Enable FFT Resampler Feature Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Configure Cargo.toml to enable the FFT-based synchronous resampler. This is the default behavior. ```toml [dependencies] rubato = { version = "3.0", features = ["fft_resampler"] } ``` -------------------------------- ### Control Log Level with RUST_LOG Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Demonstrates setting the `RUST_LOG` environment variable to control the verbosity of logging output at runtime for different commands. ```bash RUST_LOG=trace cargo run # Trace level RUST_LOG=debug cargo test # Debug level RUST_LOG=info cargo build # Info level RUST_LOG=rubato=debug cargo run # Only rubato at debug ``` -------------------------------- ### Error Handling for Resampler Creation and Processing Source: https://github.com/henquist/rubato/blob/master/_autodocs/07-usage-patterns.md This pattern demonstrates robust error handling for both creating a resampler and processing audio data. It uses `match` statements to gracefully handle potential `ResampleError` variants. ```rust use rubato::{Resampler, Async, FixedAsync, ResampleError, PolynomialDegree}; // Create with error checking let resampler = match Async::::new_poly( 1.088, 1.02, PolynomialDegree::Cubic, 1024, 2, FixedAsync::Input ) { Ok(rs) => rs, Err(e) => { eprintln!("Failed to create resampler: {}", e); std::process::exit(1); } }; // Process with error recovery match resampler.process_into_buffer(&input, &mut output, None) { Ok((in_f, out_f)) => { println!("Processed {} → {} frames", in_f, out_f); } Err(ResampleError::InsufficientInputBufferSize { expected, actual }) => { eprintln!("Input buffer too small: need {}, got {}", expected, actual); // Recover by buffering more input } Err(ResampleError::InsufficientOutputBufferSize { expected, actual }) => { eprintln!("Output buffer too small: need {}, got {}", expected, actual); // Recover by allocating larger output } Err(e) => { eprintln!("Resampling error: {}", e); // Handle other errors } } ``` -------------------------------- ### input_frames_next and output_frames_next Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md These methods return the number of frames required for the next input or produced by the next output, per channel. They are crucial for determining buffer requirements before processing. ```APIDOC ## input_frames_next and output_frames_next ### Description Returns the number of frames required for the next call to `process_into_buffer` (input) or produced from the next call (output), per channel. ### Returns `usize` - Number of frames per channel. ### Notes For fixed-size resamplers, one of these values is constant; for variable-size resamplers, both may change after each call. Always call these methods before providing data to `process_into_buffer` to determine the exact requirements. ``` -------------------------------- ### Blackman Window Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/06-window-functions.md The standard Blackman window is suitable for general-purpose high-quality resampling, offering medium rolloff and medium attenuation. ```rust let params = SincInterpolationParameters { window: WindowFunction::Blackman, sinc_len: 256, .. }; ``` -------------------------------- ### BlackmanHarris2 (Squared Blackman-Harris) Window Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/06-window-functions.md The BlackmanHarris2 window, often the default, offers the slowest rolloff and excellent attenuation, ensuring minimal aliasing artifacts for maximum quality. ```rust let params = SincInterpolationParameters { window: WindowFunction::BlackmanHarris2, // Default sinc_len: 256, .. }; ``` -------------------------------- ### Batch File Processing with Fft Resampler Source: https://github.com/henquist/rubato/blob/master/_autodocs/07-usage-patterns.md Use this pattern to resample an entire audio file with a fixed ratio. It utilizes the Fft resampler with FixedSync::Both for efficient batch processing. Ensure input and output data are interleaved slices. ```rust use rubato::{Resampler, Fft, FixedSync}; use audioadapter_buffers::direct::InterleavedSlice; // Create resampler for fixed 44.1 → 48 kHz conversion let mut resampler = Fft::::new( 44100, 48000, 1024, // Chunk hint 2, // Stereo 2, // Blocks for overlap-add FixedSync::Both, )?; // Load entire file let input_data = load_audio_file("input.wav"); // Vec, interleaved let input_len = input_data.len() / 2; // Number of frames // Calculate output buffer size let output_len = resampler.process_all_needed_output_len(input_len); let mut output_data = vec![0.0f64; output_len]; // Process entire file let input = InterleavedSlice::new(&input_data, 2, input_len)?; let mut output = InterleavedSlice::new_mut(&mut output_data, 2, output_len)?; let (in_processed, out_processed) = resampler.process_all_into_buffer( &input, &mut output, input_len, None, )?; println!("Processed {} input frames → {} output frames", in_processed, out_processed); save_audio_file("output.wav", &output_data[..out_processed * 2]); ``` -------------------------------- ### new_poly Source: https://github.com/henquist/rubato/blob/master/_autodocs/02-async-resampler.md Creates a fast asynchronous resampler using polynomial interpolation. No anti-aliasing filtering is applied, making this significantly faster than sinc-based resampling but with potential artefacts, especially at high frequencies. ```APIDOC ## new_poly ### Description Creates a fast asynchronous resampler using polynomial interpolation. No anti-aliasing filtering is applied, making this significantly faster than sinc-based resampling but with potential artefacts, especially at high frequencies. ### Method `pub fn new_poly( resample_ratio: f64, max_resample_ratio_relative: f64, interpolation_type: PolynomialDegree, chunk_size: usize, nbr_channels: usize, fixed: FixedAsync, ) -> Result` ### Parameters #### Path Parameters - **resample_ratio** (f64) - Required - Initial ratio (output_rate / input_rate), must be > 0 - **max_resample_ratio_relative** (f64) - Required - Maximum relative deviation from initial ratio, must be ≥ 1.0. Ratio can be set to `resample_ratio * max_resample_ratio_relative` (max) or `resample_ratio / max_resample_ratio_relative` (min) - **interpolation_type** (PolynomialDegree) - Required - Polynomial degree for interpolation (Nearest, Linear, Cubic, Quintic, or Septic) - **chunk_size** (usize) - Required - Size of input/output chunks (depending on `fixed` parameter) - **nbr_channels** (usize) - Required - Number of audio channels - **fixed** (FixedAsync) - Required - Whether input or output size is fixed ### Request Example ```rust use rubato::{Async, FixedAsync, PolynomialDegree}; let mut resampler = Async::::new_poly( 1.1, // 48 kHz / 44.1 kHz ≈ 1.087 2.0, // Ratio can be adjusted ±2× PolynomialDegree::Cubic, // Balance speed/quality 1024, // Chunk size 2, // Stereo FixedAsync::Input, // Input size fixed at 1024 )?; ``` ### Response #### Success Response (200) `Result` — A new polynomial-based async resampler or an error if parameters are invalid. ``` -------------------------------- ### BlackmanHarris Window Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/06-window-functions.md The Blackman-Harris window is recommended when very high quality is needed and a slower rolloff is acceptable, offering good attenuation. ```rust let params = SincInterpolationParameters { window: WindowFunction::BlackmanHarris, sinc_len: 256, .. }; ``` -------------------------------- ### Enable Logging Feature Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Configure Cargo.toml to enable the `log` crate integration for debugging purposes. This is disabled by default. ```toml # Development with logging rubato = { version = "3.0", features = ["log"] } ``` -------------------------------- ### Detect x86_64 CPU Features Source: https://github.com/henquist/rubato/blob/master/_autodocs/09-advanced-topics.md Use these macros to detect specific CPU features on x86_64 architectures at runtime. Ensure the `std::arch` module is available. ```rust is_x86_feature_detected!("avx"); is_x86_feature_detected!("sse3"); ``` -------------------------------- ### Fft::new Source: https://github.com/henquist/rubato/blob/master/_autodocs/03-fft-resampler.md Creates a new FFT-based synchronous resampler for fixed sample-rate conversions. The resampling ratio is determined by the input and output sample rates. ```APIDOC ## Fft::new ### Description Creates an FFT-based synchronous resampler. The resampling ratio is fixed at `fs_out / fs_in` and cannot be changed. The `blocks` parameter controls the internal FFT overlap size; higher values can improve quality but increase latency and memory. ### Method ```rust pub fn new( fs_in: usize, fs_out: usize, chunk_size: usize, nbr_channels: usize, blocks: usize, fixed: FixedSync, ) -> Result ``` ### Parameters #### Path Parameters - **fs_in** (`usize`) - Input sample rate (Hz), must be > 0 - **fs_out** (`usize`) - Output sample rate (Hz), must be > 0 - **chunk_size** (`usize`) - Target size for the fixed side (in frames) - **nbr_channels** (`usize`) - Number of audio channels - **blocks** (`usize`) - Number of overlapping FFT blocks to use (typically 2–3) - **fixed** (`FixedSync`) - Which side has fixed chunk size (Input, Output, or Both) ### Response #### Success Response - **Self** (`Fft`) - A new FFT resampler instance. - **ResamplerConstructionError** - An error if sample rates are invalid. ### Request Example ```rust use rubato::{Fft, FixedSync}; let mut resampler = Fft::::new( 44100, // Input sample rate 48000, // Output sample rate 1024, // Chunk size (frames) 2, // Stereo 2, // Number of blocks FixedSync::Both, // Both input and output fixed )?; ``` ``` -------------------------------- ### process_all_into_buffer Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md Processes an entire audio clip by repeatedly calling `process_into_buffer`. This method handles the consumption of all input frames, including managing resampler delay and partial frames at the end. The output buffer must be pre-allocated to a sufficient size. ```APIDOC ## process_all_into_buffer ### Description Convenience method for processing entire audio clips. Internally calls `process_into_buffer` repeatedly until all input frames are consumed, handling resampler delay trimming and partial frames at the end. ### Method `process_all_into_buffer` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **buffer_in** (`&dyn Adapter<'a, T>`) - Required - Input audio buffer - **buffer_out** (`&mut dyn AdapterMut<'b, T>`) - Required - Output audio buffer (must be pre-allocated to sufficient size) - **input_len** (`usize`) - Required - Total number of input frames to process - **active_channels_mask** (`Option<&[bool]>`) - Optional - Which channels to process ### Request Example ```rust use rubato::{Resampler, Fft, FixedSync}; use audioadapter_buffers::direct::InterleavedSlice; let mut resampler = Fft::::new(48000, 44100, 1024, 2, 2, FixedSync::Both)?; let input = vec![0.0f64; 88200]; // 2 seconds at 44.1 kHz, stereo let input_len = input.len() / 2; let output_len = resampler.process_all_needed_output_len(input_len); let mut output = vec![0.0f64; output_len]; let input_adapter = InterleavedSlice::new(&input, 2, input_len)?; let mut output_adapter = InterleavedSlice::new_mut(&mut output, 2, output_len)?; let (in_frames, out_frames) = resampler.process_all_into_buffer( &input_adapter, &mut output_adapter, input_len, None, )?; ``` ### Response #### Success Response (200) `ResampleResult<(usize, usize)>` — Tuple of `(input_len, output_len)` where output_len is the actual resampled length (may differ from input_len due to ratio), or an error. #### Response Example None provided in source. ``` -------------------------------- ### process_into_buffer Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md Resamples audio from an input buffer to a pre-allocated output buffer. This method is designed for real-time processing as it avoids heap allocations. It supports flexible buffer layouts and sample formats via the `audioadapter` crate. ```APIDOC ## process_into_buffer ### Description Resample a buffer of audio to a pre-allocated output buffer. This is the primary method for real-time processing. The input and output buffers use the `audioadapter` crate to support any buffer layout or sample format. The method performs no heap allocations, making it suitable for real-time applications. ### Method `process_into_buffer` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **buffer_in** (`&dyn Adapter<'a, T>`) - Required - Input audio buffer implementing the audioadapter `Adapter` trait - **buffer_out** (`&mut dyn AdapterMut<'b, T>`) - Required - Output audio buffer implementing the audioadapter `AdapterMut` trait - **indexing** (`Option<&Indexing>`) - Optional - Optional indexing parameters (offsets, partial length, channel mask) ### Request Example ```rust use rubato::{Resampler, Fft, FixedSync, Indexing}; use audioadapter_buffers::direct::InterleavedSlice; let mut resampler = Fft::::new(48000, 44100, 1024, 2, 2, FixedSync::Both)?; let input_data = vec![0.0f64; 4096]; let mut output_data = vec![0.0f64; 5000]; let input = InterleavedSlice::new(&input_data, 2, 2048)?; let mut output = InterleavedSlice::new_mut(&mut output_data, 2, 2500)?; let (frames_in, frames_out) = resampler.process_into_buffer(&input, &mut output, None)?; println!("Consumed {} frames, produced {} frames", frames_in, frames_out); ``` ### Response #### Success Response (200) `ResampleResult<(usize, usize)>` — Tuple of `(input_frames_consumed, output_frames_written)` per channel, or a `ResampleError`. #### Response Example None provided in source. ``` -------------------------------- ### Real-Time Rubato Configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/08-feature-flags-and-configuration.md Configure Rubato for real-time-safe applications. This uses the default settings which enable the FFT resampler but disable logging. ```toml rubato = "3.0" # Default: fft_resampler enabled, log disabled [dev-dependencies] env_logger = "0.11" ``` -------------------------------- ### Process Method Signature Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md The process method is a convenience wrapper around process_into_buffer that automatically allocates the output buffer. It is not recommended for real-time use due to potential allocation overhead, but is useful for batch processing. ```rust fn process( &mut self, buffer_in: &dyn Adapter<'_, T>, input_offset: usize, active_channels_mask: Option<&[bool]>, ) -> ResampleResult> ``` -------------------------------- ### process Source: https://github.com/henquist/rubato/blob/master/_autodocs/01-resampler-trait.md A convenience method that wraps `process_into_buffer` by automatically allocating the output buffer. It is suitable for batch processing or scenarios where allocation latency is acceptable, but not recommended for real-time applications. ```APIDOC ## process ### Description A convenience wrapper around `process_into_buffer` that allocates the output buffer automatically. Not recommended for real-time applications due to heap allocation overhead, but useful for batch processing or when allocation latency is acceptable. ### Method `process` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **buffer_in** (`&dyn Adapter<'_, T>`) - Required - Input audio buffer - **input_offset** (`usize`) - Required - Number of frames to skip at the start of input - **active_channels_mask** (`Option<&[bool]>`) - Optional - Which channels to process (true = process, false = skip) ### Request Example None provided in source. ### Response #### Success Response (200) `ResampleResult>` — Newly allocated output buffer containing resampled audio, or an error. #### Response Example None provided in source. ```