feat(quench): add Quench sub-safe clipper

Quench splits the signal with a Linkwitz-Riley crossover and lets the sub
pass unclipped. The top is clipped symmetrically at the ceiling minus the
sub's held peak, so it does not pump at the sub's rate and the sum stays
under the ceiling. What the clip removes is high-passed at the split, so its
products stay out of the low band. Two correction passes and an oversampled
hard clip hold the ceiling; a safety clip catches the downsampler's ringing.

- Controls: Drive, Ceiling, Split, Hold, Soft, Bypass.
- Listen to Quench, a plain clipper at the same settings, or the delta.
- Editor meter compares how much the low band changed for Quench and for a
  plain clip, with a scope of the output, the sub and the top's room.
- Measured: sub level +0.04 dB against -2.2 dB for a plain clip, low-band
  products -35 dB against -16 dB, at 0.5-1.2 dB less RMS.
- Registered in the catalog, workflows, editor-check, README, chain and
  development docs, and the website copy.
This commit is contained in:
nvrl committed 2026-11-06 15:51:36 +01:00
1 parent 77ee4a9078
commit 3d316cbe49
28 files changed
+4397 -17

No files matched your search

+8 -2
View File
@@ -8,7 +8,8 @@ in the chain changes the audio, the pitch detection after it can go wrong.
```text
bass track: synth → Lathe → Temper → Planish → Braze → Knurl → Patina → Weld
bass bus: Anvil → (bus compression, clipping) → Crucible
bass bus: Anvil → (bus compression) → Quench → Crucible
master: … → Quench (last, or before a true-peak limiter)
```
- **Lathe and Temper before Knurl.** They hear the plain synth, where the pitch
@@ -31,6 +32,10 @@ bass bus: Anvil → (bus compression, clipping) → Crucible
that layer late.
- **Anvil on the bus, in MIDI mode when Knurl is in the chain.** For Kick
lock, send the kick's track to Anvil as a sidechain.
- **Quench last on the bus or the master.** It clips the top and leaves the sub
alone, so put it where you would put a clipper. On the bass bus after Anvil,
set its Split at or a little above Anvil's Split: Anvil's sub then passes
Quench untouched. Quench does not detect pitch, so it can sit after Knurl.
- **Crucible at the end of the chain you want to resample.**
## Knurl and pitch detection
@@ -53,7 +58,8 @@ and route the bass's MIDI notes to it.
## Latency
Each tracked plugin adds its own lookahead: Anvil 80 ms, Lathe, Temper,
Planish and Braze about 67 ms, Knurl about 71 ms, Patina about 45 ms. A full chain is
Planish and Braze about 67 ms, Knurl about 71 ms, Patina about 45 ms, Quench
under 1 ms. A full chain is
about 400 ms. FL
Studio compensates this for playback and rendering, but playing a MIDI keyboard
through the full chain is not practical. Write with a shorter chain and add the
+3 -2
View File
@@ -25,7 +25,7 @@ Patina has `render` for offline WAV evaluation. The shared crates are:
- `common-ui`: palette, embedded fonts, header, panels, knobs, meters.
- `common-dsp`: filters, YIN pitch tracking, the note tracker used by Anvil,
Lathe, Temper, Knurl, Planish and Braze, 4× oversampling, meters and WAV files.
Lathe, Temper, Knurl, Planish and Braze, 4× oversampling (also Quench's), meters and WAV files.
The wrappers stay separate workspaces, each with its own lockfile, so the
NIH-plug Git dependency stays out of the root workspace. Host identities and
@@ -45,7 +45,7 @@ python3 -m unittest discover -s scripts/tests -v
```
Products: `rivet`, `patina`, `anvil`, `crucible`, `lathe`, `temper`, `weld`,
`knurl`, `planish`, `braze`.
`knurl`, `planish`, `braze`, `quench`.
`check-plugin.py` runs formatting, tests and clippy for one product's packages
and its wrapper, without compiling the other products. Run it for every product
@@ -146,6 +146,7 @@ identify plugins by CLAP ID, so the vendor name does not affect saved projects.
| Knurl | (new) | `io.narl.bass-foundry.knurl` |
| Planish | (new) | `io.narl.bass-foundry.planish` |
| Braze | (new) | `io.narl.bass-foundry.braze` |
| Quench | (new) | `io.narl.bass-foundry.quench` |
CLAP IDs use the form `io.narl.bass-foundry.<product>`. Builds tagged before
this scheme used `io.storyboard.*` IDs; hosts treat the new IDs as different
+25 -2
View File
@@ -263,8 +263,8 @@ one period of the note, so heavy settings do not ripple at f0. See [Planish](pla
Patina already cut fixed formants on every note, but it also cut a boosted
harmonic as hard (5.7 dB), at a position that moved with the note.
Open: MIDI as the pitch source.
3. Planish (done, released 0.1.0), then Quench and Ballast: they fill the mix
and master gap.
3. Planish (done, released 0.1.0), then Quench (done, unreleased) and Ballast:
they fill the mix and master gap.
- In parallel, from the research findings, in this order: Weld delay
spread (done, Weld 0.3.0); the fatness lane, as the first Assay piece
(prototype `scripts/fatness.py`); Anvil Ghost harmonics and Phone listen
@@ -328,6 +328,29 @@ Quenching hardens hot metal in one fast step. Quench clips only above a split
frequency and adds the clean sub back with its own headroom, so the master can
be clipped hard without distorting the low end. Pairs with Anvil's split.
Built (unreleased 0.1.0, see [Quench](quench/README.md)). Design checks, made
in a prototype before the plugin:
- Splitting and giving the top the instantaneous room, clamp(top, −C − sub,
C − sub), is exactly a plain clip of the sum: the error is the same signal.
The sub-safe part has to come from somewhere else.
- Feeding the clip error back through 1 − lowpass diverges: the complement of
an LR4 lowpass peaks at 1.5× near the split.
- What works: clip the top symmetrically at the ceiling minus the sub's held
peak (no pumping at the sub's rate, the sum stays under the ceiling), then
high-pass the clip error at the split so its products below the split go.
Two clip-and-high-pass passes and an oversampled hard clip hold the ceiling.
Measured: sub level +0.04 dB against −2.2 dB for a plain clip; low-band
products −35 dB against −16 dB. Cost: 0.5–1.2 dB less RMS at the same
ceiling.
- Where it does not help: a top whose fundamental lies within an octave of the
split is partly in the sub band (saw at 98 Hz over a 49 Hz sub: about the same
as a plain clip).
- Next ideas: link the channels' sub peak and offer mono below the split
(with Gauge); give the top the room on the sub's far side too (asymmetric)
with the error still high-passed, and measure whether that wins back the
loudness without pumping; a true-peak ceiling.
### Scribe — audio to MIDI (problem 18)
A scribe marks lines on metal. Scribe runs the note tracker on a bass and
+16
View File
@@ -0,0 +1,16 @@
# Quench changelog
## Unreleased (0.1.0)
- Introduce Quench, a clipper that clips the top and lets the sub pass clean.
- A Linkwitz–Riley split at **Split** (40–300 Hz). The top is clipped at the
ceiling minus the sub's held peak; **Hold** sets how long that peak holds.
- What the clip removes is high-passed at Split, so its products stay out of
the low band. Two correction passes and an oversampled hard clip hold the
ceiling; a safety clip catches the downsampler's ringing.
- **Drive**, **Ceiling**, **Soft** (knee of the top's clip), **Bypass**.
- Listen to **Quench**, a **Plain** clipper at the same settings, or the
**Delta** that Quench takes away. Not saved.
- Editor: how much the low band changed for Quench and for a plain clip, how
far the top is clipped, the sub's peak and the room it leaves, and a scope.
- 4× oversampling; 37 samples of latency.
+104
View File
@@ -0,0 +1,104 @@
# Quench
Quench clips the top of the mix as hard as you like and lets the sub pass clean.
Current version **0.1.0** (unreleased).
Riddim and dubstep masters are clipped hard. A plain clipper clips the sum of
the sub and everything above it. Near the sub's peaks only one side of the top
gets clipped, so the clipping takes energy out at the sub's rate: the sub loses
level, and the low end fills with products that were not in the mix. Quench
splits the signal at a frequency you set, never clips the sub, and clips only
the top, in the room the sub leaves under the ceiling.
![Quench](assets/editor.png)
## Install on Windows
Copy `Quench.clap` into `C:\Program Files\Common Files\CLAP\`. In FL Studio
2024.1 or newer, open Options → Manage plugins, enable Verify plugins, and Find
installed plugins. Load Quench last on the master or on the bass bus. Keep the
font license with redistributed packages.
## Work with it
1. Put Quench where you would put a clipper: last on the master, or last on
the bass bus. Before a true-peak limiter is fine.
2. Set **Ceiling**, the highest output peak.
3. Set **Split** above the highest sub note, or at Anvil's Split when Anvil
makes the sub. Everything below Split passes without clipping.
4. Raise **Drive** until the top clips as hard as you want. The panel shows
how far the top is clipped.
5. Press **PLAIN** to hear a plain clipper at the same settings, then
**QUENCH** again. **DELTA** plays only what Quench takes away. The listen
choice is not saved and goes back to QUENCH when the editor closes.
The panel shows:
- **Low end changed by**: how much the band below Split differs from the
input, against the sub's level, for Quench and for a plain clip of the same
signal. Lower is cleaner. It reads "—" when no sub plays.
- **Top clipped by**: how far the top's loudest peak went past its room.
- **Sub peak · room left**: the sub's peak after Drive and the room it leaves
the top under the ceiling.
- The scope: the output (grey), the sub band (blue), and the sub plus or minus
the top's room (thin lines). The output stays between the thin lines.
Other controls:
- **Hold** keeps the room the sub's peak needs for this long. With a hold
longer than half a period of the lowest note (17 ms at 30 Hz), the top's
clip level stays steady through the sub's cycle and the top does not pump
with the sub. Shorter holds give the top a little more room between sub
peaks, and that room then changes at the sub's rate.
- **Soft** bends the top's clip: 0 % is a hard clip, 100 % a soft curve from
the start. The ceiling stays a hard limit.
- **Bypass** crossfades to the input, delayed by the latency.
When the sub alone reaches the ceiling, the top has no room left. The panel
then warns: lower Drive or the sub. A safety clip still holds the ceiling, and
that clip does cut the sub.
### How it works
A Linkwitz–Riley crossover splits the signal at Split. The sub passes. The top
is clipped symmetrically at the ceiling minus the sub's held peak, so the sum
of sub and top never goes over the ceiling.
Clipping the top also makes products below Split, for example difference
tones between its partials. Quench high-passes what the clip removed at Split,
so those products do not reach the low band. High-passing lets a few peaks
overshoot. Two correction passes clip those again and high-pass the correction,
and a final hard clip at the ceiling takes the small rest. All of this runs at
4× oversampling. A safety clip after the downsampler catches the filters'
ringing; it reads "idle" or a few hundredths of a dB.
Measured on a 50 Hz sub at −10.5 dBFS under a top of five unrelated partials
peaking about 6 dB over the ceiling:
| | Sub level | Low-band products |
| --- | --- | --- |
| Plain clip | −2.2 dB | −16 dB |
| Quench | +0.04 dB | −35 dB |
Low-band products are everything below 110 Hz except the sub, against the
sub's level.
Quench pays for this in loudness. The top gets the room on the sub's quieter
side only, so at the same ceiling Quench measured 0.5–1.2 dB lower in RMS
than a plain clip. Add Drive to make up for it.
## Timing and limits
Latency is the oversampling filters: 37 samples (0.8 ms at 48 kHz), reported
to the host for delay compensation.
The split is a slope, not a wall. A top whose own fundamental lies near
Split, for example a distorted patch an octave above a 49 Hz sub, is partly in
the sub band. That part passes unclipped and takes up room, and Quench helps
less there: on a saw top at 98 Hz it changed the low end about as much as a
plain clip. Keep the top's lowest partial at least an octave above Split.
Quench keeps the ceiling on sample peaks. True peaks between samples can
still go a little over it: put a true-peak limiter after Quench if the master
needs one. Each channel is clipped on its own; Quench does not link the
channels or turn the sub to mono.
Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB