Describe the Limiter node as a device that holds its reduction (#397)

- Sounds: the table row, and a part on the device under Compressor
  and Limiter. It covers the knobs, the lever, the lamp, the screen,
  how the capture is held and how the reduction is read.
- Architecture: LimiterPanel, LimiterFace and limiterView.
- Development: 1970 editor checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-10-10 20:31:12 +02:00
1 parent beb6022fb9
commit fdb016d88d
3 files changed
+37 -3

No files matched your search

+4 -1
@@ -443,7 +443,10 @@ src/editor/soundfx/ SoundFxEditor (#311: the graph, a sound to try it on, Pla
worked out apart from the drawing), SaturationPanel + SaturationFace + worked out apart from the drawing), SaturationPanel + SaturationFace +
saturationView (#396: the Saturation as a device, the wave a sine comes out as saturationView (#396: the Saturation as a device, the wave a sine comes out as
and the heat it glows with worked out apart from the drawing; its type buttons and the heat it glows with worked out apart from the drawing; its type buttons
are the Reverb's `PickButton`), nodeParamDrag (a knob's drag as one undo step, for the tab and the are the Reverb's `PickButton`), LimiterPanel + LimiterFace + limiterView (#397:
the Limiter as a device, what it takes away read from its taps and caught from
the start of a sound, held once it ends, worked out apart from the drawing),
nodeParamDrag (a knob's drag as one undo step, for the tab and the
node, several settings at once since #389), nodeTabs (which nodes open a tab of node, several settings at once since #389), nodeTabs (which nodes open a tab of
their own) their own)
src/editor/instrument/ InstrumentEditor (#331: the graph over the keys, Preset, Randomize, Mutate, Audition), src/editor/instrument/ InstrumentEditor (#331: the graph over the keys, Preset, Randomize, Mutate, Audition),
+1 -1
@@ -19,7 +19,7 @@ php tests/php/accounts.test.php # the API's accoun
php tests/php/snapshots.test.php # the snapshot store (#231), the same way php tests/php/snapshots.test.php # the snapshot store (#231), the same way
php tests/php/releases.test.php # the release store (#266), the same way php tests/php/releases.test.php # the release store (#266), the same way
php tests/php/files.test.php # uploaded files in a folder per account (#344), the same way php tests/php/files.test.php # uploaded files in a folder per account (#344), the same way
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1969 editor checks, screenshots in /tmp/gm-e2e-*.png node tools/seed-e2e.mjs && node tools/e2e.mjs # 1970 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below ./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result ./e2e.sh status # live progress, or the last run's result
+32 -1
@@ -435,7 +435,7 @@ response of a Reverb, and as what the Sound FX tab tries out. Its row means noth
| **Flanger** | Blends the sound with a copy a few ms late: the jet sound of a flanger, and what sfxr calls its phaser. `offset` is how late the copy is (1 ms by default), `sweep` moves that on by so many ms a second from the start of the sound (0), an LFO adds up to `depth` ms (2) `rate` times a second (0.25 Hz). `feedback` (0.5) and `wet` (1) as on the Phaser. See [below](#phaser-and-flanger). | | **Flanger** | Blends the sound with a copy a few ms late: the jet sound of a flanger, and what sfxr calls its phaser. `offset` is how late the copy is (1 ms by default), `sweep` moves that on by so many ms a second from the start of the sound (0), an LFO adds up to `depth` ms (2) `rate` times a second (0.25 Hz). `feedback` (0.5) and `wet` (1) as on the Phaser. See [below](#phaser-and-flanger). |
| **Pan** | Moves the sound left or right: `pan` -1 is all left, 1 all right, 0 (the default) leaves it in the middle. A mono sound is spread on both sides and then moved (each side 0.707 at 0). A stereo sound keeps the side it goes to and the other side moves over into it, as Web Audio's `StereoPannerNode` does: at 1 both sides are heard on the right. In an [instrument](Instruments#envelopes) an Envelope can move it. Measured (e2e 34, Chrome offline): a mono sine at 0.5 came out 0.5 / 0 at -1 and 0.354 / 0.354 at 0, a stereo one at 0.5 came out 0.354 / 0.854. In the graph the node is drawn as the Gain's device in cyan (#392), with one knob for `Pan`: the middle stands straight up, the turn goes evenly to *L* and *R* engraved at its ends. A linked `Pan` greys the knob. | | **Pan** | Moves the sound left or right: `pan` -1 is all left, 1 all right, 0 (the default) leaves it in the middle. A mono sound is spread on both sides and then moved (each side 0.707 at 0). A stereo sound keeps the side it goes to and the other side moves over into it, as Web Audio's `StereoPannerNode` does: at 1 both sides are heard on the right. In an [instrument](Instruments#envelopes) an Envelope can move it. Measured (e2e 34, Chrome offline): a mono sine at 0.5 came out 0.5 / 0 at -1 and 0.354 / 0.354 at 0, a stereo one at 0.5 came out 0.354 / 0.854. In the graph the node is drawn as the Gain's device in cyan (#392), with one knob for `Pan`: the middle stands straight up, the turn goes evenly to *L* and *R* engraved at its ends. A linked `Pan` greys the knob. |
| **Compressor** | Squeezes the loudness together: what goes above `threshold` (-24 dB by default) comes out only 1/`ratio` (4) as much louder. `knee` (6 dB) eases into it, `attack` (0.003 s) and `release` (0.25 s) say how fast it turns down and lets go. `makeup` (0 dB) raises it afterwards. **Auto-gain** (off) gives back what it takes from a sound at -18 dB, with the makeup on top. The node is drawn as a device with a meter of what it takes away, and a double-click opens a tab with its curve and the level going in and out. See [below](#compressor-and-limiter). | | **Compressor** | Squeezes the loudness together: what goes above `threshold` (-24 dB by default) comes out only 1/`ratio` (4) as much louder. `knee` (6 dB) eases into it, `attack` (0.003 s) and `release` (0.25 s) say how fast it turns down and lets go. `makeup` (0 dB) raises it afterwards. **Auto-gain** (off) gives back what it takes from a sound at -18 dB, with the makeup on top. The node is drawn as a device with a meter of what it takes away, and a double-click opens a tab with its curve and the level going in and out. See [below](#compressor-and-limiter). |
| **Limiter** | Keeps every peak below `threshold` (-6 dB): it looks 5 ms ahead, so even a sudden peak never gets through, and comes back up in `release` (0.1 s). **Auto-gain** (on) raises the limited sound to `ceiling` (-1 dB). Nothing ever goes above the ceiling. See [below](#compressor-and-limiter). | | **Limiter** | Keeps every peak below `threshold` (-6 dB): it looks 5 ms ahead, so even a sudden peak never gets through, and comes back up in `release` (0.1 s). **Auto-gain** (on) raises the limited sound to `ceiling` (-1 dB). Nothing ever goes above the ceiling. The node is drawn as a brick device whose screen holds how much it took away and when (#397). See [below](#compressor-and-limiter). |
| **Saturation** | Bends the sound, from warmth to a hard distortion. **Type**: *Soft (tanh)* (the default), *Cubic*, *Hard clip*, *Tube*, *Fuzz*, *Foldback*, *Sine fold* or *Rectify*. `drive` (12 dB) is how hard the sound is pushed into it, `tone` (1) a low-pass after it from 1 kHz (0) to wide open (1). **Auto-gain** (on) keeps the bent sound about as loud as it came in, `output` (0 dB) is added on top. `wet` (1) how much of it is heard instead of the sound itself. The node is drawn as a copper device whose screen glows hotter the harder it is driven (#396). See [below](#saturation). | | **Saturation** | Bends the sound, from warmth to a hard distortion. **Type**: *Soft (tanh)* (the default), *Cubic*, *Hard clip*, *Tube*, *Fuzz*, *Foldback*, *Sine fold* or *Rectify*. `drive` (12 dB) is how hard the sound is pushed into it, `tone` (1) a low-pass after it from 1 kHz (0) to wide open (1). **Auto-gain** (on) keeps the bent sound about as loud as it came in, `output` (0 dB) is added on top. `wet` (1) how much of it is heard instead of the sound itself. The node is drawn as a copper device whose screen glows hotter the harder it is driven (#396). See [below](#saturation). |
| **Tremolo** | Makes the volume swing `rate` times a second (5 Hz by default), from full down by `depth` percent (50) and back. **Shape**: *Sine* (the default), *Triangle*, *Square* or *Saw*. See [below](#tremolo-and-vibrato). | | **Tremolo** | Makes the volume swing `rate` times a second (5 Hz by default), from full down by `depth` percent (50) and back. **Shape**: *Sine* (the default), *Triangle*, *Square* or *Saw*. See [below](#tremolo-and-vibrato). |
| **Vibrato** | Makes the pitch swing `rate` times a second (5 Hz), `depth` semitones up and as far down (0.5). **Shape** as on the Tremolo; a *Square* jumps between two pitches. See [below](#tremolo-and-vibrato). | | **Vibrato** | Makes the pitch swing `rate` times a second (5 Hz), `depth` semitones up and as far down (0.5). **Shape** as on the Tremolo; a *Square* jumps between two pitches. See [below](#tremolo-and-vibrato). |
@@ -853,6 +853,37 @@ Both (#326) work on the whole sound passing them: on a voice that is one sound,
so the node keeps hearing. so the node keeps hearing.
- The pictures of the tab, curve and levels, are not on the panel. A double-click on the node - The pictures of the tab, curve and levels, are not on the panel. A double-click on the node
opens the tab for them. opens the tab for them.
- **The Limiter's node is a device as well** (#397): a plate of brushed brick, 720x280 graph
units, its inputs on the left and its output on the right. It has no tab.
- **Chrome knobs**: threshold large, ceiling and release small beside it. They turn and reset
as the Compressor's do, each one undo step. A knob whose input is linked is greyed. At wet 0
the knobs and the lever are pale and the screen says `DRY`.
- **Auto-gain** is a lever at the top right. Beside it stands what it gives, `ceiling -
threshold`, for example `+5 dB`, or `off`.
- **The lamp** `LIMIT` beside the name lights red while the Limiter takes something away.
- **The screen** catches what the Limiter takes away **from the moment a sound starts**: the
reduction hangs down from the top, 0 to 24 dB by the square root like the Compressor's meter,
with marks at 1, 3, 6, 12 and 24 dB. Along the bottom runs the level coming in, -60 to 0 dB,
orange above the line of the limit. Time runs across from the start of the sound. The screen
shows 1 s and grows to 2, 4 and 8 s as the sound goes on. A longer sound rolls, and the last
8 s of it are kept. The times stay counted from its start.
- **It is held**: once nothing has come in for 0.4 s, the capture stands still, the silence
after the sound left off, until the next sound starts a new one. Above the screen stands
`WAITING FOR SOUND`, `LIVE` or `HELD`. Under it the most taken away is written with when, for
example `MOST -11.9 dB AT 0 ms`, and the time counts from the first reading that is heard.
On the right stands `NOW -3.9 dB` while live and `LASTED 1.47 s` once held. A white line
and dot mark the most. A capture is also held when the node leaves the picture.
- **How it is read**: from the same taps as the Compressor's, a gain of 1 in front of the node
and behind it. Each frame reads the loudest sample since the last frame, at least 25 ms, at
most 150 ms. The side in front is read 5 ms earlier, as late as the Limiter is, so a peak
going in is met by what it became. What is taken away is the level in less the level out,
without the auto-gain. Below 1, Wet blends the limited sound with what came in, and the
reading is solved for the limited part: `out / in = wet * gain * auto + (1 - wet)`. Less than
0.2 dB counts as none.
- **Measured** (2026-10-10, live, stein2): the seeded blip at -4.4 dBFS through a threshold of
-12 dB showed 7.56 dB taken away. A sound of three hits at 0, -8 and -2 dBFS showed
11.9 dB at the first and lasted 1.47 s on the screen (the file is 1.5 s, the first hit
50 ms in). In e2e 34 (test Chrome) -10.44 dBFS in against a limit of -20 dB showed 9.56 dB.
- **Measured** (2026-10-07, e2e 34, Chrome offline): an impulse came out of the Compressor 288 - **Measured** (2026-10-07, e2e 34, Chrome offline): an impulse came out of the Compressor 288
samples late and out of the Limiter 240. A 1 kHz sine at -18 dB through a hard-knee samples late and out of the Limiter 240. A 1 kHz sine at -18 dB through a hard-knee
Compressor at -24 dB and 4:1 came out at -17.92 dB with auto-gain on and at -22.42 dB with it Compressor at -24 dB and 4:1 came out at -17.92 dB with auto-gain on and at -22.42 dB with it