Skip to main content

sf-limiter

PyPI version PyPI downloads License

sf-limiter (short for “straightforward limiter”) is a look-ahead brick-wall audio limiter with a Rust core and Python bindings for NumPy.

It applies one linked gain value to every channel in a frame, preserving the relative balance between channels.

Non-streaming: The current API processes a complete audio buffer offline. Each call starts with a fresh gain envelope, so limiter state does not carry across chunks or successive calls. The output has the same shape and length as the input, while the limiter uses future samples equal to its attack-time look-ahead.

Note: The limiter algorithm itself was not AI-generated. Codex was used only to help with API design, documentation, and packaging.

Python 3.11+

Install the package from PyPI:

python -m pip install sf-limiter

Limit a mono NumPy array:

import numpy as np
import sf_limiter

audio = np.array([0.0, 0.5, 3.0, -4.0, 0.25], dtype=np.float64)
limited, frame_gains = sf_limiter.limit(audio, sample_rate=48_000)

assert limited.dtype == np.float32
assert np.max(np.abs(limited), initial=0.0) <= 1.0

The one-shot limit function accepts these keyword parameters:

  • threshold_dBFS=0.0 (dBFS)
  • attack_ms=5.0
  • hold_ms=15.0
  • release_ms=40.0
  • axis=-1

For repeated use, configure a limiter object once:

limiter = sf_limiter.SFLimiter(
    48_000,
    threshold_dBFS=-1.0,
    attack_ms=5.0,
    hold_ms=15.0,
    release_ms=40.0,
)
limited, frame_gains = limiter.process(audio)

limiter.threshold_dBFS returns the configured dBFS value, while limiter.threshold returns the corresponding linear amplitude.

Input may be a one-dimensional mono array or a two-dimensional multichannel array. The last axis is interpreted as frames by default, so the usual shape is (channels, frames). Pass axis=0 for (frames, channels). The input is converted to float32 without being mutated; the returned audio is a new float32 array, and frame_gains contains one value per frame.

Each call starts from a neutral gain envelope. Non-finite samples and invalid configuration values raise ValueError.

Rust

The core Rust API accepts flat f32 samples in either of these layouts:

  • Frame-interleaved: each frame contains one sample per channel. Use process_interleaved or process_interleaved_inplace.
  • Channel-planar: all frames of the first channel are followed by all frames of the next channel. Use process_planar or process_planar_inplace.

For frame-interleaved audio:

use sf_limiter::SFLimiter;

let input = [0.0, 0.5, 3.0, -4.0, 0.25];
let mut limiter = SFLimiter::with_default(48_000)?;
let output = limiter.process_interleaved(&input, 1)?;

assert!(output.audio.iter().all(|sample| sample.abs() <= 1.0));
# Ok::<(), sf_limiter::LimiterError>(())

Use process_interleaved_inplace to reuse the input allocation. Both methods return one linked gain value per frame and reset the envelope on every call.

For channel-planar audio:

let mut planar = [0.0, 0.5, 3.0, -4.0, 0.25, -0.25];
let mut limiter = SFLimiter::with_default(48_000)?;
let frame_gains = limiter.process_planar_inplace(&mut planar, 2)?;

assert_eq!(frame_gains.len(), 3);
# Ok::<(), sf_limiter::LimiterError>(())

The Python binding always uses the planar core path. Default two-dimensional axis=-1 input is already planar and is processed directly; (frames, channels) input is transposed to planar layout for processing and then restored to its original layout for the returned array. The interleaved core path remains available to Rust callers.

Ceiling guarantee

For finite input, a valid channel count, and a finite threshold_dBFS no greater than 0.0 dBFS, every returned discrete sample is finite and has an absolute value no greater than the corresponding linear ceiling (10 ** (threshold_dBFS / 20)). The test suite checks this with large impulses, high-level deterministic noise, mono input, and linked multichannel input.

This is a sample-peak limiter. It does not oversample to detect reconstructed inter-sample (true-peak) excursions.

Design reference

The limiter design was informed by Geraint Luff's “Designing a straightforward limiter” (Signalsmith Audio, 2022). In particular, this implementation follows the article's look-ahead structure: a moving minimum of permissible gain, an exponential release, and finite-length cascaded box-filter smoothing.

The Rust implementation was extracted from limiter.rs in thesia and adapted into a standalone crate with a dependency-free core.

Development

Run the Rust tests:

cargo test

Create the Python environment with the test dependencies, build the extension, and run its tests:

uv sync
uv run pytest -q

Compare the Python API performance with numpy-audio-limiter:

uv sync --group benchmark
uv run --group benchmark python benchmarks/compare_numpy_audio_limiter.py

The benchmark uses contiguous channel-planar arrays shaped (channels, frames) for both implementations and measures reusable and one-shot sf_limiter calls separately. Use --help to select durations, channel counts, timing repetitions, and limiter settings.

TODO

  • Refine the Rust API
  • Add a streaming API
  • Publish the crate to crates.io
  • Implement an optional true-peak limiter with oversampling

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sf_limiter-0.1.1.tar.gz (39.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

sf_limiter-0.1.1-cp311-abi3-win_amd64.whl (175.9 kB view details)

Uploaded CPython 3.11+Windows x86-64

sf_limiter-0.1.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (304.7 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

sf_limiter-0.1.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (299.6 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64

sf_limiter-0.1.1-cp311-abi3-macosx_11_0_arm64.whl (272.0 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

sf_limiter-0.1.1-cp311-abi3-macosx_10_12_x86_64.whl (276.3 kB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file sf_limiter-0.1.1.tar.gz.

File metadata

  • Download URL: sf_limiter-0.1.1.tar.gz
  • Upload date:
  • Size: 39.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sf_limiter-0.1.1.tar.gz
Algorithm Hash digest
SHA256 d2e49be563d7311e4bd448fb3fc514252b4a27880a67ed504a0d7bec46617314
MD5 17971ee783907d47407182e16675a91f
BLAKE2b-256 8bd388de59c63ce7bd4f26c8ec2c5ab2f2ef0a9464cdc02b7cafd5502224a4ba

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.1.tar.gz:

Publisher: release.yml on Sytronik/sf-limiter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sf_limiter-0.1.1-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: sf_limiter-0.1.1-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 175.9 kB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sf_limiter-0.1.1-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 3a85af87b54d5f4e6656266a6629c4095df80e5b693e4e39a662804844fc4e39
MD5 104fbe0fd49f71ef199b971068f7b5c8
BLAKE2b-256 1790bf48a356afae40c318508978219ce99af28fcc24a7ba56f5d07c512d1edd

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.1-cp311-abi3-win_amd64.whl:

Publisher: release.yml on Sytronik/sf-limiter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sf_limiter-0.1.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sf_limiter-0.1.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 46f6a3768893b713514a50c2eb9fdfcb8bbbdcd1753abc1a27083aca872bb5f0
MD5 30a2e8d8d04125bde006e53d3ecb93ec
BLAKE2b-256 3f23b693701e9d0b5c29dae07dfc56decc14166c11f520dfed5e424f59913639

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on Sytronik/sf-limiter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sf_limiter-0.1.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for sf_limiter-0.1.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5e6f8344b17d76ba484e41d46a22a75c6346332d83589b2700c4d08d73dd1210
MD5 8c48f7ca96359871acdc15493119e801
BLAKE2b-256 efb8b4b19c7d61eef0315011a231f00b3aa9aac178cdcca1e9c6f4c7e5454aa9

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on Sytronik/sf-limiter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sf_limiter-0.1.1-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for sf_limiter-0.1.1-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3dad988d5d21ac1ad45767cdc6a042999e057cf7245d3131202f3002f6e1f420
MD5 157231014f10e9218f0a45d58a81a5ce
BLAKE2b-256 0a5a1823af89636550b83bfd1559bae420bc46cb51e3b725cb3038317d3b06c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.1-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on Sytronik/sf-limiter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sf_limiter-0.1.1-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for sf_limiter-0.1.1-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a777dc91e6a20d3c81b88fb7d962d4e414e574be81837fb9f8e20f882f5f563c
MD5 7d3dadcabfefdcdb36537c3024a45f35
BLAKE2b-256 1639d8715516f34e1b62d2f3709e2049314ddf7225ba67ed0a0996551fcd0c7e

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.1-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on Sytronik/sf-limiter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page