Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Port remaining C code to Rust
The remaining audio processing function (calc_gating_block) is about 1.5%
faster in its Rust version than the C version.

Overall the Rust version is currently
 - 9% slower with all features enabled but not histogram mode
 - 2% slower with all features enabled in histogram mode
 - 1% to 2.5% slower in M/S/I modes (with and without histogram)

There are various obvious optimizations to do.

The Rust version gives exactly the same results as the C version (less
than 2ULP difference).

Fixes #1
  • Loading branch information
sdroege committed Aug 9, 2020
1 parent 38b2511 commit adc557d
Show file tree
Hide file tree
Showing 25 changed files with 1,485 additions and 1,958 deletions.
8 changes: 6 additions & 2 deletions Cargo.toml
Expand Up @@ -16,7 +16,7 @@ bitflags = "1.0"
lazy_static = "1.0"

[build-dependencies]
cc = "1.0"
cc = { version = "1.0", optional = true }

[dev-dependencies]
criterion = "0.3"
Expand All @@ -27,7 +27,7 @@ quickcheck_macros = "0.9"
rand = "0.7"

[features]
internal-tests = []
internal-tests = ["cc"]

[[bench]]
name = "interp"
Expand All @@ -45,6 +45,10 @@ harness = false
name = "filter"
harness = false

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

[[bench]]
name = "ebur128"
harness = false
Expand Down
3 changes: 3 additions & 0 deletions LICENSE
@@ -1,3 +1,6 @@
Copyright (c) 2011 Jan Kokemüller
Copyright (c) 2020 Sebastian Dröge <sebastian@centricular.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
Expand Down
3 changes: 1 addition & 2 deletions README.md
Expand Up @@ -15,8 +15,7 @@ Features:
* True peak scanning
* Supports all samplerates by recalculation of the filter coefficients

This crate is based on the [libebur128](https://github.com/jiixyj/libebur128) C
library.
This crate is a Rust port of the [libebur128](https://github.com/jiixyj/libebur128) C library.

## LICENSE

Expand Down
77 changes: 77 additions & 0 deletions benches/calc_gating_block.rs
@@ -0,0 +1,77 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};

#[cfg(feature = "internal-tests")]
fn calc_gating_block_c(
frames_per_block: usize,
audio_data: &[f64],
audio_data_index: usize,
channel_map: &[u32],
) -> f64 {
unsafe {
ebur128::calc_gating_block_c(
frames_per_block,
audio_data.as_ptr(),
audio_data.len() / channel_map.len(),
audio_data_index,
channel_map.as_ptr(),
channel_map.len(),
)
}
}

#[cfg(feature = "internal-tests")]
fn calc_gating_block(
frames_per_block: usize,
audio_data: &[f64],
audio_data_index: usize,
channel_map: &[ebur128::Channel],
) -> f64 {
ebur128::calc_gating_block_internal(frames_per_block, audio_data, audio_data_index, channel_map)
}

pub fn criterion_benchmark(c: &mut Criterion) {
#[cfg(feature = "internal-tests")]
{
let mut data = vec![0f64; 48_000 * 3 * 2];
let mut accumulator = 0.0;
let step = 2.0 * std::f64::consts::PI * 440.0 / 48_000.0;
for out in data.chunks_exact_mut(2) {
let val = f64::sin(accumulator);
out[0] = val;
out[1] = val;
accumulator += step;
}

let channel_map = [ebur128::Channel::Left; 2];
let channel_map_c = [1; 2];

let frames_per_block = 1_44_000;

let mut group = c.benchmark_group("calc gating block: 48kHz 2ch");
group.bench_function("C", |b| {
b.iter(|| {
calc_gating_block_c(
black_box(frames_per_block),
black_box(&data),
black_box(0),
black_box(&channel_map_c),
)
})
});
group.bench_function("Rust", |b| {
b.iter(|| {
calc_gating_block(
black_box(frames_per_block),
black_box(&data),
black_box(0),
black_box(&channel_map),
)
})
});

group.finish();
}
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

0 comments on commit adc557d

Please sign in to comment.