Skip to main content

Docs below are from the original repo for the most part.

jaxloudnorm Zenodo

Flexible audio loudness meter in Python.

Implementation of ITU-R BS.1770-4.
Allows control over gating block size and frequency weighting filters for additional control.

For full details on the implementation see our paper with a summary in our AES presentation video.

Installation

Install from PyPI:

pip install jaxloudnorm

Usage

Find the loudness of an audio file

It's easy to measure the loudness of a wav file. Here we use PySoundFile to read a .wav file as an ndarray.

import soundfile as sf
import jaxloudnorm as jln

data, rate = sf.read("test.wav") # load audio (with shape (samples, channels))
data = data.T # convert to (channels, samples) for jaxloudnorm
meter = jln.Meter(rate) # create BS.1770 meter
loudness = meter.integrated_loudness(data) # measure loudness

Loudness normalize and peak normalize audio files

Methods are included to normalize audio files to desired peak values or desired loudness.

import soundfile as sf
import jaxloudnorm as jln

data, rate = sf.read("test.wav") # load audio
data = data.T # convert to (channels, samples) for jaxloudnorm
# peak normalize audio to -1 dB
peak_normalized_audio = jln.normalize.peak(data, -1.0)

# measure the loudness first 
meter = jln.Meter(rate) # create BS.1770 meter
loudness = meter.integrated_loudness(data)

# loudness normalize audio to -12 dB LUFS
loudness_normalized_audio = jln.normalize.loudness(data, loudness, -12.0)

Advanced operation

A number of alternate weighting filters are available, as well as the ability to adjust the analysis block size. Examples are shown below.

import soundfile as sf
import jaxloudnorm as jln
from jaxloudnorm import IIRfilter

data, rate = sf.read("test.wav") # load audio (with shape (samples, channels))
data = data.T # convert to (channels, samples) for jaxloudnorm

# block size
meter1 = jln.Meter(rate)                               # 400ms block size
meter2 = jln.Meter(rate, block_size=0.200)             # 200ms block size

# filter classes
meter3 = jln.Meter(rate)                               # BS.1770 meter
meter4 = jln.Meter(rate, filter_class="DeMan")         # fully compliant filters  
meter5 = jln.Meter(rate, filter_class="Fenton/Lee 1")  # low complexity improvement by Fenton and Lee
meter6 = jln.Meter(rate, filter_class="Fenton/Lee 2")  # higher complexity improvement by Fenton and Lee
meter7 = jln.Meter(rate, filter_class="Dash et al.")   # early modification option

# create your own IIR filters
my_high_pass  = IIRfilter(0.0, 0.5, 20.0, rate, 'high_pass')
my_high_shelf = IIRfilter(2.0, 0.7, 1525.0, rate, 'high_shelf')

# create a meter initialized without filters
meter8 = jln.Meter(rate, filter_class="custom")

# load your filters into the meter
meter8._filters = [my_high_pass, my_high_shelf]

# Use FIR approximation for faster speed on GPU.
# This idea is from AudioTools:
# https://github.com/descriptinc/audiotools/blob/master/audiotools/core/loudness.py
# We can set the FIR length with the `zeros` keyword.
meter9 = jln.Meter(rate, use_fir=True, zeros=2048)

Batched operation

Using jax allows us to calculate loudness and normalize across a batch dimension using vmap (or pmap across devices). Examples from tests:

def test_batched_integrated_loudness():
    data, rate = sf.read("tests/data/sine_1000.wav")
    data = data.T # convert to (channels, samples) for jaxloudnorm
    meter = pyln.Meter(rate)
    loudness = jax.vmap(meter.integrated_loudness)(jnp.stack([data, data, data]))

    assert jnp.allclose(loudness, jnp.full(loudness.shape, -3.0523438444331137))

def test_batched_loudness_normalize():
    data, rate = sf.read("tests/data/sine_1000.wav")
    data = data.T # convert to (channels, samples) for jaxloudnorm
    data = jnp.stack([data, data, data, data])
    meter = pyln.Meter(rate)
    loudness = jax.vmap(meter.integrated_loudness)(data)
    norm = jax.vmap(pyln.normalize.loudness, in_axes=(0, 0, None))(data, loudness, -6.0)
    loudness = jax.vmap(meter.integrated_loudness)(norm)

    assert jnp.allclose(loudness, jnp.full(loudness.shape, -6.0))

`

Dependencies

The examples above read audio with python-soundfile (https://github.com/bastibe/python-soundfile), which jaxloudnorm itself does not require. Install it with pip install soundfile if you want to load files the same way.

References

Ian Dash, Luis Miranda, and Densil Cabrera, "Multichannel Loudness Listening Test," 124th International Convention of the Audio Engineering Society, May 2008

Pedro D. Pestana and Álvaro Barbosa, "Accuracy of ITU-R BS.1770 Algorithm in Evaluating Multitrack Material," 133rd International Convention of the Audio Engineering Society, October 2012

Pedro D. Pestana, Josh D. Reiss, and Álvaro Barbosa, "Loudness Measurement of Multitrack Audio Content Using Modifications of ITU-R BS.1770," 134th International Convention of the Audio Engineering Society, May 2013

Steven Fenton and Hyunkook Lee, "Alternative Weighting Filters for Multi-Track Program Loudness Measurement," 143rd International Convention of the Audio Engineering Society, October 2017

Brecht De Man, "Evaluation of Implementations of the EBU R128 Loudness Measurement," 145th International Convention of the Audio Engineering Society, October 2018.

Metadata

Release files for jaxloudnorm 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jaxloudnorm 0.3.2
File Size Uploaded Provenance
jaxloudnorm-0.3.2.tar.gz 15.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for jaxloudnorm 0.3.2
File Interpreter ABI Platform
jaxloudnorm-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 28.7 kB

Release files / jaxloudnorm-0.3.2.tar.gz

Download URL jaxloudnorm-0.3.2.tar.gz
Size 15.4 kB
Tags Source
SHA-256 checksum
How to use checksums
a8667c150b7bc8c71f9243b4d9ac2f564f9acfe2f72a9e5cb3123bd50e4831c0
BLAKE2b-256 checksum
How to use checksums
717c423e5bca295f7182618561a37a7e99fb1f439784f777d1aa43612d99cab8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / jaxloudnorm-0.3.2-py3-none-any.whl

Download URL jaxloudnorm-0.3.2-py3-none-any.whl
Size 13.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
de1d5810c9b5139e99126e94a57b726c11b88452a3a32596536b33a49b37bc6f
BLAKE2b-256 checksum
How to use checksums
19ba340b91a1a012c21c969090be15b4b6a1181f97391d7b840cf56cf510554c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Security for jaxloudnorm 0.3.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page