Skip to main content

Crate ebur128_stream

Crate ebur128_stream 

Source
Expand description

§ebur128-stream

Streaming, zero-allocation EBU R128 loudness measurement in pure Rust.

ebur128-stream implements the ITU-R BS.1770-4 loudness algorithm and the surrounding EBU R128 practices (momentary, short-term, integrated, true peak, loudness range) with a push-based streaming API that accepts arbitrary chunk sizes deterministically and performs no allocations on the hot path.

§Quick start

use ebur128_stream::{AnalyzerBuilder, Channel, Mode};

let mut analyzer = AnalyzerBuilder::new()
    .sample_rate(48_000)
    .channels(&[Channel::Left, Channel::Right])
    .modes(Mode::Integrated | Mode::TruePeak)
    .build()?;

// Push interleaved stereo samples (any chunk size; the analyzer is
// chunk-size-deterministic).
let stereo = vec![0.0f32; 9_600]; // 100 ms of silence at 48 kHz
analyzer.push_interleaved(&stereo)?;

let report = analyzer.finalize();
// For silent input, integrated loudness is None (nothing cleared the
// -70 LUFS absolute gate).
assert!(report.integrated_lufs().is_none());

§Concepts

§What is loudness?

Loudness is the perceived energy of an audio signal — what the ear hears, not what a meter sees. The classic peak / RMS meter measures signal amplitude; loudness meters apply a frequency-weighted filter (the K-weighting filter of BS.1770) that approximates the ear’s sensitivity, then sum energy across channels with appropriate per-channel weights, and report a single calibrated value in LUFS (Loudness Units relative to Full Scale).

Two signals at the same RMS can differ by 10 LU in measured loudness if one has more high-frequency content than the other. This is why broadcasters use LUFS rather than peak / RMS for loudness compliance.

§Momentary, short-term, integrated

BS.1770 defines three measurement windows:

  M (momentary)    : sliding 400 ms window  → quick reaction
  S (short-term)   : sliding 3 s window     → smoother envelope
  I (integrated)   : full programme, gated  → "the" loudness number

Integrated loudness uses gating to ignore quiet sections that shouldn’t drag the programme average down: an absolute gate at -70 LUFS, then a relative gate -10 LU below the absolute-gated mean.

§True peak vs. sample peak

Sample peak — the largest absolute value in the PCM buffer — undercounts the actual signal level whenever a peak falls between samples. True peak (per BS.1770 Annex 2) approximates the analog reconstructed signal by 4× upsampling through a 12-tap polyphase FIR and reports the oversampled max in dBTP (decibels relative to full scale, true peak).

§Choosing a mode

Use caseModes to request
Real-time monitorMode::Momentary + Mode::ShortTerm
Programme delivery QCMode::Integrated + Mode::TruePeak
Mastering / archivalMode::All
True-peak limiter feedMode::TruePeak only

§Performance characteristics

§Compliance

Calibration is verified against synthetic stimuli matching the ITU-R BS.1770-4 reference signals. Independent verification against the official EBU Tech 3341 test vectors is in progress; see tests/calibration.rs for the current cross-checks.

§See also

  • bs1770 — filter only, no gating, no streaming API.
  • ebur128 — Rust bindings to the C libebur128.

Modules§

normalizenormalize
Loudness normalisation helpers.
resamplerresampler
Sample-rate conversion to one of the analyzer’s supported rates.
svgsvg
Dynamic SVG VU meter rendering.

Structs§

Analyzer
Streaming EBU R128 loudness analyzer.
AnalyzerBuilder
Builder for Analyzer.
AnalyzerSinktokio
A futures_sink::Sink that ingests Vec<f32> interleaved sample chunks into the wrapped Analyzer.
Mode
The set of measurements an analyzer should compute.
Report
Programme-final loudness measurements.
Snapshot
A point-in-time view of the analyzer’s measurements.

Enums§

Channel
One channel of a multi-channel programme.
Error
Errors returned from analyzer construction or sample ingestion.

Traits§

Sample
A sample type accepted by Analyzer::push_planar and Analyzer::push_interleaved.