Describe the Compressor tab's layout and auto-gain as a switch (#378)
- Sounds: knobs at the bottom, levels filling the height, the curve centred at their right, and the least size of its window. - Sounds: auto-gain of the Compressor, Limiter and Saturation is a switch with the makeup or output on top. The Compressor's gives back what it takes at -18 dB. New offline measurement. - Concepts: a window is at least 320 x 200, more where its tab needs. - Development: 1949 editor checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent
5b9343f173
commit
a51884fafb
3 files changed
+42
-25
No files matched your search
+2
-1
@@ -359,7 +359,8 @@ one kind can be open at once — two textures, three behaviors — each with its
|
||||
- **A tab can float** (#371): right-click it and pick *Float*, and the document leaves the row for
|
||||
a window of its own above the editor. Its title bar moves the window, the lower right corner
|
||||
sizes it, *Dock* puts the document back into the row, showing, and the `×` closes it. Only
|
||||
documents float, never Scene or Game.
|
||||
documents float, never Scene or Game. A window is at least 320 × 200 px. A tab that needs more,
|
||||
like a Compressor's with its knobs (#378), holds its window at that size.
|
||||
- Every kind has one editor, so it has **one window**: with a texture in a window, opening
|
||||
another texture shows it there and closes the one it had. Windows of different kinds can be
|
||||
open side by side, a sound FX beside its Parametric EQ for instance.
|
||||
|
||||
+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/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
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1947 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1949 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
|
||||
./e2e.sh start [GM_STEPS] # the same run detached, see below
|
||||
./e2e.sh status # live progress, or the last run's result
|
||||
|
||||
+39
-23
@@ -435,9 +435,9 @@ response of a Reverb, and as what the Sound FX tab tries out. Its row means noth
|
||||
| **Phaser** | Sweeps notches through the sound, the swirl of a phaser pedal. **Stages** (2, 4, 6, 8 or 12, 4 by default) is how many allpass stages it has, every two make one notch. They sit around `frequency` (800 Hz by default), and an LFO moves them `depth` octaves wide (2), `rate` times a second (0.5 Hz). `feedback` (0.4) sharpens the notches, `wet` (1) is how much is heard. 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. |
|
||||
| **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` (0) blends that with the gain that brings a sound at full scale back to full scale. A double-click on the node opens its tab: a knob for each number, 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` (1) raises the limited sound towards `ceiling` (-1 dB). Nothing ever goes above the ceiling. 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). `output` (0 dB) and `auto-gain` (1) set the level of the bent sound, `wet` (1) how much of it is heard instead of the sound itself. See [below](#saturation). |
|
||||
| **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. A double-click on the node opens its tab: a knob for each number, 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). |
|
||||
| **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. 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). |
|
||||
| **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). |
|
||||
| **Reverb** | The sound in a space. **Type**: *Room* (the default), *Hall*, *Cave*, *Plate*, *Custom* or *Sound*. Custom shows the rows `decay` (s, 1.5 by default), `damping` (0.4) and `pre-delay` (s, 0.01); Sound picks a sound asset as the impulse response of a real space, with `pre-delay`. `wet` (0.3) is how much of the reverb is heard instead of the sound itself. See [below](#reverb). |
|
||||
@@ -451,12 +451,15 @@ Bitcrusher `bits` 1 to 16, `rate` 100 to 48000 Hz, Phaser `frequency` 20 to
|
||||
125 ms/s, `rate` 0 to 10 Hz, `depth` 0 to 10 ms, both with `feedback` 0 to 0.95,
|
||||
Pan -1 to 1, Compressor `threshold` -100 to 0 dB, `ratio` 1 to 20, `knee` 0 to 40 dB, `attack` and
|
||||
`release` 0 to 1 s, `makeup` -24 to +24 dB, Limiter `threshold` -60 to 0 dB, `ceiling` -30 to 0 dB,
|
||||
`release` 0.001 to 2 s, both with `auto-gain` 0 to 1, Saturation `drive` 0 to 48 dB, `tone` and
|
||||
`auto-gain` 0 to 1, `output` -24 to +24 dB, Tremolo `rate` 0 to 20 Hz and `depth` 0 to 100 %,
|
||||
`release` 0.001 to 2 s, Saturation `drive` 0 to 48 dB, `tone` 0 to 1, `output` -24 to +24 dB, Tremolo `rate` 0 to 20 Hz and `depth` 0 to 100 %,
|
||||
Vibrato `rate` 0.5 to 20 Hz and `depth` 0 to 4 semitones, Reverb `decay` 0.1 to 10 s, `damping`
|
||||
0 to 1, `pre-delay` 0 to 0.5 s, and every `wet` 0 to 1),
|
||||
whichever way the value arrives.
|
||||
|
||||
**Auto-gain** of the Compressor, the Limiter and the Saturation is a switch on the node, not an
|
||||
input (#378). Until then it was a number from 0 to 1 that blended between the node's own gain and
|
||||
the auto-gain. A project from before reads such a number as on when it is above 0.
|
||||
|
||||
### Bypass and Wet
|
||||
|
||||
Every effect has a **Bypass** and a **`wet`** (#354), all but the Mix, the Input and the Output.
|
||||
@@ -708,16 +711,18 @@ Both (#326) work on the whole sound passing them: on a voice that is one sound,
|
||||
- **Compressor** is Web Audio's `DynamicsCompressorNode`. Its knee is a curve the browser draws;
|
||||
the game takes Chromium's, so the numbers below are worked out the way Chrome compresses.
|
||||
- The node **adds a gain of its own**: 0.6 of what it takes off a sound at full scale (the spec
|
||||
says so). The game takes that back out, so with `makeup` 0 and `auto-gain` 0 a compressed sound
|
||||
really is quieter. After the node the sound gets `(1 - auto-gain) * makeup + auto-gain * A` dB,
|
||||
where `A` is what the curve takes off at 0 dBFS. At `auto-gain` 1 a sound at full scale comes
|
||||
back near full scale.
|
||||
says so). The game takes that back out, so with `makeup` 0 and auto-gain off a compressed sound
|
||||
really is quieter. After the node the sound gets `makeup + A` dB with auto-gain on, `makeup`
|
||||
with it off. `A` is what the curve takes off a sound at **-18 dB**, about where a mixed sound
|
||||
sits on average, so that one comes out as loud as it went in. Below the threshold `A` is 0.
|
||||
Until #378 `A` was taken at 0 dB. With a low threshold that lifted everything far too much
|
||||
(+28.1 dB at -40 dB, 4:1, knee 6, against +14.6 dB now).
|
||||
- **Limiter** runs on the FX worklet. It holds the sound back 5 ms, finds the gain every sample in
|
||||
that window needs to stay below the lower of `threshold` and `ceiling`, and averages it over the
|
||||
window, so the gain is down smoothly by the time a peak is heard. Then it comes back up in
|
||||
`release`. Both sides of a stereo sound are turned down together, by the louder one. `auto-gain`
|
||||
raises what comes out by its share of `ceiling - threshold` dB: at 1 the peaks sit on the
|
||||
ceiling, at 0 on the threshold.
|
||||
`release`. Both sides of a stereo sound are turned down together, by the louder one. Auto-gain
|
||||
on raises what comes out by `ceiling - threshold` dB, so the peaks sit on the ceiling. Off, they
|
||||
sit on the threshold.
|
||||
- **Both are late**: the Compressor by the spec's look-ahead of 6 ms, the Limiter by 5 ms (240
|
||||
samples at 48 kHz, 221 at 44.1 kHz). This is made up exactly, as for a
|
||||
[Pitch on a bus](#a-pitch-on-a-bus): a voice starts as much earlier, the other way of a Mix and
|
||||
@@ -727,28 +732,38 @@ Both (#326) work on the whole sound passing them: on a voice that is one sound,
|
||||
their ratio.
|
||||
- **The Compressor's tab** (#378): a double-click on the node opens it, one tab per node, named
|
||||
and closed like a [Parametric EQ's](#parametric-eq). It has three parts:
|
||||
- **Knobs**, one for each of the seven numbers. Drag up or down to turn one: 200 px is the
|
||||
- **Knobs**, one for each of the six numbers. Drag up or down to turn one: 200 px is the
|
||||
whole turn, with Shift a tenth of that. A notch of the wheel turns it by a fiftieth.
|
||||
A double-click sets the default, and a click on the number below lets you type one. Attack,
|
||||
release and ratio give most of the turn to the low end, where they are used. A knob whose
|
||||
input is linked is greyed: the link decides its value.
|
||||
- **Auto-gain** is a switch at the right of the knobs. Below it stands what it gives, for
|
||||
example `+14.6 dB`, or `off`. A click is one undo step.
|
||||
- **The curve**, level in across and level out up, both -60 to 0 dB, before the makeup and
|
||||
auto-gain. Two points are dragged: the one where it starts to bend sets `threshold`, the one
|
||||
at its end sets the `ratio` that ends there. A dot on the curve is the level coming in now.
|
||||
With auto-gain on, a line at -18 dB in leads from the curve up to the diagonal: that is how
|
||||
far auto-gain lifts the sound.
|
||||
- **The levels** of the last 4 s, newest at the right, +6 to -60 dB: grey what comes in, in
|
||||
the colour of a sound port what goes out. Where the compressor takes more than 0.5 dB away,
|
||||
the stretch below the level coming in is tinted by as much as it takes. The makeup is left
|
||||
out of that, so a raised sound still shows what was squeezed. A level is the loudest sample
|
||||
the stretch below the level coming in is tinted by as much as it takes. The makeup and
|
||||
auto-gain are left out of that, so a raised sound still shows what was squeezed. Every
|
||||
reading keeps the gain of its time, so changing the makeup does not repaint the past. A level is the loudest sample
|
||||
of the last 25 ms. The line across is the threshold.
|
||||
|
||||
Each drag, notch or typed number is one undo step. The levels come from the same taps as the
|
||||
EQ's spectrum: a gain of 1 in front of the node and behind it, fed into an analyser only while
|
||||
the tab is seen. An EQ's tab and a Compressor's can be listened to at once.
|
||||
|
||||
The knobs stay on the bottom line, centred. The levels fill the height above them. The curve
|
||||
is a square at their right, centred up and down. It grows with the tab from 180 to 360 px, but
|
||||
takes no more than 40 % of its width. A floated Compressor's window cannot be made smaller than
|
||||
what shows every knob and the smallest pictures (560 × 414 px in the test browser).
|
||||
- **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 full scale through a hard-knee
|
||||
Compressor at -12 dB and 4:1 came out at +0.19 dB with full auto-gain and at -8.81 dB with none
|
||||
(the curve says -9). A sine at 2 through a Limiter at -6 dB peaked at exactly -6.00 dB, with
|
||||
auto-gain 1 at -1.00 dB. Chrome's own gain far below the threshold was measured at four
|
||||
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
|
||||
off (the curve says -22.5; measured 2026-10-09, #378). A sine at 2 through a Limiter at -6 dB
|
||||
peaked at exactly -6.00 dB, with auto-gain on at -1.00 dB. Chrome's own gain far below the threshold was measured at four
|
||||
settings: 1.524 at -24 dB, knee 30, 12:1; 1.862 at -12 dB, knee 0, 4:1; 1.675 at -20 dB,
|
||||
knee 10, 2:1; 1.000 at 0 dB. The curve gives all four to three places
|
||||
(`tests/core/dynamics.test.ts`).
|
||||
@@ -766,8 +781,9 @@ aliasing.
|
||||
types make.
|
||||
- **`drive` is a gain in front of the curve**, not a curve of its own: the curve spans 256 times
|
||||
full scale and the sound is turned down as far before it. So a drive glides like any gain.
|
||||
- **`output` and `auto-gain`**: the bent sound gets `(1 - auto-gain) * output + auto-gain * A` dB.
|
||||
`A` is the gain that brings a sine at -12 dBFS, driven and bent, back to the RMS it came in with.
|
||||
- **`output` and auto-gain**: the bent sound gets `output + A` dB with auto-gain on, `output`
|
||||
with it off. `A` is the gain that brings a sine at -12 dBFS, driven and bent, back to the RMS it
|
||||
came in with.
|
||||
- **`tone`** is a low-pass after the curve, from 1 kHz at 0 to 20 kHz at 1, evenly in octaves.
|
||||
- **`wet`** blends the bent sound with the sound itself. The oversampling makes the bent sound
|
||||
**192 samples late** (Chrome, at 48 and at 44.1 kHz alike), so the sound itself is held back as
|
||||
@@ -776,8 +792,8 @@ aliasing.
|
||||
leaves the node out.
|
||||
- **Measured** (2026-10-07, e2e 34, Chrome offline): an impulse came out 192 samples late at 48
|
||||
and at 44.1 kHz. Half bent and half dry at 1125 Hz, where 192 samples off would cancel, the sine
|
||||
came out at 0.00 dB. A sine at -12 dBFS driven 24 dB into *Soft* came out at 0.00 dB with full
|
||||
auto-gain.
|
||||
came out at 0.00 dB. A sine at -12 dBFS driven 24 dB into *Soft* came out at 0.00 dB with
|
||||
auto-gain on.
|
||||
|
||||
### Tremolo and Vibrato
|
||||
|
||||
|
||||
Reference in new issue
Block a user