### Slip Constructor Example Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Slip.md Creates a new Slip instance for stereo audio with the output side fixed. This is useful when the device callback size is known and fixed. ```rust use rubato::Slip; // Create slip for stereo audio, fixed output (device callback size) let slip = Slip::::new(512, 2, FixedAsync::Output)?; ``` -------------------------------- ### Adaptive Real-time Processing with Adjustable and Resizable Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Adjustable-Resizable.md Example demonstrating runtime adaptation of a resampler's chunk size and ratio based on system state like buffer fill. ```rust use rubato::{Async, Adjustable, Resizable}; let mut resampler = /* ... */; // Runtime adaptation based on system state let buffer_fill = input_buffer.len(); let is_full = buffer_fill > 80% of capacity; if is_full { // Reduce chunk size to respond faster if let Some(r) = resampler.as_resizable() { r.set_chunk_size(256)?; } // Speed up processing if let Some(a) = resampler.as_adjustable() { a.set_resample_ratio_relative(0.95, true)?; } } ``` -------------------------------- ### Example: Using set_chunk_size on Async Resampler Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Adjustable-Resizable.md Demonstrates how to use `set_chunk_size` to reduce the chunk size of an `Async` resampler. Note that the chunk size cannot exceed the construction maximum. ```rust use rubato::{Async, FixedAsync, PolynomialDegree, Resizable}; let mut resampler = Async::::new_poly( 2.0, 1.1, PolynomialDegree::Cubic, 1024, // Maximum chunk size 2, FixedAsync::Input, )?; // Can reduce resampler.set_chunk_size(512)?; // OK resampler.set_chunk_size(256)?; // OK // Cannot exceed construction maximum resampler.set_chunk_size(2048)?; // Error ``` -------------------------------- ### Set Resample Ratio Example Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Adjustable-Resizable.md Demonstrates how to change the resampling ratio to an absolute value using the set_resample_ratio method. Use ramp=true for smooth transitions and ramp=false for immediate application. ```rust use rubato::{Async, FixedAsync, PolynomialDegree, Adjustable}; let mut resampler = Async::::new_poly( 2.0, // original ratio 1.1, // max_relative = 1.1 PolynomialDegree::Cubic, 1024, 2, FixedAsync::Input, )?; // Valid: 2.0 / 1.1 ≤ ratio ≤ 2.0 * 1.1 // i.e., 1.818 ≤ ratio ≤ 2.2 resampler.set_resample_ratio(1.9, false)?; // OK resampler.set_resample_ratio(2.1, true)?; // OK with ramping resampler.set_resample_ratio(2.5, false)?; // Error: exceeds 2.2 ``` -------------------------------- ### Resampler Constructors Source: https://github.com/henquist/rubato/blob/master/_autodocs/DELIVERY_SUMMARY.txt Documentation for the constructors available for different resampler types, including parameters, errors, and examples. ```APIDOC ## Async::new_poly() ### Description Constructs a new asynchronous polynomial resampler. ### Method ``` Async::new_poly(parameters...) ``` ### Parameters Detailed parameter table including name, type, default value, and description. ### Return Type Returns an instance of an asynchronous polynomial resampler or a `ResamplerConstructionError`. ### Error Conditions Specifies the conditions under which `ResamplerConstructionError` can occur. ### Examples Provides 2-5 worked code examples demonstrating usage. ``` ```APIDOC ## Async::new_sinc() ### Description Constructs a new asynchronous sinc resampler. ### Method ``` Async::new_sinc(parameters...) ``` ### Parameters Detailed parameter table including name, type, default value, and description. ### Return Type Returns an instance of an asynchronous sinc resampler or a `ResamplerConstructionError`. ### Error Conditions Specifies the conditions under which `ResamplerConstructionError` can occur. ### Examples Provides 2-5 worked code examples demonstrating usage. ``` ```APIDOC ## Fft::new() ### Description Constructs a new synchronous FFT resampler. ### Method ``` Fft::new(parameters...) ``` ### Parameters Detailed parameter table including name, type, default value, and description. ### Return Type Returns an instance of a synchronous FFT resampler or a `ResamplerConstructionError`. ### Error Conditions Specifies the conditions under which `ResamplerConstructionError` can occur. ### Examples Provides 2-5 worked code examples demonstrating usage. ``` ```APIDOC ## Fft::new_custom() ### Description Constructs a new synchronous FFT resampler with custom parameters. ### Method ``` Fft::new_custom(parameters...) ``` ### Parameters Detailed parameter table for advanced custom parameters, including name, type, default value, and description. ### Return Type Returns an instance of a synchronous FFT resampler or a `ResamplerConstructionError`. ### Error Conditions Specifies the conditions under which `ResamplerConstructionError` can occur. ### Examples Provides worked code examples demonstrating advanced usage. ``` ```APIDOC ## Slip::new() ### Description Constructs a new frame-slip clutch resampler. ### Method ``` Slip::new(parameters...) ``` ### Parameters Detailed parameter table including name, type, default value, and description. ### Return Type Returns an instance of a frame-slip clutch resampler or a `ResamplerConstructionError`. ### Error Conditions Specifies the conditions under which `ResamplerConstructionError` can occur. ### Examples Provides 2-5 worked code examples demonstrating usage. ``` -------------------------------- ### Example: InvalidRatio Error (Zero Sample Rate) Source: https://github.com/henquist/rubato/blob/master/_autodocs/errors.md Demonstrates a failure when creating an Fft resampler with a zero input sample rate. ```rust // Also fails for Fft: sample rates must be > 0 Fft::::new(0, 48000, 1024, 2, FixedSync::Input)? ``` -------------------------------- ### Audio Interface Clock Synchronization with Slip Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Slip.md This example demonstrates how to use the Slip resampler to synchronize an audio interface's output clock to a slightly faster input clock. It involves monitoring buffer fill levels and adjusting the resampler's ratio to maintain synchronization, suitable for embedded or real-time systems with tight CPU limits. ```rust use rubato::{Slip, FixedAsync, Resampler, Adjustable}; // A sound card output that runs slightly fast (consumer clock 50 ppm ahead) // needs to stay in sync with an input that runs at nominal rate. let mut slip = Slip::::new(512, 2, FixedAsync::Output)?; // Monitor input buffer fill and steer the ratio let target_fill = 10240; // ~10ms at 48kHz let max_error = 5120.0; // ±5ms allowed let mut measurement_count = 0; let mut accumulated_error = 0.0; for cycle in 0..10000 { // Query resampler let frames_in = slip.input_frames_next(); let frames_out = slip.output_frames_next(); // Fixed at 512 // Read from input let input = read_input_buffer(frames_in); // Process (slip hides corrections) let mut output = vec![vec![0.0; frames_out]; 2]; slip.process_into_buffer(&input_adapter, &mut output_adapter, None)?; // Write to device device.write(&output)?; // Measure buffer fill every 100 cycles (to smooth noise) if cycle % 100 == 0 { let current_fill = input_buffer.approximate_fill() as f64; let error = current_fill - target_fill as f64; accumulated_error += error; measurement_count += 1; if measurement_count >= 10 { let avg_error = accumulated_error / measurement_count as f64; let adjustment = 1.0 - 1e-6 * avg_error / max_error; slip.set_resample_ratio(adjustment, true)?; accumulated_error = 0.0; measurement_count = 0; } } } ``` -------------------------------- ### Configure FFT Resampler with Standard Constructor Source: https://github.com/henquist/rubato/blob/master/_autodocs/configuration.md Use the standard constructor for basic FFT resampler setup. Ensure input and output rates are greater than 0. The chunk size is a target and may be adjusted. ```rust pub fn Fft::::new( input_rate: usize, output_rate: usize, chunk_size: usize, nbr_channels: usize, fixed: FixedSync, ) -> Result where T: Sample, ``` ```rust use rubato::{Fft, FixedSync, Resampler}; // Convert 44.1 kHz to 48 kHz stereo let mut resampler = Fft::::new( 44100, // input rate 48000, // output rate 1024, // target chunk size 2, // stereo FixedSync::Both, // Both fixed (best efficiency) )?; ``` -------------------------------- ### Async Sinc Resampler Constructor (Custom Parameters) Source: https://github.com/henquist/rubato/blob/master/_autodocs/configuration.md Constructs an asynchronous resampler using sinc interpolation with custom parameters for fine-tuning quality and performance. This example demonstrates adjusting oversampling and interpolation types for specific needs. ```rust let params = SincInterpolationParameters::new(256, WindowFunction::BlackmanHarris2) .oversampling_factor(256) // More interpolation points for quality .interpolation(SincInterpolationType::Linear); // Faster but lower quality let mut resampler = Async::::new_sinc( 48000.0 / 44100.0, 1.1, ¶ms, 1024, 2, FixedAsync::Input, )?; ``` -------------------------------- ### Async Resample Stereo Audio Chunk by Chunk Source: https://github.com/henquist/rubato/blob/master/README.md Resamples stereo audio from one sample rate to another, processing one chunk at a time. This example uses the Async resampler with polynomial interpolation and is suitable for streaming or file-based processing where data is read in chunks. ```rust use rubato::{ Resampler, Async, FixedAsync, PolynomialDegree, Indexing }; use audioadapter_buffers::direct::InterleavedSlice; let channels = 2; let chunk_size = 1024; let mut resampler = Async::::new_poly( 48000.0 / 44100.0, 1.1, PolynomialDegree::Cubic, chunk_size, channels, FixedAsync::Input, ).unwrap(); // Reusable buffers for a single chunk, assuming interleaved f64 samples. // With `FixedAsync::Input` every call consumes `chunk_size` input frames and // produces at most `output_frames_max()` output frames. let mut indata = vec![0.0; channels * chunk_size]; let mut outdata = vec![0.0; channels * resampler.output_frames_max()]; let outdata_capacity = outdata.len() / channels; let indexing = Indexing::new(); // Keep processing for as long as there is more audio to handle. // Here the source is a dummy counter that stops after a few chunks; // in a real application this stands in for "is there more data?". let mut chunks_left = 10; loop { // Fetch the next `input_frames_next()` frames from the source into `indata`. // For a file, break out of the loop once the end is reached (a shorter final // chunk is handled by setting `partial_len` on the indexing struct, see the // `process_f64` example). For an endless stream, simply never break. if chunks_left == 0 { break; } chunks_left -= 1; let frames_to_read = resampler.input_frames_next(); // (read `frames_to_read` frames from the file or stream into `indata` here) let input_adapter = InterleavedSlice::new(&indata, channels, frames_to_read).unwrap(); let mut output_adapter = InterleavedSlice::new_mut(&mut outdata, channels, outdata_capacity).unwrap(); let (_frames_read, frames_written) = resampler .process_into_buffer(&input_adapter, &mut output_adapter, Some(&indexing)) .unwrap(); // Write the `frames_written` output frames to the destination file or stream. let _ = frames_written; } ``` -------------------------------- ### Example: InvalidSampleRate Error Source: https://github.com/henquist/rubato/blob/master/_autodocs/errors.md Demonstrates a scenario where creating an Fft resampler fails due to an invalid output sample rate of 0. ```rust // Fails: output rate is 0 Fft::::new(44100, 0, 1024, 2, FixedSync::Input)? ``` -------------------------------- ### Clock Drift Feedback Loop Example in Rust Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Slip.md This snippet demonstrates a complete feedback loop for clock drift compensation using the Slip resampler. It simulates audio device behavior and uses a proportional controller to adjust the resampling ratio, ensuring synchronization. Ensure you have the `rubato` and `audioadapter-buffers` crates included in your project. ```rust use rubato::{Slip, FixedAsync, Resampler, Adjustable}; use audioadapter_buffers::direct::SequentialSliceOfVecs; // Mock sound card plus source (producer/consumer simulation) struct Backend { period: usize, // Fixed buffer size the card asks us to fill consumer_ratio: f64, // Card clock relative to nominal (e.g., 1.0001 = 100 ppm fast) input_fill: f64, // Input frames buffered, waiting to be consumed } impl Backend { // Block until the card wants the next buffer // While we waited, the source topped up the input buffer fn wait_for_device(&mut self) -> Vec> { self.input_fill += self.period as f64 / self.consumer_ratio; vec![vec![0.0; self.period]; 2] } // Take `frames` frames out of the input buffer to feed the resampler fn read_source(&mut self, frames: usize) -> Vec> { self.input_fill -= frames as f64; vec![vec![0.0; frames]; 2] } // Hand the filled buffer back to the card to be played fn play(&mut self, _buffer: Vec>) {} // Feedback: how far the input buffer has drifted from its starting fill fn rate_error(&self) -> f64 { self.input_fill } } // Main loop let mut backend = Backend { period: 512, consumer_ratio: 1.0001, // Card clock 100 ppm fast input_fill: 0.0, }; let mut slip = Slip::::new(backend.period, 2, FixedAsync::Output)?; let gain = 1e-5; // Proportional controller gain for _ in 0..1000 { // Get output buffer from card let mut output_data = backend.wait_for_device(); // Read input based on resampler requirement let frames_in = slip.input_frames_next(); let input_data = backend.read_source(frames_in); // Resample (slip adjusts sync) let input = SequentialSliceOfVecs::new(&input_data, 2, frames_in)?; let mut output = SequentialSliceOfVecs::new_mut(&mut output_data, 2, backend.period)?; slip.process_into_buffer(&input, &mut output, None)?; // Hand buffer to card backend.play(output_data); // Feedback control: measure input buffer fill and adjust ratio // Draining input buffer means we're consuming too fast; raise the ratio // to take fewer input frames per output chunk (and vice versa) let error = backend.rate_error(); slip.set_resample_ratio(1.0 - gain * error, false)?; } // After convergence, the input buffer stays bounded and the loop tracks the card's clock assert!((slip.resample_ratio() - backend.consumer_ratio).abs() < 1e-3); assert!(backend.rate_error().abs() < 50.0); ``` -------------------------------- ### Process with Input and Output Offsets Source: https://github.com/henquist/rubato/blob/master/_autodocs/configuration.md Shows how to use the `Indexing` struct to process a sub-region of a larger buffer by specifying input and output offsets. This skips initial frames in the input and starts writing at a specific frame in the output. ```rust use rubato::{Indexing, Resampler}; // Process a sub-region of a larger buffer let indexing = Indexing::new() .input_offset(512) // Skip first 512 frames .output_offset(256); // Write starting at frame 256 resampler.process_into_buffer(&input, &mut output, Some(&indexing))?; ``` -------------------------------- ### Example: InvalidRatio Error (Zero Ratio) Source: https://github.com/henquist/rubato/blob/master/_autodocs/errors.md Illustrates a failure case when constructing an Async resampler with a resample_ratio of 0.0. ```rust // Fails: ratio is 0 (invalid) or negative Async::new_poly(0.0, 1.1, PolynomialDegree::Cubic, 1024, 2, FixedAsync::Input)? ``` -------------------------------- ### Convert 64-bit Float Raw Samples to WAV Source: https://github.com/henquist/rubato/blob/master/README.md Use the `sox` command-line tool to convert processed 64-bit floating-point raw audio samples back into a WAV file. This example specifies a target sample rate of 44.1 kHz and 16-bit signed integer format. ```sh sox -e floating-point -b 64 -r 44100 -c 2 resampler_output.raw -e signed-integer -b 16 some_file_resampled.wav ``` -------------------------------- ### Example: InvalidRelativeRatio Error Source: https://github.com/henquist/rubato/blob/master/_autodocs/errors.md Shows how creating an Async resampler fails when the max_resample_ratio_relative is less than 1.0. ```rust // Fails: 0.5 < 1.0 Async::new_poly(2.0, 0.5, PolynomialDegree::Cubic, 1024, 2, FixedAsync::Input)? ``` -------------------------------- ### Example: InvalidChunkSize Error Source: https://github.com/henquist/rubato/blob/master/_autodocs/errors.md Shows a scenario where creating an Async resampler fails because the chunk_size is set to 0. ```rust // Fails: chunk_size must be >= 1 Async::new_poly(2.0, 1.1, PolynomialDegree::Cubic, 0, 2, FixedAsync::Input)? ``` -------------------------------- ### Real-time Streaming with Fixed Input Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Demonstrates a real-time streaming pattern using an asynchronous resampler with a fixed input size. It shows how to initialize the resampler, determine frame counts, and process data in a loop. ```rust use rubato::{Resampler, Async, FixedAsync, PolynomialDegree}; let mut resampler = Async::::new_poly(2.0, 1.1, PolynomialDegree::Cubic, 1024, 2, FixedAsync::Input)?; let frames_in = resampler.input_frames_next(); // Always 1024 let frames_out_max = resampler.output_frames_max(); let mut input = vec![vec![0.0; frames_in]; 2]; let mut output = vec![vec![0.0; frames_out_max]; 2]; loop { // Fill input... let frames_out = resampler.output_frames_next(); // May vary let (_, written) = resampler.process_into_buffer(&input_adapter, &mut output_adapter, None)?; // Send written frames to output... } ``` -------------------------------- ### Get Number of Channels Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Returns the number of channels the resampler is configured for. This is used to correctly size output buffers. ```rust fn nbr_channels(&self) -> usize ``` ```rust let channels = resampler.nbr_channels(); let mut output = vec![vec![0.0; output_frames_max]; channels]; ``` -------------------------------- ### Real-Time Async Resampler Usage Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Async.md This snippet shows the typical workflow for using the Async resampler in a real-time audio application. It covers creating the resampler, pre-allocating buffers, processing audio frames in a loop, and adjusting the resample ratio based on buffer fill. ```rust use rubato::{Async, FixedAsync, PolynomialDegree, Resampler, Adjustable}; use audioadapter_buffers::direct::SequentialSliceOfVecs; // 1. Create resampler let mut resampler = Async::::new_poly( 48000.0 / 44100.0, 1.1, PolynomialDegree::Cubic, 1024, 2, FixedAsync::Output, // Fixed output for device )?; // 2. Pre-allocate buffers let frames_in_max = resampler.input_frames_max(); let frames_out = resampler.output_frames_next(); // Fixed let mut input_data = vec![vec![0.0; frames_in_max]; 2]; let mut output_data = vec![vec![0.0; frames_out]; 2]; // 3. Processing loop for _ in 0..1000 { // Get required input frames let frames_in = resampler.input_frames_next(); // Fill input from source for frame in 0..frames_in { input_data[0][frame] = source.read_mono(); input_data[1][frame] = source.read_mono(); } // Process let input = SequentialSliceOfVecs::new(&input_data, 2, frames_in)?; let mut output = SequentialSliceOfVecs::new_mut(&mut output_data, 2, frames_out)?; resampler.process_into_buffer(&input, &mut output, None)?; // Send to device (exactly frames_out frames, no buffering needed) device.write(&output_data, frames_out)?; // Optionally: measure buffer fill and adjust ratio let error = buffer_fill as i64 - target_fill; let adj = 1.0 - 0.0001 * error as f64; // Proportional controller if let Some(adj) = resampler.as_adjustable() { let _ = adj.set_resample_ratio_relative(adj, true); } } ``` -------------------------------- ### Batch File Conversion with Fft Resampler Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Fft.md This snippet demonstrates how to resample an entire audio file using the Fft resampler. It includes loading input data, creating a resampler instance with specified parameters, processing all input frames, and saving the output. Note that file I/O is simplified for brevity. ```rust use rubato::{Fft, FixedSync, Resampler}; use std::fs; fn resample_file(input_path: &str, output_path: &str, target_rate: usize) -> Result<(), Box> { // Load input (simplified; real code would use wav crate) let input_rate = 44100; let input_data = vec![vec![0.0; 44100 * 2]; 2]; // 2 seconds stereo // Create resampler let mut resampler = Fft::::new( input_rate, target_rate, 4096, 2, FixedSync::Both, )?; // Resample entire file let input_adapter = audioadapter_buffers::direct::SequentialSliceOfVecs::new( &input_data, 2, input_data[0].len(), )?; let output = resampler.process_all(&input_adapter, input_data[0].len(), None)?; // Save output (simplified; real code would use wav crate) println!("Resampled {} frames to {}", input_data[0].len(), output.frames()); Ok(()) } ``` -------------------------------- ### Get Maximum Input Frames Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Returns the maximum possible input frames per channel. This value is useful for pre-allocating buffers and changes only if `set_chunk_size()` is called. ```rust fn input_frames_max(&self) -> usize ``` -------------------------------- ### Async Resampler Constructors and Methods Source: https://github.com/henquist/rubato/blob/master/_autodocs/MANIFEST.txt The Async resampler offers constructors for polynomial and sinc interpolation, and implements all methods from the Resampler, Adjustable, and Resizable traits. ```APIDOC ## Async Resampler ### Description An asynchronous resampler implementation supporting polynomial and sinc interpolation. It adheres to the Resampler, Adjustable, and Resizable traits, offering flexibility in input/output handling. ### Constructors - `Async::new_poly(sample_rate_in, sample_rate_out, degree)`: Creates a new polynomial-based asynchronous resampler. - `Async::new_sinc(sample_rate_in, sample_rate_out, params)`: Creates a new sinc-based asynchronous resampler with specified parameters. ### Methods Implements all methods from the `Resampler`, `Adjustable`, and `Resizable` traits. Specific behaviors for fixed input/output sides are detailed in `api-reference/Async.md`. ``` -------------------------------- ### Get Maximum Output Frames Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Returns the maximum possible output frames per channel. This is always greater than or equal to `output_frames_next()`, and is useful for pre-allocating output buffers. ```rust fn output_frames_max(&self) -> usize ``` ```rust let max_out = resampler.output_frames_max(); let mut output = vec![vec![0.0; max_out]; nbr_channels]; // Can reuse for all calls ``` -------------------------------- ### Combine Multiple Indexing Options Source: https://github.com/henquist/rubato/blob/master/_autodocs/configuration.md Shows how to combine multiple `Indexing` options to control input/output offsets, partial chunk length, and channel masks simultaneously for complex processing scenarios. ```rust // Combine multiple options let indexing = Indexing::new() .input_offset(100) .output_offset(200) .partial_len(512) .active_channels_mask(vec![true; resampler.nbr_channels()]); resampler.process_into_buffer(&input, &mut output, Some(&indexing))?; ``` -------------------------------- ### Get Next Output Frames Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Returns the exact number of output frames that will be produced by the next `process_into_buffer` call. For FixedAsync::Output, this is always the configured chunk size. ```rust fn output_frames_next(&self) -> usize ``` ```rust let frames_out = resampler.output_frames_next(); let mut output = vec![0.0; frames_out]; resampler.process_into_buffer(&input_adapter, &mut output_adapter, None)? ``` -------------------------------- ### Real-time Processing with Pre-validated Buffer Sizes Source: https://github.com/henquist/rubato/blob/master/_autodocs/errors.md Illustrates setting up a resampler and pre-validating buffer sizes to avoid errors during continuous real-time processing loops. This pattern is suitable for scenarios where buffer sizes are stable. ```rust let mut resampler = Async::new_poly(2.0, 1.1, PolynomialDegree::Cubic, 1024, 2, FixedAsync::Input)?; let frames_in = resampler.input_frames_next(); let frames_out = resampler.output_frames_next(); let mut input = vec![vec![0.0; frames_in]; 2]; let mut output = vec![vec![0.0; frames_out]; 2]; // Now processing will not fail on buffer size loop { resampler.process_into_buffer(&input_adapter, &mut output_adapter, None) .expect("Buffer sizes pre-validated"); } ``` -------------------------------- ### Async Sinc Resampler Constructor (Default Parameters) Source: https://github.com/henquist/rubato/blob/master/_autodocs/configuration.md Constructs an asynchronous resampler using sinc interpolation with default high-quality parameters. This is suitable for applications requiring high fidelity audio resampling. The `SincInterpolationParameters` are configured for optimal quality. ```rust pub fn Async::::new_sinc( resample_ratio: f64, max_resample_ratio_relative: f64, parameters: &SincInterpolationParameters, chunk_size: usize, nbr_channels: usize, fixed: FixedAsync, ) -> Result where T: Sample, ``` ```rust use rubato::{Async, FixedAsync, SincInterpolationParameters, WindowFunction}; // Default high-quality sinc parameters let params = SincInterpolationParameters::new(256, WindowFunction::BlackmanHarris2); let mut resampler = Async::::new_sinc( 48000.0 / 44100.0, 1.1, ¶ms, 1024, 2, FixedAsync::Input, )?; ``` -------------------------------- ### Get Output Delay Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Returns the resampler's internal delay in terms of output frames. Events in the input appear in the output delayed by this amount. For Slip, the delay is always 0. ```rust fn output_delay(&self) -> usize ``` ```rust let delay = resampler.output_delay(); println!("Delay: {} output frames", delay); // For manual alignment in streaming: // Input frame N appears at output frame N + delay (in output sample rate domain) ``` -------------------------------- ### Get Resample Ratio Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Returns the current resample ratio, calculated as output sample rate divided by input sample rate. This value is useful for understanding the scaling factor between input and output. ```rust fn resample_ratio(&self) -> f64 ``` ```rust let ratio = resampler.resample_ratio(); println!("Ratio: {:.3}", ratio); // e.g., 1.088 for 44.1→48kHz ``` -------------------------------- ### Change Chunk Size Source: https://github.com/henquist/rubato/blob/master/_autodocs/configuration.md Demonstrates changing the chunk size of a resampler. The chunk size can be reduced but not increased beyond the initial maximum. This example assumes the resampler was created with a maximum chunk size of 1024. ```rust use rubato::Resizable; // Created with max chunk size 1024 let mut resampler = Async::new_poly(2.0, 1.1, PolynomialDegree::Cubic, 1024, 2, FixedAsync::Input)?; // Can reduce resampler.set_chunk_size(512)?; // Cannot increase resampler.set_chunk_size(2048)?; ``` -------------------------------- ### Create Custom Fft Resampler Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Fft.md Use `Fft::new_custom` for fine-grained control over the resampler's configuration, including the number of sub-chunks and the anti-aliasing window function. This allows for tuning quality and performance. ```rust use rubato::{Fft, FixedSync, WindowFunction}; // Fine-tuned for maximum quality let resampler = Fft::::new_custom( 44100, 48000, 4096, // larger chunks 4, // more sub-chunks for better overlap 2, WindowFunction::BlackmanHarris2, // best quality FixedSync::Both, )?; ``` -------------------------------- ### One-Shot File Conversion with Rubato FFT Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Fft.md Use this snippet to resample an entire audio file in a single operation. It's recommended for files that fit into memory as it automatically handles startup delay trimming and returns the exact output length. ```rust use rubato::{Fft, FixedSync, Resampler}; use audioadapter_buffers::direct::SequentialSliceOfVecs; // Load entire input file into memory let input_data: Vec> = load_wav_file("input.wav")?; // e.g., 44100 Hz, 2 channels let input_len = input_data[0].len(); // Create resampler: 44.1 kHz → 48 kHz let mut resampler = Fft::::new( 44100, 48000, 4096, // larger chunk for efficiency 2, FixedSync::Both, // best for fixed ratio )?; // Resample in one call (automatically handles startup delay trimming) let input_adapter = SequentialSliceOfVecs::new(&input_data, 2, input_len)?; let output = resampler.process_all(&input_adapter, input_len, None)?; // Save resampled output save_wav_file("output.wav", &output)?; ``` -------------------------------- ### Get Next Input Frames Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Returns the exact number of input frames required for the next `process_into_buffer` call. The behavior varies based on the resampler's configuration (FixedAsync::Input, FixedAsync::Output, or FixedSync). ```rust fn input_frames_next(&self) -> usize ``` ```rust let frames_needed = resampler.input_frames_next(); let mut input = vec![0.0; frames_needed]; // Fill input buffer... resampler.process_into_buffer(&input_adapter, &mut output_adapter, None)?; ``` -------------------------------- ### output_delay Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Returns the resampler's internal delay, expressed in output frames. Input events are delayed by this amount before appearing in the output. For 'Slip', this is always 0. When used with `process_all`, the result is automatically trimmed to start at frame 0. ```APIDOC ## output_delay ### Description Returns the resampler's internal delay, reported as number of output frames. Events in the input appear in the output delayed by this amount. ### Note for Slip Always returns 0 (no delay; Slip passes samples through). ### Use in process_all The returned value is automatically trimmed, so the result starts at frame 0 corresponding to input frame 0. ### Example ```rust let delay = resampler.output_delay(); println!("Delay: {} output frames", delay); // For manual alignment in streaming: // Input frame N appears at output frame N + delay (in output sample rate domain) ``` ``` -------------------------------- ### Create Standard Fft Resampler Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Fft.md Use `Fft::new` to create a synchronous FFT resampler with automatic sub-chunk selection and default anti-aliasing window. This is suitable for common file conversion tasks where the sample rate ratio is known. ```rust use rubato::{Fft, FixedSync}; // Convert 44.1 kHz to 48 kHz, stereo, fixed both input and output let resampler = Fft::::new( 44100, 48000, 1024, // target, will be adjusted 2, // stereo FixedSync::Both, // most efficient for fixed ratio )?; ``` -------------------------------- ### Create Async Sinc Resampler with Customized Parameters Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Async.md Creates an asynchronous sinc resampler with customized filter parameters for optimized speed and quality. This allows fine-tuning of the sinc length, window function, and oversampling factor. ```rust use rubato::{Async, FixedAsync, SincInterpolationParameters, SincInterpolationType, WindowFunction}; // Customized for speed while maintaining quality let fast_params = SincInterpolationParameters::new(128, WindowFunction::Hann) .interpolation(SincInterpolationType::Linear) .oversampling_factor(64); let faster_resampler = Async::::new_sinc( 1.0, 1.05, &fast_params, 1024, 2, FixedAsync::Output, )?; ``` -------------------------------- ### Low-CPU Real-time Resampling for Voice Source: https://github.com/henquist/rubato/blob/master/_autodocs/configuration.md Employ the `Async` resampler with `PolynomialDegree::Linear` for low-CPU, real-time audio processing, suitable for voice or gaming. This offers acceptable quality with minimal processing overhead. ```rust use rubato::{Async, FixedAsync, PolynomialDegree}; // Fast polynomial: least CPU, acceptable for voice let mut resampler = Async::::new_poly( 1.0, 1.1, PolynomialDegree::Linear, // Fast but lower quality 512, 1, // Mono for voice FixedAsync::Output, )?; ``` -------------------------------- ### Real-time streaming with fixed input Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Demonstrates how to use the Resampler for real-time audio streaming with a fixed input size. This pattern is suitable for continuous audio processing where input frames are consistently available. ```APIDOC ## Real-time streaming with fixed input ### Description This usage pattern shows how to set up and use the Resampler for real-time audio processing with a fixed input buffer size. It's ideal for scenarios where audio is continuously streamed and processed in chunks. ### Usage ```rust use rubato::{Resampler, Async, FixedAsync, PolynomialDegree}; let mut resampler = Async::::new_poly(2.0, 1.1, PolynomialDegree::Cubic, 1024, 2, FixedAsync::Input)?; let frames_in = resampler.input_frames_next(); // Always 1024 let frames_out_max = resampler.output_frames_max(); let mut input = vec![vec![0.0; frames_in]; 2]; let mut output = vec![vec![0.0; frames_out_max]; 2]; loop { // Fill input... let frames_out = resampler.output_frames_next(); // May vary let (_, written) = resampler.process_into_buffer(&input_adapter, &mut output_adapter, None)?; // Send written frames to output... } ``` ``` -------------------------------- ### Per-call configuration Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Illustrates how to configure the Resampler's behavior on a per-call basis using the `Indexing` struct. This allows for dynamic adjustments like skipping channels or specifying partial output lengths. ```APIDOC ## Per-call configuration ### Description This section demonstrates how to customize the `process_into_buffer` method's behavior for individual calls using the `Indexing` struct. This enables fine-grained control over channel selection and output chunk sizing. ### Usage ```rust use rubato::Indexing; // Skip channels during processing let indexing = Indexing::new().active_channels_mask(vec![true, false]); resampler.process_into_buffer(&input, &mut output, Some(&indexing))?; // Final partial chunk let indexing = Indexing::new().partial_len(256); resampler.process_into_buffer(&input, &mut output, Some(&indexing))?; ``` ``` -------------------------------- ### Per-Call Configuration for Resampler Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Shows how to configure resampler behavior on a per-call basis using the `Indexing` struct. This includes skipping channels and processing a final partial chunk. ```rust use rubato::Indexing; // Skip channels during processing let indexing = Indexing::new().active_channels_mask(vec![true, false]); resampler.process_into_buffer(&input, &mut output, Some(&indexing))?; // Final partial chunk let indexing = Indexing::new().partial_len(256); resampler.process_into_buffer(&input, &mut output, Some(&indexing))?; ``` -------------------------------- ### Configure FFT Resampler with Custom Constructor Source: https://github.com/henquist/rubato/blob/master/_autodocs/configuration.md Use the custom constructor for fine-grained control over FFT resampler parameters, including sub-chunks and window function. BlackmanHarris2 is recommended for optimal quality. ```rust pub fn Fft::::new_custom( input_rate: usize, output_rate: usize, chunk_size: usize, sub_chunks: usize, nbr_channels: usize, window: WindowFunction, fixed: FixedSync, ) -> Result where T: Sample, ``` ```rust use rubato::{Fft, FixedSync, WindowFunction}; // Fine-grained control over FFT resampler let mut resampler = Fft::::new_custom( 44100, 48000, 1024, 4, // more sub-chunks for better overlap 2, WindowFunction::BlackmanHarris2, // best anti-aliasing FixedSync::Both, )?; ``` -------------------------------- ### Enable Logging Feature Source: https://github.com/henquist/rubato/blob/master/_autodocs/configuration.md Enable logging via the `log` crate for debugging purposes by specifying the `log` feature in the `rubato` dependency. ```toml rubato = { version = "4.0", features = ["log"] } ``` -------------------------------- ### process_all Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Allocating wrapper around `process_all_into_buffer`. Resamples entire clip and returns precisely-sized output without padding. ```APIDOC ## process_all ### Description Allocating wrapper around `process_all_into_buffer`. Resamples entire clip and returns precisely-sized output without padding. ### Method (Not specified, likely a Rust method call) ### Parameters #### Input Buffer - **buffer_in** (`&dyn Adapter`) - Required - Input clip buffer. #### Input Length - **input_len** (`usize`) - Required - Number of input frames to resample. #### Active Channels Mask - **active_channels_mask** (`Option<&[bool]>`) - Optional - Channel processing mask. ### Return Type - `InterleavedOwned` - Owned buffer with exact resampled length (no padding) ### Errors Same as `process_all_into_buffer` ### Behavior Internally calls `reset()` before processing, so result is independent of prior use. ### Example ```rust let mut resampler = Fft::::new(44100, 48000, 1024, 2, FixedSync::Both)?; // Process entire file at once let input = /* load from file */; let output = resampler.process_all(&input, input_len, None)?; // Output has exactly the resampled frames, nothing extra assert_eq!(output.frames(), (input_len as f64 * 48000.0 / 44100.0).ceil() as usize); ``` ``` -------------------------------- ### Enable fft_resampler Feature Source: https://github.com/henquist/rubato/blob/master/_autodocs/configuration.md Enable the FFT-based synchronous resampler by adding the `rubato` dependency with the default features. ```toml rubato = "4.0" ``` -------------------------------- ### Process Audio Chunk into Buffer (Real-time) Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Core method for real-time processing, resampling into a pre-allocated output buffer without allocations. Preferred for performance-critical applications. ```rust fn process_into_buffer( &mut self, buffer_in: &dyn Adapter, buffer_out: &mut dyn AdapterMut, indexing: Option<&Indexing>, ) -> ResampleResult<(usize, usize)> ``` ```rust use rubato::{Resampler, Indexing}; use audioadapter_buffers::direct::SequentialSliceOfVecs; let mut resampler = /* ... */; // Pre-allocate buffers once let frames_in = resampler.input_frames_next(); let frames_out = resampler.output_frames_next(); let mut input_data = vec![vec![0.0; frames_in]; 2]; let mut output_data = vec![vec![0.0; frames_out]; 2]; // Reusable processing loop for _ in 0..100 { // Fill input_data from source... let input = SequentialSliceOfVecs::new(&input_data, 2, frames_in)?; let mut output = SequentialSliceOfVecs::new_mut(&mut output_data, 2, frames_out)?; let (frames_read, frames_written) = resampler.process_into_buffer(&input, &mut output, None)?; // Write frames_written frames to destination... } ``` -------------------------------- ### Process Audio Chunk (Convenience) Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md Convenience method to resample a single chunk of audio, allocating an output buffer. Suitable for non-real-time tasks. ```rust fn process( &mut self, buffer_in: &dyn Adapter, indexing: Option<&Indexing>, ) -> ResampleResult> ``` ```rust use rubato::{Resampler, Async, FixedAsync, PolynomialDegree}; use audioadapter_buffers::direct::InterleavedSlice; let mut resampler = Async::::new_poly(2.0, 1.1, PolynomialDegree::Cubic, 1024, 2, FixedAsync::Input)?; let input_data = vec![vec![0.0; 1024]; 2]; // Stereo input let input_adapter = InterleavedSlice::new(&input_data, 2, 1024)?; // Simple processing let output = resampler.process(&input_adapter, None)?; println!("Output frames: {}", output.frames()); // With indexing (skip first 512 input frames) use rubato::Indexing; let indexing = Indexing::new().input_offset(512); let output = resampler.process(&input_adapter, Some(&indexing))?; ``` -------------------------------- ### Builder Methods Source: https://github.com/henquist/rubato/blob/master/_autodocs/DELIVERY_SUMMARY.txt Documentation for builder methods used in configuring resampler-related types. ```APIDOC ## Builder Methods ### Description This section covers the builder methods available for configuring various types, such as `SincInterpolationParameters` and `Indexing`. ### Methods - **SincInterpolationParameters**: Approximately 5 builder methods for configuring sinc interpolation. - **Indexing**: Approximately 4 builder methods for configuring indexing behavior. ### Parameter Documentation Each builder method includes a detailed parameter table (name, type, default, description). ### Return Type Specification Specifies the return type and describes its behavior. ### Worked Examples Includes worked code examples demonstrating the use of these builder methods. ``` -------------------------------- ### Convert WAV to 64-bit Float Raw Samples Source: https://github.com/henquist/rubato/blob/master/README.md Use the `sox` command-line tool to convert a WAV audio file into raw 64-bit floating-point samples. This format is often used for processing with audio resampling libraries. ```sh sox some_file.wav -e floating-point -b 64 some_file_f64.raw ``` -------------------------------- ### Sample Trait Definition Source: https://github.com/henquist/rubato/blob/master/_autodocs/types.md Defines the core requirements for audio sample types, including arithmetic, trigonometric operations, and SIMD support. Implementations are typically f32 and f64. ```rust pub trait Sample: Copy + CoerceFrom + CoerceFrom + CoerceFrom + FftNum + std::ops::Mul + std::ops::Div + std::ops::Add + std::ops::Sub + std::ops::MulAssign + std::ops::RemAssign + std::ops::DivAssign + std::ops::SubAssign + std::ops::AddAssign + AvxSample + SseSample + NeonSample + Send { const PI: Self; fn sin(self) -> Self; fn cos(self) -> Self; fn coerce(value: T) -> Self where Self: CoerceFrom; } ``` -------------------------------- ### Process Entire Audio Clip to Owned Output Source: https://github.com/henquist/rubato/blob/master/_autodocs/api-reference/Resampler.md An allocating wrapper around `process_all_into_buffer` that resamples an entire clip and returns a precisely-sized output buffer without padding. This is useful for when you need the exact resampled data without managing buffer allocation manually. ```rust fn process_all( &mut self, buffer_in: &dyn Adapter, input_len: usize, active_channels_mask: Option<&[bool]>, ) -> ResampleResult> ``` ```rust let mut resampler = Fft::::new(44100, 48000, 1024, 2, FixedSync::Both)?; // Process entire file at once let input = /* load from file */; let output = resampler.process_all(&input, input_len, None)?; // Output has exactly the resampled frames, nothing extra assert_eq!(output.frames(), (input_len as f64 * 48000.0 / 44100.0).ceil() as usize); ```