diff --git a/MCP.md b/MCP.md index ce0d7e7..c31b004 100644 --- a/MCP.md +++ b/MCP.md @@ -59,7 +59,7 @@ the badge says *Agent offline* meanwhile. | `screenshot` | The whole editor as drawn, as a PNG, at most `maxWidth` pixels wide (1280 unless asked otherwise) | | `list_assets` | The project's settings (start scene, layers, play settings, master bus) and the assets with ids, names and types, by type or a part of the name | | `list_files` | The pictures, typefaces, sounds or videos the server holds for your account, the demo material among them, whether a project uses them or not: file, upload name, size, a picture's size, a video's state, length, frame rate and sound, and the asset wearing it in this project. `add_file_asset` makes an asset of one, see below | -| `get_asset` | One asset as stored, with the rows of its properties and the named objects of a scene or container, the content of a placed container too (marked `fromContainer`, ids like `~`). A graph is only counted, and so are the cells of a map past 400. Pixel art lists its palette as `colors` and, up to 16 384 pixels over all layers and frames, every layer of every frame as rows of characters (`.` is transparent, `1`-`9`, `a`-`z`, `A`-`Z` the indices 1 to 61); a bigger one says how many pixels are painted. Colors of palettes and vector art read as `#rrggbb`. An animation lists what its rows may aim at (`targets`, the root as `""`), with the properties each offers. Under `usedBy`: every asset naming it or one of its frames or clips, with the objects, nodes, items or keys in there that do, and the start scene, master FX or master routing of the project; empty when nothing uses it | +| `get_asset` | One asset as stored, with the rows of its properties and the named objects of a scene or container, the content of a placed container too (marked `fromContainer`, ids like `~`). A graph is only counted, and so are the cells of a map past 400. Pixel art lists its palette as `colors` and, up to 16 384 pixels over all layers and frames, every layer of every frame as rows of characters (`.` is transparent, `1`-`9`, `a`-`z`, `A`-`Z` the indices 1 to 61); a bigger one says how many pixels are painted. Colors of palettes and vector art read as `#rrggbb`. An animation lists what its rows may aim at (`targets`, the root as `""`), with the properties each offers. Each track of a song carries its automation lanes and, under `params`, the parameters a lane of it can move, each with its default. Under `usedBy`: every asset naming it or one of its frames or clips, with the objects, nodes, items or keys in there that do, and the start scene, master FX or master routing of the project; empty when nothing uses it | | `get_graph` | A graph: every node with its settings and its ports as they are now (the ports it declares itself under `ports`), the edges, the groups and comments with their boxes and colors | | `lint_graph` | How a graph reads, counted as you see it: nodes on top of each other, links that cross, links running over a node that is not theirs, links running right to left, comments a node lies on, the longest links, with a few ids of each | | `catalog` | What there is to make: the commands by area with what each does, and with a query (an area or command names) their arguments; the nodes a graph can hold (all of them, or the best matches of a search in full); the asset types and their properties; the variable kinds | @@ -167,7 +167,7 @@ for an area or for command names asked for. | tiles | `add_tile_picture`, `remove_tile_picture`, `move_tile_picture`, `paint_tiles`, `add_tilemap_layer`, `duplicate_tilemap_layer`, `remove_tilemap_layer`, `move_tilemap_layer`, `set_tilemap_layer`, `resize_placed_tilemap` | | pixelart | `paint_pixels`, `add_pixel_layer`, `duplicate_pixel_layer`, `remove_pixel_layer`, `set_pixel_layer`, `move_pixel_layer`, `merge_pixel_layer_down`, `add_pixel_frame`, `remove_pixel_frame`, `move_pixel_frame`, `resize_pixel_canvas`, `set_palette_colors`, `remove_palette_color` | | vectorart | `add_vector_shape`, `set_vector_shape_outline`, `set_vector_shape_style`, `transform_vector_shapes`, `duplicate_vector_shape`, `remove_vector_shapes`, `combine_vector_shapes`, `rename_vector_shape`, `order_vector_shape`, `move_vector_shapes`, `group_vector_shapes`, `ungroup_vector_shapes`, `add_vector_layer`, `remove_vector_layer`, `move_vector_layer`, `set_vector_layer` | -| music | `add_notes`, `change_notes`, `remove_notes`, `set_loop`, `apply_preset`, `add_song_track`, `change_song_track`, `move_song_track`, `remove_song_track`, `add_song_item`, `change_song_item`, `remove_song_items`, `set_send`, `add_clip`, `change_clip`, `remove_clip` | +| music | `add_notes`, `change_notes`, `remove_notes`, `set_loop`, `apply_preset`, `add_song_track`, `change_song_track`, `move_song_track`, `remove_song_track`, `set_song_lane`, `add_song_item`, `change_song_item`, `remove_song_items`, `set_send`, `add_clip`, `change_clip`, `remove_clip` | | composition | `add_composition_track`, `change_composition_track`, `move_composition_track`, `remove_composition_track`, `add_composition_item`, `change_composition_item`, `remove_composition_items`, `add_composition_clip`, `change_composition_clip` | | project | `rename_project`, `set_layer_names`, `set_play_from`, `set_while_playing`, `set_game_link_zoom`, `set_symbol_scale`, `set_master_volume`, `set_master_fx` | @@ -202,6 +202,13 @@ from the inspector. not loaded yet needs a length. An object item's object is set with the commands of area objects, in = the composition. Moving an item takes the clips that belong to it along, as dragging does, and a clip that would come to lie over another is refused. +- **Automation of a song track** (#337) is one command, `set_song_lane`: the lane by its target + (`volume`, `pan` or `param:`, as `get_asset` lists it), and all its points at once, each a + tick, a value and an easing as for animation keys. Points on one tick stay in the order given, + which makes a jump. A value outside the lane, an easing there is none of and a Curve asset that is + not there are refused. `points: []` takes the lane of the volume or the pan away. A parameter lane + is only made for a parameter something on the track has (`params` in `get_asset`); without `min` + and `max` it gets the range the Song tab would offer, round the default. `remove` takes it away. Not for the agent, on purpose: uploading a file (it takes one the server holds), pasting needs the clipboard (the agent builds directly instead), and switching a plugin on would run its code. @@ -342,7 +349,10 @@ What is behind it on the server, and the routes it uses: [API](API), [Developmen replaced, a loop set and cleared; a pattern laid on a song as long as it is, a sound by its loaded length and refused while not loaded, tracks added, changed, moved and removed (the last one kept) with the routing following, sends of a song and of the master routing (a sound only after its - level); a clip of a sound added, changed and removed; an object, a picture and a pattern laid on a + level); a volume lane set in the order of its ticks with its easings, a value, an easing, a Curve + asset and a range out of place refused, and the lane cleared with no points; a parameter lane + refused for a parameter not on the track, made round its default, its points held to a narrower + range, set while its parameter is gone and removed, with `params` per track; a clip of a sound added, changed and removed; an object, a picture and a pattern laid on a composition, an animation and the composition itself refused as items, an item moved with its clip, a clip over another refused, fades only on what sounds, an item removed with its object, and the tracks of a composition; what of a pattern, a song and a composition is silent without an diff --git a/Songs.md b/Songs.md index 5eb2dee..189d360 100644 --- a/Songs.md +++ b/Songs.md @@ -21,8 +21,8 @@ inspector. Where a `Play song` and the tab are heard is said by the links of the song's node in the [Master routing](Sounds#master-routing) (#351). The *Output* of the song's own routing goes there. -One tempo and one meter hold for the whole song. A change of tempo within a song would come with -automation (#337). +One tempo and one meter hold for the whole song. [Automation](#automation) (#337) moves the volume, +the pan and parameters of a track, not the tempo. ### Tracks @@ -33,7 +33,8 @@ of its own: a change of volume, pan, mute or solo reaches what is sounding on it 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. +does at first, or through other tracks. Its volume, pan and the parameters of what lies on it can +change over the song along [automation lanes](#automation). ### Items @@ -131,6 +132,61 @@ below them. **Fit** shows the whole song across and all its tracks down, each as tall as they share out (28 to 320 px), with 9 % of the lanes free on every side. A song with no view kept yet opens fitted the same way. +## Automation + +A track can change its **volume**, its **pan** and the **parameters** of what lies on it over the +song, along points on an automation lane (#337). From each point the value runs to the next along +that point's easing, as from one [animation key](Animations) to the next: Linear, Step, every curve +going in, out or both, or a [Curve](Curves) asset of the project. Before the first point the lane +holds the first value, after the last one the last. Two points on one tick are a jump there. + +- **The volume** is in dB, -60 to +12, **the pan** -1 (left) to 1 (right). While their lane has a + point, it rules the value in place of the track's own: the fader in the head shows the lane's + value in pink and cannot be dragged, and the inspector says which lanes rule the track. Cleared, + the lane goes and the track's own value rules again, from where the lane left it. +- **A parameter** (`param:`) moves every parameter of that name on the track: of the track's + [sound FX](#sound-fx-on-tracks-items-and-whole-songs), of the sound FX of its items, of the + [instruments](Instruments) its patterns play and of their own sound FX, as `Set sound FX + parameters` reaches them. A parameter says nothing of its own range, so its lane keeps one (*From* + and *To*). Such a lane stays, for its range, until it is removed, also without a point. Removed, + the parameter goes back to its default. +- **A note or clip starts at the value its lane has there.** While it sounds it follows the lane. + What a voice only reads when it starts (the times of an envelope, the pick of a Sample) changes + from the next note on. +- A lane is played on the clock of the sound, ramped where it can be and read every 10 ms where it + runs along a curve. At the end of the loop it jumps back with the playhead. It is heard in the + tab, in `Play song`, in a bake, and in a [composition](Compositions) that plays the song, round + the song's loop there too. +- An edit while the song plays is heard from the next window on. While a lane rules a value, the + track's own value does not set it back. + +### Lanes in the Song tab + +The triangle at the left of a head folds the lanes of its track out and in: one for the volume and +one for the pan, and one for each parameter it has a lane for. The right-click menu of the head +shows or hides each lane by itself (*Volume lane*, *Pan lane*, …) and has *Add parameter lane…*, +a dialog for the parameter and its range, which starts round the parameter's default (0 to 2000 for +800). The triangle is pink while the track has automation. A lane with points opens by itself; +which lanes are open belongs to the view of the tab, not to the song, and takes no undo step. + +A lane is a row of its own, as high as a track, under its track. Its head shows its name and the +value at the playhead, or where playing starts. + +| Do this | And this happens | +|---|---| +| Click on a lane | A point on the grid line nearest the pointer, at the height clicked. With `Alt` or `Shift`, on the tick. | +| Press and drag on a lane | A point is set and dragged along, in one undo step. | +| Drag a point | It moves in time and value. It stops at the point next to it; on the same tick the two make a jump. The value shows beside it. | +| Rest the pointer on a point | A tooltip with its value. | +| Double-click a point, or `Delete` with one picked | Deletes it. | +| Right-click a point | *Ease to next point*, with the same choice as animation keys, and *Delete point*. | +| Right-click a lane's head | *Clear lane* (every point), *Hide lane*; on a parameter's lane also *Range…* and *Remove lane*. | + +Measured (2026-10-19, e2e 65 on the CI's Windows machine): a volume lane playing in the tab set the +level of its track's bus 0.09 dB off the lane at the playhead, with the fader at -60 dB. A sound +item whose sound FX turns its parameter `cut` into a gain started at the lane's value there (-27.5 dB +at tick 9600), and at two readings 1.5 s apart its gain lay within 0.04 dB of the lane. + ## Routing **Routing** in the header shows the song as a graph instead of the timeline (#350): a node for @@ -363,7 +419,7 @@ edit is heard at once. and `Set sound FX parameters`, `volume`, `fade in`, the bus, the Master routing and a stop with a fade. A node behaves the same with a bake and without. - **When it holds:** a bake keeps a print of what it was made from: the notes and clips, tempo, - length and loop, the tracks with their level, pan and FX, how each instrument plays each of its + length and loop, the tracks with their level, pan, FX and automation lanes, how each instrument plays each of its notes with its sound FX, and the files, cuts and levels of the sounds. A change to any of them outdates it, also one to an instrument or a sound the pattern only names. Then the icon is no longer lit, the info of the tab says *bake outdated*, and a game plays the notes again. Renaming @@ -416,8 +472,9 @@ Bitcrusher crushes the chord, and it costs one chain however many notes sound. (#352). In the tab the song's FX sits on a bus of the tab between the output and the master. The tab leaves the song's links in the Master routing out (#368). - 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`. +- Track and item FX play at the defaults of their parameters, unless a lane of the track moves them + (see [Automation](#automation)). 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. @@ -433,7 +490,8 @@ bus. Stop let it go. An item's *Sound FX* offered *From the asset*, *None* and t ## Not yet A link sends at one volume; it cannot be moved over time. Nothing tells a graph that a song played -once has ended (#373), and there is no node that changes the volume of a playing song. No start at a -marker (#338), no automation (#337), no swing (#372), no song inside a song, no held note (drone) as +once has ended (#373), and there is no node that changes the volume of a playing song or the value +of a lane while it plays. No start at a marker (#338), no automation of the tempo and none in a +pattern (#337 left both out), no swing (#372), no song inside a song, no held note (drone) as an item. A variation of a pattern for one item is *Embed a copy* in the item's menu (see [Embedded assets](#embedded-assets)). A song cannot keep an instrument to itself.