pyloudnorm

repository·master·Indexed 21 days ago

https://github.com/csteinmetz1/pyloudnorm

A Python implementation of the ITU-R BS.1770-4 loudness algorithm. It provides tools to measure integrated loudness and loudness range (LRA) via the Meter class, and perform peak or loudness normalization using the normalize module. The library supports various filter classes (including DeMan, Fenton/Lee, and Dash et al.) and allows for custom IIR filters via the IIRfilter class.

Tokens
3.9K
Snippets
17
Records
18
Agent score
72%

What's inside pyloudnorm

  1. Install pyloudnorm

    master

    You can install pyloudnorm using pip. For the latest features, install directly from the GitHub repository.

    # Standard installation
    pip install pyloudnorm
    
    # Install latest from GitHub
    pip install git+https://github.com/csteinmetz1/pyloudnorm
  2. Measure the loudness of an audio file

    master

    To measure the integrated loudness of an audio file, use the pyln.Meter class. You must provide the sampling rate of the audio. The audio data should be an ndarray (typically loaded via soundfile).

    import soundfile as sf
    import pyloudnorm as pyln
    
    data, rate = sf.read("test.wav") # load audio (with shape (samples, channels))
    meter = pyln.Meter(rate) # create BS.1770 meter
    loudness = meter.integrated_loudness(data) # measure loudness
  3. Normalize audio files by peak or loudness

    master

    The pyln.normalize module provides methods to adjust audio levels:

    1. Peak Normalization: Use pyln.normalize.peak(data, target_peak_db) to scale audio to a specific decibel peak.
    2. Loudness Normalization: Use pyln.normalize.loudness(data, current_loudness, target_loudness_lufs) to scale audio to a target LUFS value. This requires measuring the current loudness first using a Meter.
    import soundfile as sf
    import pyloudnorm as pyln
    
    data, rate = sf.read("test.wav") # load audio
    
    # peak normalize audio to -1 dB
    peak_normalized_audio = pyln.normalize.peak(data, -1.0)
    
    # loudness normalize audio to -12 dB LUFS
    meter = pyln.Meter(rate)
    loudness = meter.integrated_loudness(data)
    loudness_normalized_audio = pyln.normalize.loudness(data, loudness, -12.0)
  4. Configure Meter block size and filter classes

    master

    The pyln.Meter class allows for advanced configuration of the analysis process:

    • block_size: Adjust the gating block size in seconds (e.g., 0.200 for 200ms). The default is 400ms.
    • filter_class: Choose from different frequency weighting filters:
      • "BS.1770": Standard BS.1770 meter (default).
      • "DeMan": Fully compliant filters.
      • "Fenton/Lee 1": Low complexity improvement.
      • "Fenton/Lee 2": Higher complexity improvement.
      • "Dash et al.": Early modification option.
      • "custom": Use this to provide your own IIR filters.
    import soundfile as sf
    import pyloudnorm as pyln
    
    data, rate = sf.read("test.wav")
    
    # block size configuration
    meter1 = pyln.Meter(rate)                               # 400ms block size
    meter2 = pyln.Meter(rate, block_size=0.200)             # 200ms block size
    
    # filter class configuration
    meter3 = pyln.Meter(rate)                               # BS.1770 meter
    meter4 = pyln.Meter(rate, filter_class="DeMan")         # fully compliant filters  
    meter5 = pyln.Meter(rate, filter_class="Fenton/Lee 1")  # low complexity improvement
    meter6 = pyln.Meter(rate, filter_class="Fenton/Lee 2")  # higher complexity improvement
    meter7 = pyln.Meter(rate, filter_class="Dash et al.")   # early modification option
  5. Use custom IIR filters with Meter

    master

    You can create custom frequency weighting filters using the IIRfilter class and load them into a Meter initialized with filter_class="custom". You assign filters to the meter via the _filters attribute.

    import soundfile as sf
    import pyloudnorm as pyln
    from pyloudnorm import IIRfilter
    
    data, rate = sf.read("test.wav")
    
    # 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 = pyln.Meter(rate, filter_class="custom")
    
    # load your filters into the meter
    meter8._filters = {'my_high_pass' : my_high_pass, 'my_high_shelf' : my_high_shelf}
  6. Measure Loudness Range (LRA)

    master

    To quantify the variation in loudness over time (measured in LU), use the loudness_range method of the Meter class. This implementation is based on EBU Tech 3342.

    import soundfile as sf
    import pyloudnorm as pyln
    
    data, rate = sf.read("test.wav") # load audio
    
    meter = pyln.Meter(rate) # create BS.1770 meter
    lra = meter.loudness_range(data) # measure loudness range
    
    print(f"Loudness Range: {lra:.1f} LU")
  7. Loudness normalize an audio signal with loudness()

    master

    Use loudness(data, input_loudness, target_loudness) to normalize an input multichannel audio signal to a specific loudness level in dB LUFS.

    Parameters:

    • data (ndarray): The input multichannel audio data.
    • input_loudness (float): The current loudness of the input signal in dB LUFS.
    • target_loudness (float): The desired target loudness for the output in dB LUFS.

    Returns:

    • output (ndarray): The loudness normalized audio data.

    Note: If the resulting output has a maximum absolute amplitude $\ge 1.0$, a UserWarning is issued regarding potentially clipped samples.

    import numpy as np
    from pyloudnorm import loudness
    
    # Example: Loudness normalize from -24 LUFS to -12 LUFS
    data = np.random.uniform(-1, 1, 44100)
    # Assuming input_loudness was previously measured as -24.0
    normalized_data = loudness(data, -24.0, -12.0)
  8. Peak normalize an audio signal with peak()

    master

    Use peak(data, target) to normalize an input multichannel audio signal to a specific peak amplitude.

    Parameters:

    • data (ndarray): The input multichannel audio data.
    • target (float): The desired peak amplitude in dB.

    Returns:

    • output (ndarray): The peak normalized audio data.

    Note: If the resulting output has a maximum absolute amplitude $\ge 1.0$, a UserWarning is issued regarding potentially clipped samples.

    import numpy as np
    from pyloudnorm import peak
    
    # Example: Peak normalize to -1 dB
    data = np.random.uniform(-1, 1, 44100)
    normalized_data = peak(data, -1.0)
  9. Use the IIRFilter class for frequency weighting

    master

    The IIRFilter class is used to generate and apply Infinite Impulse Response (IIR) filters to audio data. This is typically done to apply frequency weighting (like those required by loudness standards) before measuring loudness.

    Parameters

    When instantiating IIRFilter, provide the following arguments:

    • G (float): Gain of the filter in dB.
    • Q (float): The Q factor of the filter.
    • fc (float): Center frequency of the shelf in Hz.
    • rate (float): Sampling rate in Hz.
    • filter_type (str): The shape/type of the filter (see supported types below).
    • passband_gain (float, optional): A multiplier applied to the filtered signal. Defaults to 1.0.

    Supported filter_type values

    Standard RBJ (Cookbook) filters:

    • 'high_shelf'
    • 'low_shelf'
    • 'high_pass'
    • 'low_pass'
    • 'peaking'
    • 'notch'

    DeMan filters (for ITU specification compliance):

    • 'high_shelf_DeMan'
    • 'high_pass_DeMan'

    Note: If you require full compliance with ITU specifications, use the 'DeMan' filter types.

    from pyloudnorm.iirfilter import IIRFilter
    
    # Example: Create a high-pass filter
    filter = IIRFilter(G=0, Q=0.707, fc=100, rate=44100, filter_type='high_pass')
    
    # Apply the filter to audio data
    filtered_audio = filter.apply_filter(audio_data)
  10. Import the pyloudnorm public API

    master

    The pyloudnorm package provides tools for loudness measurement and normalization. The primary public interface is available via the top-level module, which exports the Meter class and the IIRfilter class from the .meter submodule, as well as the util and normalize submodules.

    import pyloudnorm
    
    # Accessing exported classes
    # pyloudnorm.Meter
    # pyloudnorm.IIRfilter
    
    # Accessing submodules
    # pyloudnorm.util
    # pyloudnorm.normalize
  11. Configure the weighting filter class

    master

    You can change the weighting filter used by the Meter instance by setting the filter_class property. Setting this property resets the internal filters.

    Supported values:

    • 'K-weighting'
    • 'Fenton/Lee 1'
    • 'Fenton/Lee 2'
    • 'Dash et al.'
    • 'DeMan'
    • 'custom'

    Note: Setting this property will re-initialize the internal _filters dictionary based on the selected class.

    meter = Meter(rate=44100)
    meter.filter_class = 'Fenton/Lee 1'
  12. Use the Meter class for loudness measurement

    master

    The Meter class is the primary tool for measuring loudness in audio signals according to standard loudness models (like EBU R128). It is exported directly from the pyloudnorm top-level module.

    from pyloudnorm import Meter
    
    # Example usage (requires audio data and sample rate)
    # meter = Meter(rate)
    # loudness = meter.measure(audio)