pyloudnorm

A lightweight Python library implementing the ITU-R BS.1770-4 loudness algorithm for measuring and normalizing audio loudness.

Library
PyPI
v0.2.0
781stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
40/100Fair
Development Activity0
Maintenance20
Community52
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
64/100Good
Architecture70
Code Quality55
Innovation75
Learning Curve55

pyloudnorm is a Python library for measuring and adjusting the perceived loudness of audio signals according to the ITU-R BS.1770-4 broadcast loudness standard. Given a NumPy array of audio samples, its Meter class computes integrated (LUFS) loudness through the same gated, K-weighted algorithm used by streaming platforms and broadcasters to normalize playback levels, and a companion loudness_range method estimates the EBU Tech 3342 loudness range (LRA) of a track.

Beyond measurement, the normalize module exposes simple peak- and loudness-normalization functions so audio can be scaled to a target dBFS or LUFS value in a single call. The library ships with five alternate frequency-weighting filter implementations — including the reference DeMan filters validated against the ITU specification — making it useful both as a drop-in loudness meter and as a research tool for comparing loudness-measurement variants.

What You Get

  • Meter class computing ITU-R BS.1770-4 integrated loudness (LUFS) from raw NumPy audio arrays
  • loudness_range() implementing EBU Tech 3342 Loudness Range (LRA) measurement
  • peak() and loudness() functions in the normalize module for scaling audio to a target level
  • Five interchangeable K-weighting filter implementations (K-weighting, Fenton/Lee 1/2, Dash et al., DeMan) selectable via a single constructor argument
  • IIRfilter class exposing raw biquad coefficients for building custom weighting filters

Common Use Cases

  • Loudness-normalizing a batch of audio files before publishing to a streaming platform
  • Measuring integrated loudness of a mix to check compliance with broadcast loudness targets
  • Computing loudness range to evaluate the dynamic range of a mastered track
  • Benchmarking alternative K-weighting filter designs against the ITU-R BS.1770 reference implementation

Under The Hood

Architecture pyloudnorm is a small, flat library with a clear separation of concerns across four modules: meter.py orchestrates the measurement pipeline, iirfilter.py generates biquad filter coefficients, normalize.py holds pure functional peak/loudness-scaling helpers, and util.py validates input arrays. Data flows linearly — a raw ndarray is validated, run through per-channel frequency-weighting filters, split into overlapping analysis blocks, mean-squared and gated in two passes (absolute then relative threshold) per the ITU-R BS.1770-4 gating algorithm, and reduced to a single LUFS value. Because filter coefficient generation in IIRfilter is the single source of truth for every downstream loudness number, any change there propagates silently through the whole measurement chain, with correctness enforced only by the end-to-end conformance tests rather than unit-level coefficient checks.

Tech Stack The library targets Python 3.9+ and declares just two runtime dependencies in pyproject.toml — scipy>=1.0.1 for IIR filtering via scipy.signal.lfilter and numpy>=1.14.2 for array math — keeping its footprint minimal for a signal-processing package. It builds as a standard sdist/wheel through setuptools>=61.0, and its dev/test dependencies (matplotlib, soundfile) are listed separately in requirements.txt for running the example and test scripts rather than for the library itself.

Code Quality Test coverage is domain-specific and rigorous: tests/test_loudness.py and test_loudness_range.py validate the meter against a comprehensive set of ITU-R BS.1770-2 conformance WAV files with tolerance-based assertions (np.isclose, ±0.1 LU), which is a strong practice for a scientific/audio library even though there are no unit tests isolating individual filter classes. There is no static typing, no linter/formatter configuration in the repo, and CI is defined only via a legacy .travis.yml rather than an actively maintained GitHub Actions workflow, suggesting the tooling around the library has not been modernized even as the algorithm implementation itself remains actively used.

API Design The public API is deliberately minimal — three lines get a user from a loaded WAV file to a LUFS value (meter = pyln.Meter(rate), meter.integrated_loudness(data)), and the same call signature works across five different weighting-filter algorithms by swapping a single filter_class string, a clean pluggable-strategy pattern that avoids exposing filter internals to callers. Naming maps directly onto the terminology of the underlying broadcast standards (LUFS, LRA, K-weighting), which lowers the translation cost for engineers already familiar with loudness specs, though the trade-off is that newcomers unfamiliar with those standards get little in-code guidance beyond docstrings.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search