Describe the Envelope and the Filter #335
- Instruments: a new section Envelopes (shape, end of a note, the value output and what it fits, a filter sweep, Stop sound, the measured curve), the Envelope in the node table, the end of a note under an Envelope, Play note with Let ring, Not yet. - Sounds: the Filter node and its ranges, Let ring on a note with an Envelope. - Home: the Envelope in the line of Instruments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent
f2a3834212
commit
ea30223538
3 files changed
+61
-9
No files matched your search
+1
-1
@@ -22,7 +22,7 @@ Live: <https://nockal.com/game-maker/> · Widget playground: <https://nockal.com
|
||||
| [Pixel art](Pixel-Art) | The pixel art asset and its palette, the tools, layers and frames, onion skin and the preview, resizing, how frames are worn and where the pixels are stored |
|
||||
| [Fonts](Fonts) | Uploading a typeface, what a text wears, what the editor falls back to |
|
||||
| [Sounds](Sounds) | Uploading a sound, what the asset says, `Play sound` and `Stop sound`, sound FX (gain, pitch, EQ, mix, delay) and how long a voice rings on, what a pause and a stop do to a voice |
|
||||
| [Instruments](Instruments) | The instrument asset: Notes, Sample, Parameters, Sound FX and Output, triggers, zones and layers, the keys of the Instrument tab, `Play note` |
|
||||
| [Instruments](Instruments) | The instrument asset: Notes, Sample, Parameters, Sound FX, Envelope and Output, triggers, zones and layers, the keys of the Instrument tab, `Play note` |
|
||||
| [Animations](Animations) | Animation assets, the Animation tab, how they run |
|
||||
| [Curves](Curves) | Easings drawn by hand, the Curve tab, using one on a key or a `Lerp` |
|
||||
| [Tiles](Tiles) | The tile asset, plain tiles and the two autotile kinds, the pictures as animation steps, the Tile tab |
|
||||
|
||||
+55
-5
@@ -22,8 +22,9 @@ 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. |
|
||||
| **Envelope** | Shapes a note as it is played: **Attack**, **Decay** and **Release** in seconds, **Sustain** from 0 to 1. On the way of the sound it is its volume; its output `value` moves a number with the same curve, from **From** to **To**. See [Envelopes](#envelopes). |
|
||||
| **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. |
|
||||
| Gain, Pitch, 5-Band-EQ, Filter, Mix, Delay | The effects of a [sound FX](Sounds#sound-fx), the same nodes. |
|
||||
|
||||
**Play** of a Sample:
|
||||
|
||||
@@ -80,7 +81,8 @@ voice 0.
|
||||
Sample fades out in 10 ms, *One-shot* ones play on, and *Loop, then release* ones leave their
|
||||
loop. A buffer source stops looping and plays on by itself. The pitch worklet is told to leave:
|
||||
it lets the round finish that its newest frame has read into, so nothing already read changes
|
||||
under the frames still sounding, and plays on from there.
|
||||
under the frames still sounding, and plays on from there. A Sample under an
|
||||
[Envelope](#envelopes) does not fade: it plays on through the release.
|
||||
- **Pitch.** A Sample that follows the note is shifted by the phase vocoder of #317, so a note far
|
||||
from the root sounds rough, as there. A note at its root is the sound itself, played without the
|
||||
worklet.
|
||||
@@ -92,6 +94,53 @@ A node that keeps the instrument from compiling says so, and the tab's header sa
|
||||
source nothing triggers, an effect nothing comes into. A Sound FX node naming no FX, or one that is
|
||||
gone, warns and lets the sound through as it is.
|
||||
|
||||
## Envelopes
|
||||
|
||||
An **Envelope** (#335) shapes a note over its time: from silence up to full in **Attack**, down to
|
||||
the level **Sustain** in **Decay**, held there as long as the note is, and back to silence in
|
||||
**Release** once the note ends. A new one is 0.005 / 0.1 / 1 / 0.1: a soft start, otherwise the
|
||||
sound as it is.
|
||||
|
||||
- **The shape is fixed.** The attack is a straight line; the decay and the release ease out, as a
|
||||
struck string does, and are 60 dB of the way there when their time is up. A release takes 10 ms
|
||||
at least, so a note never clicks. There is no *Punch*: a short decay to a sustain under 1 is the
|
||||
same, and a Gain sets how loud it is overall.
|
||||
- **A note ending early** (shorter than attack and decay) releases from the level it has reached
|
||||
by then, not from the sustain: mid-attack from halfway up, for one.
|
||||
- **On the way of the sound** (Sample → Envelope → Output) it is the volume of everything before
|
||||
it, behind a Mix too. Two in a row multiply. The end of the note goes to it instead of the
|
||||
10 ms fade: a *Gate* or *Loop* Sample plays on through the release (a loop loops on), a *Loop,
|
||||
then release* one leaves its loop as well, and the note ends when the release has. A
|
||||
*One-shot* under an Envelope of its own plays through as it would, the Envelope held at its
|
||||
sustain. Echoes after it ring on as ever.
|
||||
- **`value`** moves a number with the same curve: at **From** while the note rests, at **To** at
|
||||
the top of the attack, and where the sustain puts it between them while held. Its pin is of a kind of its
|
||||
own, an **envelope**, drawn in coral. It fits only a number the sound itself holds while it
|
||||
plays: `cutoff` and `resonance` of a Filter, `semitones` of a Pitch, `gain` of a Gain, a band of
|
||||
the 5-Band-EQ and `mix` of a Mix. Not the time of a Delay, not the times of an Envelope, not a
|
||||
parameter of a Sound FX node. A cutoff and a Gain move in equal ratios (octaves, decibels),
|
||||
everything else evenly. Both ends are held to the range of the number it moves.
|
||||
- **A filter sweep:** Sample → Filter → Envelope → Output, and a second Envelope with its `in` left
|
||||
open, its `value` into the Filter's `cutoff`, From 200, To 5000. Each Envelope is a curve of its
|
||||
own; one Envelope can feed several numbers.
|
||||
- **A number an Envelope moves is the Envelope's.** It is no longer reached by a parameter or by
|
||||
`Set sound FX parameters`. A Pitch it moves comes on top of the shift the note already has.
|
||||
- **The numbers of an Envelope count from the moment the note starts.** They can come from
|
||||
`velocity` or a parameter (a harder stroke, a longer decay), but changing them later does not
|
||||
bend a note already playing.
|
||||
- **Stop sound** with *Let ring* lets a note with an Envelope fall away in its release; without it
|
||||
the note is cut in 10 ms, as is every note the **Stop** of the tab ends.
|
||||
- **The same note again** while one is still in its release is a voice of its own; the first
|
||||
plays its release out.
|
||||
- The curve runs on the audio thread, one `ConstantSourceNode` per Envelope and note; a number it
|
||||
moves gets it through a `WaveShaper`. Firefox has no `cancelAndHoldAtTime`: there the level a
|
||||
release starts from is worked out from the shape.
|
||||
- **Measured** (2026-10-06, e2e 34, Chrome offline): attack 0.1, decay 0.2, sustain 0.5, release
|
||||
0.3 rendered 0.5 at 0.05 s, 1 at 0.1 s and 0.5005 at 0.3 s; released at 0.5 s it was 0.0158
|
||||
at 0.65 s and 0.0005 at 0.8 s, released mid-attack at 0.05 s it fell from 0.5 to 0.05 at 0.15 s.
|
||||
A Gain moved from 0.25 to 1 by that curve was 0.5 halfway up. Live, a looped note of 0.2 s
|
||||
through an Envelope with a release of 1 s was gone 1.32 s after it started, read every 150 ms.
|
||||
|
||||
## The Instrument tab
|
||||
|
||||
The graph, and below it **the keys**: all 128 notes, the ones that sound in white and black, the
|
||||
@@ -133,7 +182,8 @@ heard at once on what is playing. Those values are the tab's own and never writt
|
||||
Its output `voice` is the number of the note, like `Play sound`'s: `Set sound FX parameters` moves
|
||||
its parameters while it plays (the bundle of an Instrument parameters node goes into its
|
||||
`fx params`), `Stop sound` with `voice` ends it — with *Let ring* only the sound, so its echoes
|
||||
ring on. A note belongs to the object that played it and stops when that object is destroyed.
|
||||
ring on, and an Envelope plays its release first. A note belongs to the object that played it and
|
||||
stops when that object is destroyed.
|
||||
|
||||
**Instrument parameters** works like `Sound FX parameters`: it names an instrument and picks the
|
||||
parameters to set, each a number input starting at the default its Parameters node gives it.
|
||||
@@ -176,6 +226,6 @@ be made of it; nothing in the editor plays a sequence yet, only the check script
|
||||
|
||||
## Not yet
|
||||
|
||||
No envelope with a release after the note (#335), no oscillators or 8-bit sources (#329), no
|
||||
patterns or songs (#333, #334), no swing. Notes can not be played from an `.mid` file or a MIDI
|
||||
No oscillators or 8-bit sources (#329), no patterns or songs (#333, #334), no swing. An Envelope
|
||||
shapes notes of an instrument only, not a sound played through a sound FX. Notes can not be played from an `.mid` file or a MIDI
|
||||
keyboard.
|
||||
+5
-3
@@ -37,7 +37,7 @@ so what the inspector plays is what the graph will play.
|
||||
| Node | What it does |
|
||||
| --- | --- |
|
||||
| **Play sound** | Starts the sound named by its `sound` input. `volume` **multiplies** the asset's own volume (1 leaves it alone), `loop` is a choice of three (*From the asset*, *On*, *Off*), `detached` says the voice belongs to nobody, `fx` names a [sound FX](#sound-fx) to play it through, and `fx params` takes values for that FX's [parameters](#parameters). Its output `voice` is the number of this one play, for changing it [while it plays](#changing-a-playing-sound), `length` how many seconds one run of the sound lasts, and `tail` that length with the [echoes](#delay-and-the-tail-of-a-voice) of its FX after it, at the values it starts with: how long until the voice is quiet. All three are 0 where nothing was played. `tempo` (BPM, 120 where nothing is connected) is what a [Delay synced to beats](#delay-and-the-tail-of-a-voice) in its FX counts by. |
|
||||
| **Stop sound** | Silences every voice of the sound it names, however many plays started it — a loop included. Naming no sound silences everything the run is playing. With `voice` connected it silences only that one play (the number `Play sound` gave out), and nothing where that is 0. A voice is faded out in 10 ms rather than cut, so it does not click, its echoes with it; **Let ring** stops only the sound and lets the [echoes](#delay-and-the-tail-of-a-voice) fade as they would. |
|
||||
| **Stop sound** | Silences every voice of the sound it names, however many plays started it — a loop included. Naming no sound silences everything the run is playing. With `voice` connected it silences only that one play (the number `Play sound` gave out), and nothing where that is 0. A voice is faded out in 10 ms rather than cut, so it does not click, its echoes with it; **Let ring** stops only the sound and lets the [echoes](#delay-and-the-tail-of-a-voice) fade as they would, and a note of an instrument with an [Envelope](Instruments#envelopes) falls away in its release first. |
|
||||
| **Set sound FX parameters** | Hands new values to the [parameters](#changing-a-playing-sound) of one voice that is already playing, by the `voice` number its `Play sound` gave out, at once or over `time` seconds. |
|
||||
| **Sound** | A constant sound, for either of the two to work on through an edge. |
|
||||
|
||||
@@ -104,13 +104,15 @@ 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. |
|
||||
| **Filter** | Takes away what is above `cutoff` (Hz, 1000 by default): **Type** *Low-pass*. Or what is below it (*High-pass*), or both, leaving a band around it (*Band-pass*). `resonance` from 0 to 1 raises what is right at the cutoff: a low- or high-pass has no bump at 0 (Q -3 dB) and rises by 20 dB at 1, a band-pass gets narrower (Q 0.7 to 20). In an [instrument](Instruments#envelopes) an Envelope can move both while a note plays. |
|
||||
| **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
|
||||
parameter of the Input. Each is held to its range (Gain -120 to +24 dB, Pitch -64 to +64, the EQ
|
||||
bands -60 to +24 dB, Mix 0 to 1, Delay `time` 0.01 to 8 and never more than 2 s, `feedback` 0 to
|
||||
0.95, `damping` and `mix` 0 to 1), whichever way the value arrives.
|
||||
bands -60 to +24 dB, Filter `cutoff` 20 to 20000 Hz and `resonance` 0 to 1, Mix 0 to 1, Delay
|
||||
`time` 0.01 to 8 and never more than 2 s, `feedback` 0 to 0.95, `damping` and `mix` 0 to 1),
|
||||
whichever way the value arrives.
|
||||
|
||||
**How Pitch keeps the length** (#317). A way with a Pitch is played by an `AudioWorklet` on the
|
||||
audio thread, a **phase vocoder**: the sound is cut into frames of about 43 ms (2048 samples at
|
||||
|
||||
Reference in new issue
Block a user