Skip to content

Update to audioadapter 5.0 and release 5.0.0 - #139

Open
HEnquist wants to merge 12 commits into
masterfrom
next5
Open

Update to audioadapter 5.0 and release 5.0.0#139
HEnquist wants to merge 12 commits into
masterfrom
next5

Conversation

@HEnquist

@HEnquist HEnquist commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Updates the audioadapter dependencies and bumps rubato to 5.0.0.

  • audioadapter 5.0, audioadapter-buffers and audioadapter-sample 5.1
  • MSRV raised to 1.87, required by audioadapter 5.x
  • Commented-out path dependencies replaced with a commented-out [patch.crates-io] block
  • Changelog entry for 5.0.0, covering the ratio-ramp panic fix and the Horner-form polynomial speedup that landed since 4.0.0

Bump audioadapter to 5.0 and audioadapter-buffers/audioadapter-sample to 5.1,
raise the MSRV to 1.87 to match, and replace the commented-out path
dependencies with a commented-out [patch.crates-io] block.
Expose fft_size_in, fft_size_out and cutoff on Fft, and cutoff on Async.
The cutoff is relative to the input Nyquist frequency, and is None for the
polynomial variant of Async since it uses no anti-aliasing filter.

Extract the cutoff resolution into resolve_cutoff so make_interpolator and
new_sinc share one definition, and pass the resolved value to
new_with_sinc_interpolator. Also fix the Debug impl of Fft, which named
itself Fast.
A small CLI that reads a wav file with waveadapter, resamples it with the
FFT resampler, and writes it back in any sample format waveadapter supports.
Options for output format, gain, chunk size and window, parsed with clap.
The public docs for Slip::new linked to a private constant, which rustdoc
warns about and readers cannot follow. State the values instead.
Async and Fft both printed themselves as Fast, left over from when the
separate Fast and FFT resamplers were united, and both had trailing commas
inside the field name strings.
Replace the manual modulo checks with is_multiple_of, which recent clippy
versions flag, and allow the argument count of new_with_sinc_interpolator
now that it also takes the filter cutoff. CI runs clippy with -D warnings,
so both were fatal.
process_all_f64 only differed from process_f64 by calling
process_all_into_buffer, which is now shown by a doc example on the method
itself. process_i16 duplicated process_f64 apart from wrapping the input in
an integer byte adapter, which audioadapter documents. Removing it also
drops the audioadapter-sample dev dependency.
The examples took a long list of positional arguments with no help text.
Give them all named options with defaults instead, matching the new
resample_wav example.

Also merge fixedout_ramp64 and polyfixedin_ramp64 into ramp_ratio_f64.
They only differed by resampler type and which side is fixed, both of which
are now options, so the merged example also covers the two combinations
neither of them had.
@HEnquist
HEnquist requested a lite review from Copilot August 6, 2026 18:56
The section still described a 16-bit integer example that is gone, and did
not mention that resample_wav reads and writes wav files directly. List the
four examples and what each one is for.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR updates rubato to v5.0.0 by bumping MSRV and audioadapter dependencies, and extends the resampler APIs/docs/examples with more introspection and CLI tooling.

Changes:

  • Bump crate version to 5.0.0, raise MSRV to Rust 1.87, and update audioadapter / audioadapter-buffers.
  • Expose/report filter cutoff and FFT block sizes; refactor sinc cutoff resolution and add corresponding tests.
  • Refresh/remove older examples and add new Clap-based examples, including a WAV resampling CLI.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/synchro.rs Stores/exposes FFT resampler cutoff + FFT block size getters; improves Debug formatting; adds tests.
src/slip.rs Updates constructor docs for crossfade sizing details.
src/sinc_interpolator/sinc_interpolator_sse.rs Uses is_multiple_of(8) for clearer alignment assertion.
src/sinc_interpolator/sinc_interpolator_neon.rs Uses is_multiple_of(8) for clearer alignment assertion.
src/sinc_interpolator/sinc_interpolator_avx.rs Uses is_multiple_of(8) for clearer alignment assertion.
src/sinc_interpolator/mod.rs Formats/clarifies the multiple-of-8 assertion.
src/lib.rs Adds a Rustdoc example for process_all_into_buffer.
src/asynchro_sinc.rs Extracts rounding + cutoff resolution helpers for sinc interpolators.
src/asynchro.rs Tracks/exposes sinc cutoff for async resamplers; updates Debug; adds tests.
examples/resample_wav.rs Adds a minimal WAV resampling CLI example (FFT resampler).
examples/ramp_ratio_f64.rs Adds a Clap-based example for ramping adjustable ratio over time.
examples/process_i16.rs Removes an older raw i16 processing example.
examples/process_f64.rs Modernizes CLI parsing (Clap) and supports multiple resampler types via enums.
examples/process_all_f64.rs Removes an older process_all_into_buffer-focused example.
examples/polyfixedin_ramp64.rs Removes an older ramping example superseded by newer equivalents.
examples/fixedout_ramp64.rs Removes an older ramping example superseded by newer equivalents.
examples/adjust_ratio_f64.rs Modernizes CLI parsing (Clap) and improves example docs.
benches/resamplers.rs Updates bench call site for new sinc cutoff parameter plumbed through constructors.
README.md Updates docs.rs links, MSRV note, and adds v5.0.0 changelog entries.
Cargo.toml Bumps version/MSRV, updates deps, adds new dev-deps and example metadata.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/asynchro_sinc.rs
Comment thread src/slip.rs
Comment thread src/synchro.rs
Comment thread src/asynchro.rs
Drop a duplicated sentence in the docs for Fft::cutoff, and pin the
crossfade values that the docs for Slip::new quote with an assert, so they
cannot drift unnoticed.

Replace the float rounding used to size the FFT blocks and the sinc filter
with integer arithmetic. Dividing as f32 loses precision for large values,
and div_ceil says what is meant. Rounding down to zero blocks now falls
back to a single block instead of panicking further down.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (3)

examples/ramp_ratio_f64.rs:104

  • read_file uses Read::read into a fixed-size buffer but ignores bytes_read. A short read (or a truncated final sample) will cause from_le_bytes to decode stale bytes from the previous iteration and silently corrupt the input. Use read_exact (and handle UnexpectedEof) so each decoded f64 is backed by exactly 8 bytes.
        let bytes_read = inbuffer.read(&mut buffer).unwrap();
        if bytes_read == 0 {
            break;
        }
        let value = f64::from_le_bytes(buffer.as_slice().try_into().unwrap());

examples/resample_wav.rs:166

  • This comment is misleading: with Fft::new_custom, the internal FFT block sizes may be rounded up from --chunk to a valid block size for the rate pair (e.g. 44100→48000). Consider clarifying that --chunk is a requested size, while fft_size_in/out() report the actual block sizes used.
    // One sub chunk per chunk, so the chunk size is also the FFT block size.

examples/ramp_ratio_f64.rs:218

  • The processing loop stops when frames_left <= input_frames_next(), but the remaining frames are never processed. This can drop the last chunk (or the last partial chunk) of audio. Add a final partial_len call after the loop (mirroring Resampler::process_all_into_buffer).
    }

The read helper decoded the buffer whatever the read returned, so a short
read or a truncated trailing sample decoded stale bytes from the previous
iteration as audio. Use read_exact and stop at a clean end of file, like
adjust_ratio_f64 already did.

Also correct the comment in resample_wav that claimed the chunk size is the
FFT block size. It is the requested size, rounded up to a block size valid
for the sample rate pair.
The loop stopped as soon as fewer frames than a full chunk were left, so the
tail of the clip was silently dropped. Add the partial call after the loop,
like process_f64 does.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (2)

examples/process_f64.rs:107

  • The read_file loop treats any UnexpectedEof from read_exact as a clean EOF, but the comment says a partial trailing read means a malformed file. With read_exact, UnexpectedEof also occurs for a truly partial trailing sample, so the current code silently drops trailing bytes instead of failing as documented. Consider reading incrementally so you can distinguish clean EOF (0 bytes read) from a partial sample and error out on the latter.
            // A clean end of file stops the loop; a partial trailing read means a malformed file.
            Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => break,
            Err(e) => panic!("Error reading input file: {}", e),

examples/ramp_ratio_f64.rs:107

  • Same issue as in process_f64: read_exact returning UnexpectedEof is treated as a clean EOF, but it also happens for a partial trailing sample. This means malformed inputs with a non-multiple-of-8 byte length will be silently truncated despite the comment saying they are malformed.
            // A clean end of file stops the loop; a partial trailing read means a malformed file.
            Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => break,
            Err(e) => panic!("Error reading input file: {}", e),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants