Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ symphonia-libopus = ["symphonia", "dep:symphonia-adapter-libopus"]

# Resampling features
#
# Enable the specialized f32 fixed-ratio polyphase FIR backend. When enabled, fixed-ratio Sinc
# configurations use the backend when possible; Rubato remains the fallback for other ratios and
# for the 64-bit sample mode.
fixed-fir = []

# Enable FFT-based synchronous resampling as an optimization for fixed-ratio conversions. When
# enabled, conversions between standard sample rates (e.g., 48 kHz and 96 kHz, as well as 44.1 kHz
# and 48 kHz) that simplify to small integer ratios automatically use FFT processing for faster
Expand Down Expand Up @@ -195,6 +200,10 @@ name = "resampler"
harness = false
required-features = ["wav"]

[[bench]]
name = "sinc_backends"
harness = false

[[bench]]
name = "pipeline"
harness = false
Expand Down
55 changes: 55 additions & 0 deletions benches/sinc_backends.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//! Apples-to-apples fixed-ratio Sinc benchmark.
//!
//! Run this benchmark twice with the same release profile:
//!
//! ```text
//! cargo bench --bench sinc_backends --no-default-features
//! cargo bench --bench sinc_backends --no-default-features --features fixed-fir
//! ```
//!
//! `with_inputs` keeps source generation out of the timed loop. Converter construction (including
//! plan setup) is inside the timed operation for both backends. The input, ratio, channels,
//! duration, and configuration are identical; the feature selects only the backend.

use divan::Bencher;
use rodio::conversions::SampleRateConverter;
use rodio::source::{from_iter, FromIter, ResampleConfig};
use rodio::{ChannelCount, Sample, SampleRate};

fn main() {
divan::main();
}

fn input(channels: ChannelCount) -> FromIter<std::vec::IntoIter<Sample>> {
let frames = 44_100 * 2;
let channels = channels.get() as usize;
let samples = (0..frames * channels)
.map(|i| {
let frame = i / channels;
let channel = i % channels;
(2.0 * std::f32::consts::PI * (440.0 + 37.0 * channel as f32) * frame as f32 / 44_100.0)
.sin()
* 0.5
})
.collect::<Vec<_>>();
from_iter(
samples.into_iter(),
ChannelCount::new(channels as u16).unwrap(),
SampleRate::new(44_100).unwrap(),
)
}

#[divan::bench(args = [1u16, 2u16])]
fn sinc_44100_to_48000(bencher: Bencher, channel_count: u16) {
let channels: ChannelCount = channel_count.try_into().unwrap();
bencher
.with_inputs(|| input(channels))
.bench_values(|source| {
SampleRateConverter::new(
source,
SampleRate::new(48_000).unwrap(),
ResampleConfig::balanced(),
)
.for_each(divan::black_box_drop)
});
}
Loading
Loading