Coder Social home page Coder Social logo

ebur128's Introduction

ebur128 crates.io Actions Status docs.rs

Implementation of the EBU R128 loudness standard.

The European Broadcasting Union Loudness Recommendation (EBU R128) informs broadcasters how they can analyze and normalize audio so that each piece of audio sounds roughly the same volume to the human ear.

This crate provides an API which analyzes audio and outputs perceived loudness. The results can then be used to normalize volume during playback.

Features:

  • Implements M, S and I modes (EBU - TECH 3341)
  • Implements loudness range measurement (EBU - TECH 3342)
  • True peak scanning
  • Supports all samplerates by recalculation of the filter coefficients

This crate is a Rust port of the libebur128 C library, produces the same results as the C library and has comparable performance.

EBU TECH 3341/3342 Compliance

Currently, the implementation passes all tests defined in EBU - TECH 3341 and EBU - TECH 3342.

C API

ebur128 optionally provides a C API that is API/ABI-compatible with libebur128. It can be built and installed via cargo-c:

# If cargo-c was not installed yet
$ cargo install cargo-c
# Change the prefix to the place where it should be installed
$ cargo cbuild --prefix /usr/local
$ cargo cinstall --prefix /usr/local

This installs a shared library, static library, C header and pkg-config file that is compatible with libebur128.

LICENSE

ebur128 is licensed under the MIT license (LICENSE or http://opensource.org/licenses/MIT).

Contribution

Any kinds of contributions are welcome as a pull request.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in ebur128 by you shall be licensed under the MIT license as above, without any additional terms or conditions.

ebur128's People

Contributors

diizzyy avatar l0calh05t avatar luni-4 avatar rawler avatar sdroege avatar zotho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ebur128's Issues

How to use for real time processing

I am trying to use the lib in an lv2 plugin. Is it possible to run the calculation for each frame to avoid high processing need when the result is calculated.

As per recommendation I would like to expose the short term value at a frequency of 10Hz and the integrated value on 1Hz.

When getting the short therm value every 100ms the plugin produces click noises, which I guess are caused by calculation of the short term value every 100ms. The sample rate is 48kHZ

Thank you very much for some suggestions how to improve the code. Let me know if I should provide more details.

Add libebur128 ABI-compatible C API

  • For the existing functions, simple
  • Make sure it actually works, ideally with some CI tests
  • Implement the two _multiple() functions.
  • Use cargo-c for build/install

Potential performance regression

During my tests it seems like ebur128 is about 20% slower than libebur128 when used in rsgain which doesn't seem to be expected performance.

Hardware:
Intel 11th Gen (Tigerlake)

Software:
FreeBSD 13.2-RELEASE (amd64)

ebur128 0.1.7 (compiled using Rust 1.68.2) and commits e652c0d + 1b1541c
Relevant compiler flags: -C opt-level=2 -C panic=abort -C codegen-units=1 -C target-cpu=tigerlake

libebur128 1.2.6 (compiled using LLVM/clang 14.0.5)
Relevant compiler flags (no lto): -O2 -march=tigerlake

rsgain 3.2.1 (used for testing)

For testing I used a ~8h long AAC file in m4a

Command used for testing: rsgain easy /path/to/directory

How to build this for Fedora with proprietary FFMPEG codecs installed?

I use Fedora with the proprietary codecs and the complete FFMPEG software (including x264) installed. However, I cannot build the source because:

Problem 1: package libavformat-free-devel-6.0-2.fc38.i686 from fedora requires libavformat-free(x86-32) = 6.0-2.fc38, but none of the providers can be installed
Problem 2: package libavcodec-free-devel-6.0-2.fc38.i686 from fedora requires libavcodec-free(x86-32) = 6.0-2.fc38, but none of the providers can be installed
Problem 3: package libswresample-free-devel-6.0-2.fc38.i686 from fedora requires libswresample-free(x86-32) = 6.0-2.fc38, but none of the providers can be installed

Trying to install the RPM file directly results in a similar thing.

Can you please help me install the dependencies needed to build this?

Panic when calling loudness_range

Hello, thanks for making this library :-)

There seems to be a bug when calling loudness_range that occasionally triggers a panic. I've attached a stack trace with the relevant calls below. I've tried unsuccessfully to build a repro case but in my application the error is somewhat rare. Even with the same input data every time, it will fail spuriously about 1% of the time. For some context, I'm testing with a ~40 second 96kHz stereo clip buffered in as f32 samples.

panicked at 'called `Option::unwrap()` on a `None` value', /Users/marko/.cargo/registry/src/github.com-1ecc6299db9ec823/ebur128-0.1.5/src/history.rs:433:67
stack backtrace:
   0:        0x1001d1d44 - std::backtrace_rs::backtrace::libunwind::trace::h3440e89bdeed3ddf
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/../../backtrace/src/backtrace/libunwind.rs:90:5
   1:        0x1001d1d44 - std::backtrace_rs::backtrace::trace_unsynchronized::hfa68bcc7baf06ad7
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:        0x1001d1d44 - std::sys_common::backtrace::_print_fmt::h483e161a2ffbfba4
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:67:5
   3:        0x1001d1d44 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h34f76b2ca42fab41
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:46:22
   4:        0x1001ef37d - core::fmt::write::h8f13d857463c51c1
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/fmt/mod.rs:1078:17
   5:        0x1001ce326 - std::io::Write::write_fmt::h013bead77842bdd6
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/io/mod.rs:1517:15
   6:        0x1001d3db9 - std::sys_common::backtrace::_print::h7f3525175df798e8
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:49:5
   7:        0x1001d3db9 - std::sys_common::backtrace::print::hf68eec1a3c535c32
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:36:9
   8:        0x1001d3db9 - std::panicking::default_hook::{{closure}}::hb14d90e928578cc7
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:208:50
   9:        0x1001d3976 - std::panicking::default_hook::h460969f1dc8f738d
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:222:9
  10:        0x1001d443b - std::panicking::rust_panic_with_hook::h28bf9d6c3916221e
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:591:17
  11:        0x1001d3f39 - std::panicking::begin_panic_handler::{{closure}}::h99569328be4adae9
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:495:13
  12:        0x1001d21e8 - std::sys_common::backtrace::__rust_end_short_backtrace::h9a7e5cc6475b496b
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:141:18
  13:        0x1001d3eca - rust_begin_unwind
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:493:5
  14:        0x1001fb3af - core::panicking::panic_fmt::h65997884a2662b8c
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/panicking.rs:92:14
  15:        0x1001fb307 - core::panicking::panic::h2ca2e9d2b0a1f2bf
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/panicking.rs:50:5
  16:        0x100189cad - core::option::Option<T>::unwrap::hdeee087517023990
                               at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:386:21
  17:        0x100189cad - ebur128::history::History::loudness_range_multiple::{{closure}}::h1a0ff08728c0cb3b
                               at /Users/marko/.cargo/registry/src/github.com-1ecc6299db9ec823/ebur128-0.1.5/src/history.rs:433:50
  18:        0x100189cad - core::slice::<impl [T]>::sort_unstable_by::{{closure}}::hc07c59363457d04f
                               at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/mod.rs:2066:38
  19:        0x100189cad - core::slice::sort::shift_tail::h7ec07b4e8c340c30
                               at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/sort.rs:100:24
  20:        0x100189dae - core::slice::sort::insertion_sort::h74c03aa25773ab0d
                               at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/sort.rs:177:9
  21:        0x100189dae - core::slice::sort::recurse::h16dae32c7768ff6f
                               at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/sort.rs:687:13
  22:        0x10018b5f4 - core::slice::sort::quicksort::h89c7abc843bf1a67
                               at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/sort.rs:768:5
  23:        0x10018b5f4 - core::slice::<impl [T]>::sort_unstable_by::hd97a30f3bafd244c
                               at /Users/marko/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/mod.rs:2066:9
  24:        0x10018b5f4 - ebur128::history::History::loudness_range_multiple::hc7e4bb112053e86c
                               at /Users/marko/.cargo/registry/src/github.com-1ecc6299db9ec823/ebur128-0.1.5/src/history.rs:433:17
  25:        0x10018698d - ebur128::history::History::loudness_range::h10766b0a6c5a0aa1
                               at /Users/marko/.cargo/registry/src/github.com-1ecc6299db9ec823/ebur128-0.1.5/src/history.rs:377:9
  26:        0x10018698d - ebur128::ebur128::EbuR128::loudness_range::h4efb27ac08702281
                               at /Users/marko/.cargo/registry/src/github.com-1ecc6299db9ec823/ebur128-0.1.5/src/ebur128.rs:831:12
...[snip]...

Optimize Rust implementation

  • src/history.rs could probably be faster by getting rid of some bounds checks
  • src/filter.rs and all code following it could probably be faster by first deinterleaving the input channels before doing any further processing. Note that this requires updating in src/ebur128.rs for the audio_data handling, and that src/true_peak.rs already works on deinterleaved data (by deinterleaving it first)
  • EbuR128::calc_gating_block() potentially has some unneeded bounds checks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.