Describe the routing of song tracks (#350)

The Song tab has a Routing view now. The Songs page explains it.

- Songs: new section Routing with the nodes, the sends (volume and the
  three modes), loops, the "Goes nowhere" warning and the latency
  compensation per send, with measured values.
- Songs: mute and solo act along the routing, with the case of tracks
  going into a soloed track and into the output. Header, FX order and
  Not yet are brought in line.
- Development: 1872 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-10-07 20:18:25 +02:00
1 parent 4378d28d84
commit b065d62d20
2 files changed
+62 -12

No files matched your search

+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 # 1867 editor checks, screenshots in /tmp/gm-e2e-*.png
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1872 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
+61 -11
@@ -24,10 +24,13 @@ automation (#337).
### Tracks
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
and **solo**. While any track is soloed, only the soloed ones are heard, with what goes into them and
through the tracks they go through (see [Routing](#routing)). 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. 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)).
Where a track goes from there is the song's [routing](#routing): into the output, as every track
does at first, or through other tracks.
### Items
@@ -61,9 +64,10 @@ round. An end of an item under the pointer lights up and the pointer turns into
end can be dragged. A picked item has a white edge; a picked track a lit head and lane. Zoomed down
to less than 46 px, a head shows only its name, **M** and **S**.
The header has **Play** (it turns into **Stop**), **Record** with the input to record from and its
level, the **Grid**, **Fit** and on the right the number of tracks and items. **Fit** shows the
whole song across.
The header has **Timeline** and **Routing** (what the tab shows, see [Routing](#routing)), **Play**
(it turns into **Stop**), **Record** with the input to record from and its level, the **Grid**,
**Fit** and on the right the number of tracks and items. **Fit** shows the whole song across, or
frames the routing graph.
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, solo and sound FX. A click on nothing in the lanes picks the
@@ -117,6 +121,50 @@ pans both ways, and as in the Pattern tab it can take bar 1 up to half the lanes
it drawn dark and only to look at. Down the lanes it can take the first track up to half the height
down and the last up to half the height up; nothing lies above or below them. **Fit** shows the whole song across and keeps the height of the tracks.
## Routing
**Routing** in the header shows the song as a graph instead of the timeline (#350): a node for
every track, named after it, and one node **Output**. The output is what the song sounds like; from
there it goes on to the [bus](Sounds#buses-and-the-master) of the song. It is the same graph editor
as for a sound FX, with zoom, snap, undo, groups and comments. **Timeline** goes back.
- **A link is a send.** A track takes in any number of links and sends to any number of tracks and
the output. It mixes its own items and everything that comes in, sends that through its sound FX,
volume and pan, and then out along every link.
- **A new track is linked to the output**, and so is every track of a song made before #350, which
had no routing yet. A track linked nowhere is not heard: its node says *Goes nowhere*.
- **The nodes come and go with the tracks.** They cannot be added in the graph, and `Delete` does
not take them; a track is deleted in the timeline. Its name comes from the track, its volume, pan
and sound FX stay in its head. The output is there once.
- **No loops.** A link that would lead back to the track it comes from is refused while dragging.
A picked link shows two rows in the inspector:
| Row | |
|---|---|
| **Volume** | -60 to +12 dB, 0 dB at first: how loud it sends. |
| **Mode** | Where on its track it takes the sound. **Post volume (Post pan)**, the default: after the sound FX, the volume and the pan. **Pre volume (Post FX)**: after the sound FX, before volume and pan. **Pre volume (Pre FX)**: right where it comes in, before the sound FX. |
**Mute and solo along the routing.** A muted track passes nothing on: neither its items nor what
comes into it, on no link, whatever its mode. While some tracks are soloed, a soloed track is heard
with every track that goes into it. The tracks it goes through on its way out pass it on, but their
own items are silent. Every other track is silent. So with A into B and B into the output, solo on A
lets A be heard through B, without what lies on B. Only the ways through a soloed track are open: if
A and B go into C and also straight into the output, solo on C lets A and B be heard through C only,
their links into the output closed.
**In step.** A track's links can be late by different amounts: one past a [Pitch](Sounds#a-pitch-on-a-bus)
that is a frame late, one before it (*Pre FX*) that is not. Every way of a track is held back as far
as its latest one, so all of it reaches the output together and nothing is heard twice a frame apart.
A note is started as much earlier as that latest way is late.
Measured (2026-10-07, e2e 65 on the CI's Windows machine): in a song of five tracks, every track was
linked to the output when Routing opened. A drag from the first track into the second linked them,
the drag back was refused, `Delete` took two links to the output and no track, and the third track,
now linked nowhere, said *Goes nowhere*. Volume -6 dB and *Pre volume (Pre FX)* on the link from the
first into the second track: playing, the first track's only send went into the second track's bus
at 0.501 from before its sound FX, the third track had no send at all.
## Playing
**Space** or **Play** plays the song round its loop from where playing starts, through the
@@ -133,7 +181,7 @@ tab, when the song is gone and when a project is opened.
Measured (2026-10-06, e2e 65 on the CI's Windows machine): a sound clip on the first track and a
pattern at bar 3 on the third, at 120 BPM, were planned 4 s apart, the pattern's notes 1 s apart,
each on the bus of its track; a track turned down to -6 dB was set to 0.501 on its bus, and muting a
track while the song played set its bus to 0.
track while the song played closed its send to 0 (since #350; its own level stayed at 1).
## Recording
@@ -161,8 +209,8 @@ names of the inputs show once recording has been allowed, and the browser keeps
## Playing one in a game
**Play song** plays a song at its tempo, its tracks with the volume, pan, mute and solo they have,
on the same scheduler as the tab.
**Play song** plays a song at its tempo, its tracks with the volume, pan, mute and solo they have
and along its [routing](#routing), on the same scheduler as the tab.
| Input | |
|---|---|
@@ -186,7 +234,7 @@ it is 0. `fade out` is the seconds it falls silent over first; it plays on meanw
naming no sound stops songs too, and the end of the run stops every song.
Each playing is heard through a level of its own, which the fades move, with a bus inside it for
each track. `Pause game` leaves the music playing, and `Set time scale` does not slow it; the pause
each track; the output of the routing is that level. `Pause game` leaves the music playing, and `Set time scale` does not slow it; the pause
in the toolbar holds it where it is, as it holds every sound.
Measured (2026-10-06, e2e 65): a sound clip on the first bar and a pattern on the second, looped
@@ -203,8 +251,9 @@ through it **together**. A Phaser's LFO runs on across the notes, a Delay echoes
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 → the [bus](Sounds#buses-and-the-master) of
the song and the master. A sound item keeps its own *Sound FX* per
pan → the links of the [routing](#routing), through other tracks or straight on → the FX of the
`Play song` → its volume and fades → the [bus](Sounds#buses-and-the-master) of the song and the
master. 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
@@ -218,6 +267,7 @@ Measured (2026-10-07, e2e 65): a sound FX with a Pitch of +12 on the second trac
## Not yet
Nothing tells a graph that a song played once has ended, and there is no node that changes the
A link sends at one volume; it cannot be moved over time, and there is no reverb to send to yet
(#328). 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 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.