Describe sound FX on tracks, items and whole songs (#346)
- Songs: a new section on the FX box in the track head, the item's Sound FX, Play pattern and Play song with fx, and the latency the bus pitch shifter brings and how it is made up. - Sounds: a new section A Pitch on a bus. - Instruments, Patterns, Behaviors: the new inputs fx and fx params. - Development: 1857 checks.
1 parent
5100f6989e
commit
39224a1f83
6 files changed
+59
-15
No files matched your search
+4
-4
@@ -259,11 +259,11 @@ the inspector).
|
||||
`volume` multiplies that and its `loop` either leaves it alone or overrules it in either
|
||||
direction; every play is a voice of its own, so two in a row overlap, and the voice ends with the
|
||||
behavior that started it unless `detached` says otherwise), `Play note` (one note of an
|
||||
instrument, its parameters from an `Instrument parameters` node, see [Instruments](Instruments)),
|
||||
instrument, its parameters from an `Instrument parameters` node, `fx` a sound FX of its own, see [Instruments](Instruments)),
|
||||
`Play pattern` / `Stop pattern` (a whole pattern through its instrument, looped or once, owned
|
||||
like a sound, see [Patterns](Patterns#playing-one-in-a-game)), `Play song` / `Stop song` (a song
|
||||
at its tempo, an intro once and then round its loop, faded in and out, see
|
||||
[Songs](Songs#playing-one-in-a-game)),
|
||||
like a sound, `fx` one sound FX for all of it, see [Patterns](Patterns#playing-one-in-a-game)), `Play song` / `Stop song` (a song
|
||||
at its tempo, an intro once and then round its loop, faded in and out, `fx` one sound FX for the
|
||||
whole of it, see [Songs](Songs#playing-one-in-a-game)),
|
||||
`Load scene` (swaps the running scene once the frame is over — see [Scenes](Scenes)), `Log`, `Stop game`, `Restart game`,
|
||||
`Pause game`, `Resume game`, `Set time scale` with the data nodes `Is game paused` and `Time scale` (see [Concepts](Concepts), *The game pauses itself*),
|
||||
`Apply force`, `Apply impulse`, `Set velocity`, `Set angular velocity`, `Set gravity` (see [Physics](Physics)),
|
||||
|
||||
+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 # 1853 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1857 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
|
||||
|
||||
+3
-1
@@ -293,10 +293,12 @@ low-pass.
|
||||
| `detached` | As at `Play sound`: the note outlives the object that played it. |
|
||||
| `params` | Values for the instrument's parameters, from an **Instrument parameters** node. |
|
||||
| `tempo` | BPM, what a [Delay synced to beats](Sounds#delay-and-the-tail-of-a-voice) in the instrument counts by. Default 120. |
|
||||
| `fx` | A [sound FX](Sounds#sound-fx) the note goes through on top of what the instrument does (#346), as through a *Sound FX* node at its Output. Its Pitch moves the note's sound itself, with no latency. |
|
||||
| `fx params` | Values for that FX's parameters, from a **Sound FX parameters** node. They stay apart from `params`: an FX parameter and an instrument parameter of the same name are two numbers. |
|
||||
|
||||
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
|
||||
`fx params`; with an `fx` a name both have changes both), `Stop sound` with `voice` ends it — with *Let ring* only the sound, so its echoes
|
||||
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.
|
||||
|
||||
|
||||
+2
@@ -122,6 +122,8 @@ the ruler is only for editing.
|
||||
| `volume` | 0 to 1, how loud every note of it is next to its velocity. |
|
||||
| `loop` | On (the default): round and round until it is stopped. Off: once, and it is over by itself when its last note has ended. |
|
||||
| `detached` | As for a sound: off, the pattern belongs to the object of the behavior and stops when that object is destroyed; on, it outlives it. |
|
||||
| `fx` | A [sound FX](Sounds#sound-fx) **all of it** goes through as one chain (#346): an LFO runs on across the notes, an echo repeats the whole. A Pitch there is a [shifter of its own](Sounds#a-pitch-on-a-bus), and the notes start as much earlier as it is late. |
|
||||
| `fx params` | Values for that FX's parameters, from a **Sound FX parameters** node. `Set sound FX parameters` with the `playback` moves them while it plays. |
|
||||
|
||||
It gives out `playback`, the number of this playing, and 0 where the pattern has no instrument or
|
||||
no notes. Firing it twice plays the pattern twice, overlapping. Its files are loaded first, so the
|
||||
|
||||
+30
-8
@@ -25,8 +25,8 @@ automation (#337).
|
||||
A track has a name, a **volume** from -60 to +12 dB, a **pan** from -1 (left) to 1 (right), **mute**
|
||||
and **solo**. While any track is soloed, only the soloed ones are heard. Each track is heard on a bus
|
||||
of its own: a change of volume, pan, mute or solo reaches what is sounding on it at once, not only
|
||||
the next note. A song keeps at least one track. There are no effects on a track yet, that needs the
|
||||
master bus of #325.
|
||||
the next note. A song keeps at least one track. A track can have a **Sound FX** that everything on
|
||||
it goes through, before its volume and pan (see [below](#sound-fx-on-tracks-items-and-whole-songs)).
|
||||
|
||||
### Items
|
||||
|
||||
@@ -35,7 +35,7 @@ takes both kinds, mixed.
|
||||
|
||||
| Kind | |
|
||||
|---|---|
|
||||
| **Pattern** | Plays the pattern's notes. Longer than the pattern, it repeats it; it plays the whole pattern, the loop set on its ruler is for editing. **Transpose** moves every note by semitones (-48 to 48). **Instrument** plays it with another instrument; empty, the pattern's own. |
|
||||
| **Pattern** | Plays the pattern's notes. Longer than the pattern, it repeats it; it plays the whole pattern, the loop set on its ruler is for editing. **Transpose** moves every note by semitones (-48 to 48). **Instrument** plays it with another instrument; empty, the pattern's own. A **Sound FX** sends all its notes together through one effect, before the one of the track. |
|
||||
| **Sound** | Plays the sound as a clip, at its own speed whatever the tempo. Longer than the sound, it repeats it. A **Sound FX** sends it through an effect. |
|
||||
|
||||
Every item has a **volume** on top of its track's: a sound item from -60 to +12 dB, a pattern item
|
||||
@@ -49,8 +49,8 @@ the right: it starts that far before the end of a round.
|
||||
|
||||
## The Song tab
|
||||
|
||||
Down the left are the **heads** of the tracks: the name, **M** (mute, orange when on) and **S**
|
||||
(solo, yellow when on), below them the volume (the line marks 0 dB) and the pan (the line marks the
|
||||
Down the left are the **heads** of the tracks: the name, **FX** (the track's sound FX, blue when it
|
||||
has one), **M** (mute, orange when on) and **S** (solo, yellow when on), below them the volume (the line marks 0 dB) and the pan (the line marks the
|
||||
middle). A track is added from the right-click menu of a head, above or below it. Along the top is the **ruler**, as in the
|
||||
Pattern tab. Between them are the **lanes** with the items: a pattern blue with its notes drawn
|
||||
small, every round it plays; a sound green with its waveform, from where it starts in it, every
|
||||
@@ -65,7 +65,7 @@ level, the **Grid**, **Fit** and on the right the number of tracks and items. **
|
||||
whole song across.
|
||||
|
||||
What is picked goes to the inspector: an item shows its pattern or sound, its volume and the rows of
|
||||
its kind, a track its name, volume, pan, mute and solo. A click on nothing in the lanes picks the
|
||||
its kind, a track its name, volume, pan, mute, solo and sound FX. A click on nothing in the lanes picks the
|
||||
song itself, with its tempo, meter and grid. Items and tracks are deleted with `Delete` or from their
|
||||
right-click menu, not from the inspector.
|
||||
|
||||
@@ -85,6 +85,7 @@ right-click menu, not from the inspector.
|
||||
| Right-click an item | Opens its menu: *Delete* deletes it, or every picked item where it is one of them. |
|
||||
| Double-click a pattern item | Opens the pattern in the Pattern tab. |
|
||||
| Click **M** or **S** in a head | Mutes or solos the track. |
|
||||
| Click **FX** in a head | A menu of the project's sound FX: one of them for the track, or *No sound FX*. |
|
||||
| Drag along a head's volume or pan | Sets it; while the song plays it is heard as it moves. |
|
||||
| Double-click a head's volume or pan | Sets it back to 0: the volume to 0 dB, the pan to the middle. |
|
||||
| Right-click a head | *Add track above*, *Add track below*, *Move up*, *Move down*, *Delete track*. |
|
||||
@@ -169,6 +170,8 @@ on the same scheduler as the tab.
|
||||
| `fade in` | Seconds it rises from silence to `volume`, from its first note on. 0 starts it at once. |
|
||||
| `loop` | On (the default): it plays from its start, and once it gets to the end of the loop on its ruler it goes round that loop until it is stopped. So an intro before the loop is heard once. With no loop set the whole song is the loop. Off: once to its end, and it is over by itself. |
|
||||
| `detached` | As for a sound: off (the default), the song belongs to the object of the behavior and stops when that object is destroyed, which a `Load scene` does unless the object is kept; on, it outlives it. |
|
||||
| `fx` | A sound FX the whole song goes through, after its tracks and before `volume` and the fades (#346). |
|
||||
| `fx params` | Values for that FX's parameters, from a **Sound FX parameters** node. `Set sound FX parameters` with the `playback` moves them while it plays. |
|
||||
|
||||
It gives out `playback`, the number of this playing, and 0 where the song has nothing on its
|
||||
tracks. Firing it twice plays the song twice, side by side: to swap one song for another, stop the
|
||||
@@ -191,9 +194,28 @@ there, played by `Play song` at 120 BPM: the clip once, the pattern's notes 2 s
|
||||
left sat inside it at 0.501 and -0.5. The toolbar's pause held the clock, and `Stop song` with a
|
||||
fade of 1 s ended it, its buses with it.
|
||||
|
||||
## Sound FX on tracks, items and whole songs
|
||||
|
||||
A [sound FX](Sounds#sound-fx) can sit on a track, on a pattern item, and on a whole `Play pattern` or
|
||||
`Play song` (#346). There it is one chain, as an insert in a DAW: everything played there goes
|
||||
through it **together**. A Phaser's LFO runs on across the notes, a Delay echoes the sum, a
|
||||
Bitcrusher crushes the chord, and it costs one chain however many notes sound.
|
||||
|
||||
- **The order:** the notes of a pattern item → its FX → the track's FX → the track's volume and
|
||||
pan → the FX of the `Play song` → its volume and fades. A sound item keeps its own *Sound FX* per
|
||||
clip as before, then goes on through its track's.
|
||||
- A sound FX that is gone or does not compile passes everything on as it is.
|
||||
- Track and item FX play at the defaults of their parameters. Those of a `Play pattern` / `Play
|
||||
song` take `fx params`, and `Set sound FX parameters` moves them by the `playback`.
|
||||
- **A Pitch** there is a shifter of the sound going by, one frame late, and every note is started
|
||||
that much earlier, so nothing is heard out of step (see [A Pitch on a bus](Sounds#a-pitch-on-a-bus)).
|
||||
On a `Play note`, whose FX is its own, the Pitch moves the note's sound itself, with no latency.
|
||||
- When a playing ends, its chains go once its echoes have rung out; in the tab, a moment after Stop.
|
||||
|
||||
Measured (2026-10-07, e2e 65): a sound FX with a Pitch of +12 on the second track, played in the tab at 120 BPM in headless Chrome at 44.1 kHz on the CI's Windows machine: its bus said it was 0.046440 s late (2048 samples), the first note on it was planned for 19.017982 s and started at 18.971542 s, exactly that much earlier, the clip of the first track 2 s before it right on time. Offline, the shifter moved a 1 kHz tone to 2000 Hz, and at 0 semitones handed a click out 2048 samples later at a height of 1.0000001. Stop let the buses of the tab go.
|
||||
|
||||
## Not yet
|
||||
|
||||
Nothing tells a graph that a song played once has ended, and there is no node that changes the
|
||||
volume of a playing song. No start at a marker (#338), no automation (#337), no effects on a track
|
||||
(#325), no song inside a song, no held note (drone) as an item. A pattern item cannot be made into a pattern of its own (*make unique*); for a
|
||||
volume of a playing song. No start at a marker (#338), no automation (#337), no song inside a song, no held note (drone) as an item. A pattern item cannot be made into a pattern of its own (*make unique*); for a
|
||||
variation, duplicate the pattern in the Assets panel and pick it on the item.
|
||||
+19
-1
@@ -102,7 +102,7 @@ start with 5 ms each and *Linear* on both.
|
||||
| --- | --- |
|
||||
| **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, 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. |
|
||||
| **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` or `Play note` gave out, at once or over `time` seconds. It also takes the `playback` of a `Play pattern` or `Play song` and moves the sound FX on all of it (#346). On a note with a sound FX of its own, a name both its instrument and its FX have changes both. |
|
||||
| **Sound** | A constant sound, for either of the two to work on through an edge. |
|
||||
|
||||
The division is deliberate: the **asset says what a sound is**, the node only colours it. A
|
||||
@@ -363,6 +363,24 @@ Every parameter has a number field in the header, starting at its default: what
|
||||
Moving a field while the tab plays is heard at once on that sound. Those values are the tab's own
|
||||
and never written into the asset.
|
||||
|
||||
### A Pitch on a bus
|
||||
|
||||
A sound FX on a track, a pattern item or a whole `Play pattern` /
|
||||
`Play song` (#346) has no file to read: it gets the sound of many notes as it plays. There the Pitch is a
|
||||
**pitch shifter** of its own, the same phase vocoder fed as it goes. It cannot look ahead, so it holds
|
||||
one frame back before it hands anything out: it is **2048 samples late** (43 ms at 48 kHz, 46 ms at
|
||||
44.1 kHz), at every pitch, 0 too, where it is the sound itself, exactly that much later. Because the
|
||||
latency never changes, it is made up exactly:
|
||||
|
||||
- Inside the FX, the other way of a Mix is held back as far as the Pitch makes one late, so an
|
||||
octave doubling (Pitch on one way only) stays together.
|
||||
- In a song, every note and clip starts as much earlier as the buses it is heard through are late
|
||||
(item, track and the whole playing added up). So everything is heard where it was planned: a track
|
||||
with a shifter in step with one without, and with the playhead. The scheduler plans that much
|
||||
further ahead, and the first note after Play comes that much later.
|
||||
|
||||
See [Songs](Songs#sound-fx-on-tracks-items-and-whole-songs) for where a bus gets its FX.
|
||||
|
||||
### Parameters
|
||||
|
||||
The **Input** declares parameters in the inspector (**+ Parameter**): a name and a **Default**,
|
||||
|
||||
Reference in new issue
Block a user