From b065d62d20738bc438c16c219e7d982dcb4dd3ff Mon Sep 17 00:00:00 2001 From: MelekTaus Date: Wed, 7 Oct 2026 20:18:25 +0200 Subject: [PATCH] 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 --- Development.md | 2 +- Songs.md | 72 ++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/Development.md b/Development.md index c08cc72..0378236 100644 --- a/Development.md +++ b/Development.md @@ -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 diff --git a/Songs.md b/Songs.md index 516888f..36e0a86 100644 --- a/Songs.md +++ b/Songs.md @@ -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.