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.0hold_ms=15.0release_ms=40.0axis=-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_interleavedorprocess_interleaved_inplace. - Channel-planar: all frames of the first channel are followed by all
frames of the next channel. Use
process_planarorprocess_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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d786d4b97e67526a84ae1049a146bb9ecb0392b257b99a57f2ed3241b392bf49
|
|
| MD5 |
fca7407952555d5c9aeb573738135d0e
|
|
| BLAKE2b-256 |
953fd4dc1a527bc66f038976c6426ef5dfec769e7ff6bb6d9a116e480621f44d
|
Provenance
The following attestation bundles were made for sf_limiter-0.1.0.tar.gz:
Publisher:
release.yml on Sytronik/sf-limiter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sf_limiter-0.1.0.tar.gz -
Subject digest:
d786d4b97e67526a84ae1049a146bb9ecb0392b257b99a57f2ed3241b392bf49 - Sigstore transparency entry: 2496495555
- Sigstore integration time:
-
Permalink:
Sytronik/sf-limiter@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Sytronik
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47de2ef4f1c182ece60f9fde4061586e2c6debd9ff7edef620184387a4a127ab
|
|
| MD5 |
805ce7dae4b29c3e8d2533a560403eb6
|
|
| BLAKE2b-256 |
af34c05470bebd1aba1c108fe5107f9ccff10602d4870788fbe002edd2772669
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sf_limiter-0.1.0-cp311-abi3-win_amd64.whl -
Subject digest:
47de2ef4f1c182ece60f9fde4061586e2c6debd9ff7edef620184387a4a127ab - Sigstore transparency entry: 2496495572
- Sigstore integration time:
-
Permalink:
Sytronik/sf-limiter@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Sytronik
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Trigger Event:
push
-
Statement type:
File details
Details for the file sf_limiter-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: sf_limiter-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 304.6 kB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5635a68e153232d022d85cb8c982c4658765acdacff08ea48ca3e914f8bf00cd
|
|
| MD5 |
8b8b9ed8e15265dc4bd646d7af7a8662
|
|
| BLAKE2b-256 |
129737798994d7af80cfc9f75a6f23d81c4d76d386d1db50117e77a1e0b7d303
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sf_limiter-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
5635a68e153232d022d85cb8c982c4658765acdacff08ea48ca3e914f8bf00cd - Sigstore transparency entry: 2496495579
- Sigstore integration time:
-
Permalink:
Sytronik/sf-limiter@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Sytronik
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Trigger Event:
push
-
Statement type:
File details
Details for the file sf_limiter-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: sf_limiter-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 299.5 kB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1c21a81a4f0d408858fdabf109b421cedb572c29900a078d00da9a8fd381d3f
|
|
| MD5 |
ce02a6c2d4334bc50809f218c48a5e42
|
|
| BLAKE2b-256 |
af4ef53200b125255aa55a54c820e6434c1f1588ce75a7714c40e2f81213a8db
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sf_limiter-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
b1c21a81a4f0d408858fdabf109b421cedb572c29900a078d00da9a8fd381d3f - Sigstore transparency entry: 2496495565
- Sigstore integration time:
-
Permalink:
Sytronik/sf-limiter@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Sytronik
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Trigger Event:
push
-
Statement type:
File details
Details for the file sf_limiter-0.1.0-cp311-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: sf_limiter-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 271.9 kB
- Tags: CPython 3.11+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5cba79eae7f5175579bb5a7dc57f43258cc796e282ce93bc328a6451c7079312
|
|
| MD5 |
ceedd0dfe55f582a57839dff8a689aa5
|
|
| BLAKE2b-256 |
792b7c6e57b7723886acd304c870f9393afed9ff0c257f2391a6d43d513fa127
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sf_limiter-0.1.0-cp311-abi3-macosx_11_0_arm64.whl -
Subject digest:
5cba79eae7f5175579bb5a7dc57f43258cc796e282ce93bc328a6451c7079312 - Sigstore transparency entry: 2496495591
- Sigstore integration time:
-
Permalink:
Sytronik/sf-limiter@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Sytronik
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Trigger Event:
push
-
Statement type:
File details
Details for the file sf_limiter-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: sf_limiter-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 276.1 kB
- Tags: CPython 3.11+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ab8795aed690abfcc6677e48e058549f6387219e61dda49efa995e977898097
|
|
| MD5 |
754d94056a0757dda5d13e4fe1833493
|
|
| BLAKE2b-256 |
c5cff06bd6e3002f65ac9768238672b8b24b9eb34d8b74400bc469d60c9f093a
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sf_limiter-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl -
Subject digest:
8ab8795aed690abfcc6677e48e058549f6387219e61dda49efa995e977898097 - Sigstore transparency entry: 2496495585
- Sigstore integration time:
-
Permalink:
Sytronik/sf-limiter@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Sytronik
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ec019d36e51696846c4613ca3257d150cd8a9a3e -
Trigger Event:
push
-
Statement type: