Skip to main content

sf-limiter

sf-limiter (short for “straightforward limiter”) is a look-ahead brick-wall audio limiter with a dependency-free Rust core and optional 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.0.tar.gz (39.1 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.0-cp311-abi3-win_amd64.whl (175.8 kB view details)

Uploaded CPython 3.11+Windows x86-64

sf_limiter-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (304.6 kB view details)

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

sf_limiter-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (299.5 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64

sf_limiter-0.1.0-cp311-abi3-macosx_11_0_arm64.whl (271.9 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

sf_limiter-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl (276.1 kB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: sf_limiter-0.1.0.tar.gz
  • Upload date:
  • Size: 39.1 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.0.tar.gz
Algorithm Hash digest
SHA256 d786d4b97e67526a84ae1049a146bb9ecb0392b257b99a57f2ed3241b392bf49
MD5 fca7407952555d5c9aeb573738135d0e
BLAKE2b-256 953fd4dc1a527bc66f038976c6426ef5dfec769e7ff6bb6d9a116e480621f44d

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.0.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.0-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: sf_limiter-0.1.0-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 175.8 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.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 47de2ef4f1c182ece60f9fde4061586e2c6debd9ff7edef620184387a4a127ab
MD5 805ce7dae4b29c3e8d2533a560403eb6
BLAKE2b-256 af34c05470bebd1aba1c108fe5107f9ccff10602d4870788fbe002edd2772669

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.0-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.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sf_limiter-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5635a68e153232d022d85cb8c982c4658765acdacff08ea48ca3e914f8bf00cd
MD5 8b8b9ed8e15265dc4bd646d7af7a8662
BLAKE2b-256 129737798994d7af80cfc9f75a6f23d81c4d76d386d1db50117e77a1e0b7d303

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.0-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.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for sf_limiter-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b1c21a81a4f0d408858fdabf109b421cedb572c29900a078d00da9a8fd381d3f
MD5 ce02a6c2d4334bc50809f218c48a5e42
BLAKE2b-256 af4ef53200b125255aa55a54c820e6434c1f1588ce75a7714c40e2f81213a8db

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.0-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.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for sf_limiter-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5cba79eae7f5175579bb5a7dc57f43258cc796e282ce93bc328a6451c7079312
MD5 ceedd0dfe55f582a57839dff8a689aa5
BLAKE2b-256 792b7c6e57b7723886acd304c870f9393afed9ff0c257f2391a6d43d513fa127

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.0-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.0-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for sf_limiter-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 8ab8795aed690abfcc6677e48e058549f6387219e61dda49efa995e977898097
MD5 754d94056a0757dda5d13e4fe1833493
BLAKE2b-256 c5cff06bd6e3002f65ac9768238672b8b24b9eb34d8b74400bc469d60c9f093a

See more details on using hashes here.

Provenance

The following attestation bundles were made for sf_limiter-0.1.0-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