Describe the Saturation node as a device that glows (#396)

- Sounds: the table row says the node is a copper device, and the
  Saturation section describes the screen, the heat and the plate.
- Architecture: SaturationPanel, SaturationFace and saturationView.
- Development: 1969 editor checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-10-10 20:05:24 +02:00
1 parent 543f0df344
commit beb6022fb9
3 files changed
+27 -3

No files matched your search

+4 -1
@@ -440,7 +440,10 @@ src/editor/soundfx/ SoundFxEditor (#311: the graph, a sound to try it on, Pla
Reverb as a device, its tail as rings on a round screen worked out apart from Reverb as a device, its tail as rings on a round screen worked out apart from
the drawing), DelayPanel + DelayFace + delayView (#393: the Delay as a device, the drawing), DelayPanel + DelayFace + delayView (#393: the Delay as a device,
its echoes as bars on a screen and the light that runs over them at their beat its echoes as bars on a screen and the light that runs over them at their beat
worked out apart from the drawing), nodeParamDrag (a knob's drag as one undo step, for the tab and the worked out apart from the drawing), SaturationPanel + SaturationFace +
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
are the Reverb's `PickButton`), 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 # 1968 editor checks, screenshots in /tmp/gm-e2e-*.png node tools/seed-e2e.mjs && node tools/e2e.mjs # 1969 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
+22 -1
@@ -436,7 +436,7 @@ response of a Reverb, and as what the Sound FX tab tries out. Its row means noth
| **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. 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). | | **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). |
| **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. The node is drawn as a device with a round screen of its tail (#389). See [below](#reverb). | | **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. The node is drawn as a device with a round screen of its tail (#389). See [below](#reverb). |
@@ -884,6 +884,27 @@ aliasing.
far and the two meet without a comb. The node as a whole is late by that much, which a voice, a far and the two meet without a comb. The node as a whole is late by that much, which a voice, a
Mix and a bus make up for as for a [Compressor](#compressor-and-limiter). A `wet` typed in at 0 Mix and a bus make up for as for a [Compressor](#compressor-and-limiter). A `wet` typed in at 0
leaves the node out. leaves the node out.
- **The device** (#396): in the graph the node is a plate of 720x280 graph units in brushed
copper, its inputs on the left and its output on the right.
- **The screen** (*A sine at -12 dBFS*) draws a sine at the level auto-gain is reckoned at as a
grey ghost, and over it the wave that comes out: driven into the curve of the type, its DC taken
out, auto-gain and `output` after it, blended with the sine by `wet`. So it shows the shape and
the level. The edges are -6 dBFS, a louder wave is cut off there. `tone` is left out of the
picture, it would only round the edges.
- Under the screen it says what auto-gain gives (`AUTO-GAIN -10.2 dB`, `AUTO-GAIN OFF`, at `wet` 0
`DRY`) and the loudest point out (`PEAK -12.6 dBFS`).
- **The heat**: `drive` over its 48 dB, as far as `wet` lets it be heard. The colour of the wave
goes from cold steel through ember red, orange and yellow to white, above the screen it says
`COLD`, `WARM`, `HOT`, `GLOWING` or `WHITE HOT`. A glow rises from the bottom of the screen and
flickers, and from about 8 dB of drive on embers fly up, more and faster the hotter it runs
(24 at white heat). The *Heat* lamp beside the name glows with it. The node keeps the editor
drawing for that while there is heat and it is in the picture; cold it draws nothing.
- Everything is drawn from the settings, nothing is listened to while the sound plays.
- **On the plate**: a button for each type (*Soft*, *Cubic*, *Hard*, *Tube*, *Fuzz*, *Foldback*,
*Sine*, *Rectify*), the *Auto-gain* lever, `Drive` as a big chrome knob beside the screen and
`Tone`, `Output` and `Wet` small. A type, the lever and each turn are one undo step. The knobs
work as the Compressor's do, a wired number locks its knob. `Tone` reads as the cutoff
(`20 kHz`), `Output` has 0 straight up. At `wet` 0 everything else is drawn faint.
- **Measured** (2026-10-07, e2e 34, Chrome offline): an impulse came out 192 samples late at 48 - **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 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 came out at 0.00 dB. A sine at -12 dBFS driven 24 dB into *Soft* came out at 0.00 dB with