Changelog: the arrangement export
Format versions (exportVersion), newest first. Each lists what changed for a reader. Releases of Signals & Sorcery's arrangement semantics (contractVersion) are listed under the format version that was current then, with what they changed in an export's audio or meaning, or "nothing".
1.4.0
Optional fields only, present only when the song has words or roles, so 1.0–1.3 readers keep working on every export.
Added:
score.sections[].lyrics.lines: the words sung in each section, one line per phrase. When the song has words every section carries them, and an instrumental section has[]. A repeated chorus carries its words in full. See Lyrics.score.sections[].roleis filled: the section's part in the song form (verse,chorus,bridge…), free text, lower-case. It was reserved and always absent before.lyricsHash: SHA-256 of the lyrics payload (each section's words by id), present with words.timingHash,arrangementHashandscoreHashleave the words out.- The schema for 1.4.0, where
rolemust be non-empty;v1/schema.jsonis now 1.4.0.
Changed: nothing for a song without words or roles, hashes included. A file whose sections carry a role has a different scoreHash, since that payload always covered the role.
Arrangement releases while 1.4.0 was current: none yet (0.14.0 still).
1.3.0
Optional fields only, present only when a song has pickup bars, so 1.0–1.2 readers keep working on every other export.
Added:
arrangement.pickup: bars before the first section's downbeat that lead in to it, from frame 0. See Pickup bars.score.pickup, and spans in section"pickup". With pickup bars, song bars before 1 (0, −1 …) appear inscore.bars,tempoMapandmeterMap, and a span'sstartBarcan be 0 or below.- The timing payload's
pickup(only with pickup bars;timingHashcovers it), and pickup runs (section"pickup") in the arrangement payload. - The schema for 1.3.0;
v1/schema.jsonis now 1.3.0.
Changed: nothing for a song without pickup bars. With them, instances[0].startFrame is the pickup's length, not 0.
Arrangement releases while 1.3.0 was current:
- 0.14.0: songs can start on pickup bars (above). Arrangements without them export exactly as before, hashes included.
1.2.0
Optional fields only, so 1.0 and 1.1 readers keep working.
Added:
score: the arrangement resolved for a reader. It holds:- the tempo map, the meter map and the bar grid;
- the sections with their scenes;
- per layer: its role, bucket and drum piece, where it sounds (spans with level and fades), the effects placed on it, and, when asked, its notes in frames.
See Score.
scoreHash: SHA-256 of the score's payload. It changes with what the layers play, notes included. See Change detection.options.scoreandoptions.scoreNotes: whether the export wrote the score, and whether the score includes the notes.The schema for 1.2.0, and
v1/schema.json: the latest 1.x, which every 1.x file validates against.
Changed: nothing. timingHash and arrangementHash cover exactly what they did.
Arrangement releases while 1.2.0 was current:
- 0.13.0 (2026-10-24): every clip can have its own fades and level. A fade on one pasted copy of a clip no longer moves the others. The format didn't change: a run that a clip's own fade or level cuts inside a section is simply two runs, butt-joined, each with its own
fadeIn/fadeOutand level, andarrangementHashcovers them as it covers any run. Arrangements without clip settings export exactly as before, hashes included. - 0.12.0 (2026-10-20): audio regions can be trimmed, cut, copied and pasted by the beat (the meter's beat: eighths in 6/8), not only by the bar. The format didn't change. A score span or run that starts or stops inside a bar keeps the bars it touches (
startBaris the bar it starts in,endBarthe bar after the one it ends in); itsstartFrame/endFramesay exactly where inside them.arrangementHashcovers that: such a run carriesenterInsetBeats/exitInsetBeatsin the arrangement payload. Arrangements without beat edits export exactly as before, hashes included. - 0.11.1 (2026-10-18): a layer that jumps to another loop position where one section meets the next (a pasted run, or a phase change on the section's first bar) now plays from that position. It used to keep the earlier position's sample offset, which put its loop seams in the wrong place, and some such arrangements could not be played or exported at all. The format didn't change. The audio of those arrangements changes.
1.1.0
Optional fields only, so a 1.0 reader keeps working.
Added:
$schema: the exact schema version's URL.exportVersion: this format's version.exportId: a UUID per export.arrangement.revision{seq, docHash}: which edit of the arrangement the export was made from.arrangement.endFrame: the last bar's end, insampleRateframes.timingHash,arrangementHash: one comparison tells a re-timing from a re-arrangement from a re-render. See Change detection.files[].layerIds: the layers a stem carries.files[].startFrame(always 0) andfiles[].latencyMs(known uncompensated latency, 0).options.pathFree: leave every absolute path out.options.destinationandmaster.input.path/master.output.pathbecome optional in the schema (absent withpathFree).
Changed:
files[].filealways uses/as its separator. It used the operating system's.
Documented for the first time (no behaviour change): the specification, the JSON Schemas for 1.0.0 and 1.1.0, and fixtures for every rule in SPEC.md.
Arrangement releases while 1.1.0 was current:
- 0.11.0 (2026-10-10): alternatives groups (a vocal reading's takes, a kit's fills) play one unit per section, by the section's position or picked; the others rest. A scene's fills, which played in every section, now rotate. The format didn't change;
arrangementHashchanges for arrangements with groups, because what plays changed. See Alternatives (takes).
1.0.0 (2026-10-04)
The first versioned shape. Compared with the exports before it:
- Added the top-level
name: the export's name, and the base of its folder and file names. tailgainedmode:{mode: "auto", capSeconds, floorDbfs}or{mode: "fixed", seconds}.optionsgainednameandtail.
Arrangement releases while 1.0.0 was current:
- 0.10.0 (2026-10-08): the Arrange view's row order is saved with the arrangement. It is view state, so nothing in an export changes.
- 0.9.0 (2026-10-08): scene gains ("Normalize kick levels"). A scene's gain now adds to every lane of its layers wherever they play, so exported levels follow it. The format didn't change.
- 0.8.0 (2026-10-02, already current when 1.0.0 began): mute and solo in the arrangement. A silenced layer is left out of the mix and the master, and gets no stem.
Before 1.0.0 (2026-09-29 to 2026-10-03, unversioned)
- No top-level
name.tailwas{capSeconds, floorDbfs}(always automatic).optionshad nonameortail. These files don't validate against the 1.0.0 schema. Read their tail asmode: "auto". - Changes in meaning during that period:
- placed effects and exact run edges rendered into the audio (2026-09-29);
- arrangement audio no longer silent at tempos where a beat isn't a whole number of frames (0.7.1, 2026-10-02);
- silenced layers get no stem, and only the arrangement's own mute and solo count (2026-10-02 and 10-03).
The format itself: Arrangement export format. The source: github.com/shiehn/sas-arrangement-export-contract.