Describe one sound at the Output and the curve of a Mix #331

- Instruments: the Output takes one sound, a drum kit goes through
  Mixes, an old instrument with several edges says why it does not
  compile, and two layers at once depend on the Mix's curve.
- Sounds: the Mix's setting Curve with a table of both curves, the
  +6 dB at the middle, and how a glide follows the curve.
- Architecture: one line on the Output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-10-06 13:13:08 +02:00
1 parent fd1bb5b9a5
commit f2a3834212
3 files changed
+39 -6

No files matched your search

+1 -1
@@ -204,7 +204,7 @@ src/viewport/ WorldViewport (the drawing of a world or a holder, the ba
CPU and laid side by side onto one canvas, so a frame is cut out like a texture frame),
SoundLibrary + pitchWorklet (the AudioWorklet that plays a way with a Pitch through
core/soundfx/pitchPlayer, a phase vocoder, #317; a note of an instrument is one voice
of several layers, each way with its own file, #331; a voice can start and be released
of what reaches its Output, each way with its own file, #331; a voice can start and be released
at a second of the audio clock, #332), music (the scheduler on the library's clock, its
notes played by the project's instruments, driven by `__gm.music` until #333) + musicTimer
(the Web Worker whose interval is the scheduler's beat, #332), ShaderLibrary, ParticleLibrary,
+13 -4
@@ -22,7 +22,7 @@ A at 440 Hz, 127 the highest. A note is named with its octave after it and no da
| **Sample** | Plays a sound asset when its `trigger` is on. With **Follow note** (on by default) it plays higher or lower by the distance from **Root**, the note it sounds as it is (C4 by default), and **keeps its length** — it is played by the same worklet as a Pitch (#317). Off, every note plays it as it is, as for a drum. **Play** says how it is played while the note is held and once it is let go (table below). **Loop start** and **Loop end** are in seconds, 0 at the end being the end of the sound. The volume of the sound asset counts. |
| **Parameters** | The instrument's own parameters, each a number output with a default — like the parameters of a sound FX's Input. One per instrument. |
| **Sound FX** | Sends the sound through a sound FX asset, as if it were the sound at the FX's Input. Every parameter of that FX is an input here; one left open is the FX's default. The node is titled after the FX, and a double click opens it. |
| **Output** | What is heard. Unlike every other sound input it takes **any number** of sounds and plays them together: the layers of the instrument. One per instrument. |
| **Output** | What is heard. It takes **one** sound, like every other sound input; a second edge replaces the first. To play several together, put a **Mix** in front of it (several Mixes in a row for more than two). One per instrument. |
| Gain, Pitch, 5-Band-EQ, Mix, Delay | The effects of a [sound FX](Sounds#sound-fx), the same nodes. |
**Play** of a Sample:
@@ -48,8 +48,16 @@ the source plays when one of them is on: C1 and D1 can both play the same Sample
**Zones and layers.** Several Notes nodes split the keyboard into zones: a bass sample for C1-B2,
another one from C3. Where two ranges overlap, both are heard. A drum kit is one Notes node over
C1-B1 with Single notes on, a Sample on each output (C1 Kick, D1 Snare, F#1 Hi-Hat …) and all of
them into the Output: one instrument plays the whole kit.
C1-B1 with Single notes on, a Sample on each output (C1 Kick, D1 Snare, F#1 Hi-Hat …) and Mixes
gathering them into the Output: one instrument plays the whole kit. Only one drum sounds for a
note, so each Mix is its other side and the drum keeps its own volume. Two layers that sound at
once (a piano with a string pad under it) are mixed by the Mix's `mix`: with the curve
*Crossfade* 0.5 is both at half, with *Both at center* both in full (see
[the curve of a Mix](Sounds#the-curve-of-a-mix)).
An instrument saved while the Output still took any number of sounds and played them together
keeps its edges, but does not compile until there is one: the Output says *Takes one sound: put a
Mix in front of it to play several*.
## How a note is made
@@ -65,7 +73,8 @@ voice 0.
them on a playing note.
- **Velocity is always loudness**: the voice is played at `volume * velocity`. The output
`velocity` is there for anything else as well, a filter that opens with a harder stroke.
- A note is **one voice**, its layers side by side, each way reading its own file. It ends when all
- A note is **one voice**, whatever the graph mixes into it, each way reading its own file, so
`Play note` gives out one `voice` and `Stop sound` ends all of it. It ends when all
its ways have ended, or rings on first where it has an echo (see [Sounds](Sounds#delay-and-the-tail-of-a-voice)).
- **The end of a note** (the key let go, the duration of `Play note` over): every *Gate* and *Loop*
Sample fades out in 10 ms, *One-shot* ones play on, and *Loop, then release* ones leave their
+25 -1
@@ -104,7 +104,7 @@ Input and the Output once each; their pins carry sound and fit nothing but each
| **Gain** | Louder or quieter, in dB (`Gain (dB)`): 0 leaves it alone, -6 is about half as loud, +6 twice. Above 0 the sound can clip. |
| **Pitch** | Higher or lower, in semitones (12 is an octave, 0.5 a quarter tone). The sound **keeps its length**, also when the pitch changes while it plays. The pitch is made where the sound is read, so an effect before the Pitch acts as if it came after it. |
| **5-Band-EQ** | Five bands in dB: 80 Hz and 12 kHz as shelves, 250 Hz, 1 kHz and 4 kHz as peaks. A band at 0 does nothing. |
| **Mix** | Blends the sounds at `a` and `b`: at 0 only `a` is heard, at 1 only `b`, at 0.5 half of each (0.5 is the default). |
| **Mix** | Blends the sounds at `a` and `b`: at 0 only `a` is heard, at 1 only `b` (0.5 is the default). **Curve** says what lies between: *Crossfade* (the default) gives half of each at 0.5, *Both at center* keeps each full up to the middle. See [below](#the-curve-of-a-mix). |
| **Delay** | An echo: the sound comes back after `time`, again and again, each time `feedback` times as loud. **Sync** says what `time` counts: *Seconds*, or *Beats* in quarter notes at the tempo of the voice. `damping` makes every echo duller than the last, `mix` is how loud the echoes are next to the sound, which stays as it is. **Ping-pong** sends the echoes left and right in turn. See [below](#delay-and-the-tail-of-a-voice). |
Every number of these nodes is an **input**: typed in while nothing is connected, or fed from a
@@ -153,6 +153,30 @@ goes to both of its sounds. A Mix typed in at exactly 0 or 1 leaves the silent w
one is not even played. A Mix fed by a parameter keeps both ways, because the value may still
change while the voice plays.
### The curve of a Mix
| `mix` | *Crossfade* `a` / `b` | *Both at center* `a` / `b` |
| --- | --- | --- |
| 0 | 1 / 0 | 1 / 0 |
| 0.25 | 0.75 / 0.25 | 1 / 0.5 |
| 0.5 | 0.5 / 0.5 | 1 / 1 |
| 0.75 | 0.25 / 0.75 | 0.5 / 1 |
| 1 | 0 / 1 | 0 / 1 |
Between the rows it runs in a straight line. *Both at center* is what a DJ mixer calls a sharp
crossfader curve: one side only starts to fade once the other is full.
- **At 0.5 both sounds are added in full**, as two sounds on top of each other. Where both are
loud at the same moment that is up to twice as loud (+6 dB) and can clip; a Gain after the Mix
takes it down. For a drum kit, where only one side sounds per note, it changes nothing.
- **Curve is a setting, not an input**: it holds for the whole voice. `mix` itself can still be
fed by a parameter and moved with *Set sound FX parameters*.
- **A glide follows the curve.** With *Both at center* the voice carries `mix` itself on the
audio thread (a `ConstantSourceNode`), and two `WaveShaperNode`s make the shares of `a` and `b`
from it. A glide from 0 to 1 keeps `a` full for its first half, rather than ramping both shares
straight and dipping to half each at the middle.
- Mixes saved before the curve existed are *Crossfade* and sound as they did.
### Delay and the tail of a voice
A **Delay** (#327) is a delay line whose output goes through a low-pass (the damping), back into