# ode, the song format

> ode, the language a Songcode track is written in. The first line, the plan at the top, stems, the arrange table, blocks that change a stem for part of the track, the mix table and how it changes through a track, lyrics and score blocks.

A track is a short text file written in ode, Songcode's language for a song. The current version is ode 0.3.0. Anyone who writes ode is an odist, and Songcode, which wrote the language, is the greatest odist of all. This page is its reference: what each part of a track is for and the rules the app holds it to. [Rows and settings](https://docs.songco.de/ode/rows-and-settings/) covers what goes inside a stem.

## The shape of a track

A track has three parts, and no fact is written twice.

- **Stems** say what each instrument plays.
- **The arrange table** says where in the track each stem plays.
- **The mix table** says how loud each stem is, where it sits from left to right, and where in the track either one changes.

Above them sits the plan: the tempo, the key, the sections and the chords.

## A whole loop

This is one of the worked examples the model is shown, complete.

```ode
ode
title "night bus"
tempo 124
key a minor
swing 56%
form loop 8
chords [Am9 | % | Fmaj7 | Em7]

stem kick: analog {
  kick [x... x... x... x...]
}

stem hats: analog {
  hat      [xxxx xxxx xxxx xxxx]
  openhat  [..x. ..x. ..x. ..x.]
  velocity [100 38 62 44]
  chance   88%
  highpass 420hz
  bar 8 of 8 {
    hat [xxxx xxxx xx22 2222]
  }
}

stem clap: analog {
  clap     [.... x... .... x...]
  behind   8ms
  highpass 260hz
  reverb   30%
}

stem bass: pulsebass {
  rhythm   [x.xx .x.x x.xx .x..]
  tones    [root]
  octave   1
  velocity [112 70 84 70]
  lowpass  sweep(320hz, 1.5khz, every: 8bars), resonance: 35%
}

stem stab: dubchord {
  rhythm   [.... x... .... ..x.]
  tones    [all]
  octave   3
  highpass 330hz
  reverb   45%, tone: 4.2khz
  delay    30%, time: 3/16
}

stem perc: clave {
  rhythm   [..x. .x.. x... .x..]
  take     [0 2 1 3]
  chance   60%
  highpass 700hz
}

mix {
  kick  0db
  hats  -10db, pan: 15R
  clap  -7db
  bass  -4db
  stab  -8db, pan: 10L
  perc  -14db, pan: 30R
  duck bass, stab under kick, depth: 75%, recover: 110ms
}
```

## How it is written

ode has one grammar, and anything outside it is an error.

| piece | rule | example |
|---|---|---|
| first line | Exactly `ode`. | `ode` |
| statement | Starts with a word and ends at the end of the line. | `tempo 126` |
| block | A statement that opens `{` and holds statements until `}`. | `stem bass: fmbass { }` |
| row | Music, between `[` and `]`. `\|` ends a bar. A row may run over several lines. | `[x... x... x... x...]` |
| quantity | A number with its unit attached, no space. | `400hz` `8ms` `-6db` `30%` `16bars` |
| detail | Follows a setting after a comma, as `name: value`. | `reverb 40%, decay: 6s` |
| name | Lowercase letters, digits and `_`. You name stems, sections, phrases and groups. | `bass` `verse_2` |
| text | In double quotes. Only titles and lyrics. | `"glass elevator"` |
| comment | `//` to the end of the line. | `// drop` |

A track declares music and runs nothing. There are no loops, no conditions and no functions of your own, so opening someone's track never runs their code.

## The first line

```ode
ode
```

The first line says the track is written in ode. Every track Songcode writes starts with it, and a track that starts with anything else does not open.

The line can also name a version of ode, as in `ode 0.3.0`. That is optional: `ode` alone reads as the newest version the engine knows, and it is what Songcode writes. Name a version when a track has to say which ode it needs, so an older engine says plainly that it cannot read it instead of tripping over a word it does not know. Tracks saved before ode was versioned start with `ode 1`, and they still open and play as they always have. See [versions](https://docs.songco.de/ode/versions/).

## The plan

```ode
title "glass elevator"
tempo 126
key f minor
swing 54%
form intro 8, build 8, main 16, break 8, peak 16, outro 8
chords [Fm9 | % | Dbmaj7 | Eb6]
```

The top of a track is its plan. Everything below is checked against it.

| statement | what it sets |
|---|---|
| `title "glass elevator"` | The track's name. |
| `tempo 126` | The speed, in beats a minute. A beat is a quarter note, or a dotted quarter in 6/8, 9/8 and 12/8. |
| `meter 3/4` | The time signature, for the whole track. Left out, it is 4/4. |
| `key f minor` | The tonic and the scale. Scale steps and chord tones are worked out from it. |
| `tuning e -50cents, b -50cents` | Moves those notes, in every octave and on every pitched stem, away from equal temperament, by up to 100 cents either way. Quarter tones, pure thirds and tunings from outside the piano are written this way. Left out, the track is in equal temperament. |
| `swing 54%` | The track's swing. See [swing](https://docs.songco.de/ode/rows-and-settings/#swing-and-feel). |
| `loose 8ms` | How far each note may land from where it is written, for every stem. Left out, the track is on the grid. See [swing and feel](https://docs.songco.de/ode/rows-and-settings/#swing-and-feel). |
| `seed 7` | The number that `chance`, `humanize` and `loose` draw from. The same seed gives the same track every time. |
| `allow range` | Lets every stem break a rule of [what a person can play](https://docs.songco.de/ode/rows-and-settings/#played-by-a-person): `range`, `reach`, `hands`, `breath`, `speed`, or `all`. A stem can say it for itself instead. |
| `form …` | The sections in order, with their lengths in bars. |
| `chords […]` | The chord chart. |

The scales are `major`, `minor`, `dorian`, `phrygian`, `lydian`, `mixolydian`, `locrian`, `harmonic minor`, `melodic minor`, `major pentatonic`, `minor pentatonic`, `blues`, `whole tone` and `chromatic`.

A wider set covers jazz and scales from outside the western seven: `harmonic major`, `major blues`, `diminished`, `half whole diminished`, `altered`, `lydian dominant`, `bebop`, `phrygian dominant`, `double harmonic major`, `hungarian minor`, `neapolitan minor`, `persian`, `hirajoshi`, `in sen`, `iwato`, `kumoi`, `pelog`, `egyptian`, `prometheus`, `augmented` and `enigmatic`.

An odd meter names how its beats group, and rhythm rows are grouped the same way:

```ode
meter 7/8, beats: 2+2+3
```

## The form

```ode
form intro 8, verse 16, chorus 8, verse 16, chorus 8, outro 8
```

`form` lists the track's sections in order, each as a name and a length in bars. The total is the length of the track. Section names are free: whatever fits the music.

- A **loop** has one section, `form loop 8`, and repeats at exactly that length.
- A **full track** has several. The app shows their names along the timeline.
- A name used twice is the same section played again, so a chorus is written once. `in chorus 2 { }` then changes only the second one: in a stem, in the mix, or at the top of the track for its chords and key.

Bar numbers inside a section count from the start of that section. Moving a section never renumbers its music.

## The chords

```ode
chords [Fm9 | % | Dbmaj7 | Eb6]
```

The chord chart is written the way a lead sheet writes it.

- `|` ends a bar.
- `%` repeats the bar before.
- Chords that share a bar split it evenly, and `-` holds the chord before it.
- The chart starts again when it runs out, for as long as its section lasts.

Chord names are the ones on a lead sheet: `Fm9`, `Dbmaj7`, `C7`, `Gsus4`, `Bdim`, `Ab/C`.

The chart is what keeps a track in one key. A bass written as `tones [root]` and a pad written as `tones [all]` both read it, so changing one chord here changes every stem that follows it.

A section can have its own chords or its own key:

```ode
in break {
  chords [Dbmaj7 | % | Bbm9 | C7]
}
in chorus 2 {
  key g minor
}
```

`in chorus 2` is the second time the chorus comes.

## Stems

```ode
stem bass: fmbass {
  rhythm  [x.x. ..x. x... ..xx]
  tones   [root]
  octave  1
  lowpass 700hz, resonance: 20%
}
```

A stem is one instrument: the word `stem`, a name, a sound from the [catalog](https://docs.songco.de/audio-engine/sounds/), and a block. Inside the block come the rows that say what it plays, then its settings, then any blocks that change it for part of the track.

Because each stem stands alone, the app can mute, redraw or regenerate one without touching the rest.

A stem carries its music in one of three ways:

- **Lanes**, on a drum kit: one row per drum.
- **A rhythm and a pitch row**, for parts that repeat: basslines, stabs, pads, arpeggios.
- **A line**, for melodies and anything written note by note.

[Rows and settings](https://docs.songco.de/ode/rows-and-settings/) covers all three.

Rules for names:

- Lowercase letters, digits and underscores.
- Name a stem for what it is. The app recognises 15 roles from the name: kick, snare, clap, hats, perc, bass, sub, chords, stab, lead, arp, pad, vocal, texture, fx. See [roles](https://docs.songco.de/app/stem-editor/#roles).
- Each name is used once.

## The arrange table

```ode
form intro 8, verse 16, chorus 8, verse 16, chorus 8, outro 8

arrange {
  sections [intro verse chorus verse chorus outro]
  kick     [.     x     x      x     x      .]
  bass     [.     x     x      x     x      x]
  keys     [x     .     x      x     x      x]
  lead     [.     .     x      .     x      .]
  lift     [.     4     .      4     .      .]
}
```

Where each stem plays is one table: a row per stem and a column per section, in the order the form lists them. A section that comes twice has two columns, so the second verse can carry more than the first.

| mark | what it means |
|---|---|
| `x` | The stem plays in that section. |
| `.` | The stem rests. |
| a number | The stem plays only the last that many bars. This is for risers, rolls and pickups. |

A stem with no row plays through the whole track. A loop needs no arrange table.

## Blocks

A block inside a stem changes it for part of the track. A row in the block replaces the stem's row of the same name there, and a setting replaces that setting. A `line` in a block takes the whole part over from the stem's `rhythm` and pitch rows, and a `rhythm` takes it over from a `line`, so one stem can loop a figure in the verse and play a written melody in the break.

```ode
stem hats: club {
  hat      [xx.x xx.x xx.x xx.x]
  highpass 400hz
  in intro, outro {
    chance  55%
    lowpass 4khz
  }
  last 1bar into main, peak {
    hat [xx.x xx.x xx.x 2222]
  }
}
```

| block | what it covers |
|---|---|
| `in intro, outro { }` | Those sections. `in verse 2 { }` is only the second verse. |
| `last 1bar into main, peak { }` | The last bar before those sections begin. This is how fills, drops and a bar of silence are written. |
| `last 2bars into end { }` | The last bars of the track. `end` is the end of the song: an ending, a last hit, a fade. A loop has no end, so it takes `bar … of`. |
| `bar 8 of 8 { }` | The 8th bar of every 8. `bars 7..8 of 8` covers the last two, and `bars 9..16 of 16` gives the second half of a section its own rows. A line in there may open with its bar number, `9:`. |

A block may also hold one of a few moves:

| move | what it does |
|---|---|
| `silent` | The stem plays nothing. One bar of it before a drop is the most used. |
| `ratchet 2` | Every hit is doubled. |
| `halftime` `doubletime` | The row plays at half or twice its speed. |
| `reverse` | The row plays backwards. |
| `shift 2` | The row plays two steps later. |
| `transpose 12st` `octave 5` | The stem moves up or down. |

When several blocks touch the same bar, the most specific wins: `last … into` beats `bar … of`, which beats `in`, which beats the stem's own lines.

## A whole full track

The second worked example the model is shown.

```ode
ode
title "glass elevator"
tempo 126
key f minor
swing 54%
form intro 8, build 8, main 16, break 8, peak 16, outro 8
chords [Fm9 | % | Dbmaj7 | Eb6 | Fm9 | % | Bbm7 | C7]

in break {
  chords [Dbmaj7 | % | Bbm9 | % | Gm7b5 | % | C7sus4 | C7]
}
in peak {
  chords [Fm9 | Abmaj7 | Dbmaj7 | Eb6 | Fm9 | Abmaj7 | Bbm7 | C7]
}
in outro {
  chords [Fm9 | % | Dbmaj7 | % | Fm9 | % | % | %]
}

// the theme and its answer: hinted in the build, stated in main, slowed down in the break, developed at the peak
let theme  = line [c5/8 r ab4 c5/4 bb4/8 ab4/4 | g4/4. ab4/8 f4/2]
let answer = line [ab4/8 r ab4 bb4/4 c5/8 bb4/4 | g4/4. bb4/8 g4/2]
let turn   = line [db5/4 f5/8 db5 bb4/4 db5 | c5/2 e4/4 g4]

arrange {
  sections [intro build main break peak outro]
  kick     [x     x     x    .     x    x]
  clap     [.     x     x    .     x    .]
  hats     [x     x     x    .     x    x]
  bass     [.     x     x    .     x    x]
  keys     [.     x     x    x     x    x]
  motif    [.     x     x    .     .    x]
  pad      [.     .     .    x     x    x]
  lead     [.     .     .    .     x    .]
  lift     [.     4     .    4     .    .]
}

stem kick: club {
  kick [x... x... x... x...]
  bar 8 of 8 {
    kick [x... x... x... x.x.]
  }
  last 1bar into main { silent }
  last 2bars into end { silent }
}

stem clap: club {
  clap   [.... x... .... x...]
  behind 8ms
  reverb 25%
  last 1bar into peak {
    clap [.... x... ..x. x.xx]
  }
}

stem hats: club {
  hat      [xx.x xx.x xx.x xx.x | xx.x xx.x xx.x xxxx]
  openhat  [..x. ..x. ..x. ..x. | ..x. ..x. ..x. ....]
  velocity [100 40 65 45]
  chance   90%
  highpass 400hz
  in intro, outro {
    chance  55%
    lowpass 4khz
  }
  in peak {
    hat [xxxx xxxx xxxx xxxx | xxxx xxxx xxxx xx.x]
  }
  last 1bar into main, peak {
    hat [xx.x xx.x xx.x 2222]
  }
  last 2bars into end { silent }
}

stem bass: fmbass {
  rhythm   [xxxx xxxx xxxx xxxx]
  tones    [root]
  octave   1
  velocity [110 60 85 60]
  lowpass  sweep(300hz, 1.2khz, every: 16bars), resonance: 30%
  in build {
    lowpass 500hz
  }
  in peak {
    rhythm [x.xx x.xx x.xx x.xx]
    tones  [1 1 1' 1 1 1' 1 1 1' 1 1 1']
  }
  bar 8 of 8 {
    rhythm [xxxx xxxx x.x. x.x.]
    tones  [1 1 1 1 1 1 1 1 3 2 1' 3]
  }
  last 2bars into end {
    rhythm [x | -]
    tones  [root]
  }
}

stem keys: reedpiano {
  rhythm   [x... ..x. .... ..x.]
  tones    [all]
  octave   3
  voicing  smooth
  highpass 320hz
  phaser   0.4hz, depth: 40%
  reverb   40%
  delay    25%, time: 3/16, feedback: 40%
  in break {
    line [mp theme(slower) | bb4/2 g4/4 bb4 | db5/2. bb4/4 | < c5/1 | r/2 mf e4/4 g4]
    reverb 70%
  }
  in outro {
    rhythm [x]
  }
}

stem motif: synthpluck {
  line [theme | answer | theme | turn]
  delay 30%, time: 3/16, feedback: 35%
  reverb 30%
  in build {
    line [theme(first 4) r/8 r/4 | r/1 | r/1 | r/1]
    lowpass 1.4khz
  }
  in main {
    bars 13..16 of 16 {
      line [13: theme(up 2) | turn]
    }
  }
  in outro {
    line [theme(first 4) r/8 r/4 | r/1 | theme(first 4, down 2) r/8 r/4 | r/1]
  }
}

stem pad: ensemble {
  rhythm   [x]
  tones    [all]
  voicing  smooth
  attack   400ms
  release  1.5s
  highpass 240hz
  chorus   35%
  bell     400hz, gain: -3db, width: 1oct
  reverb   60%, decay: 6s
  in break {
    lowpass ramp(500hz, 6khz)
  }
}

stem lead: sawlead {
  line [theme | answer(up 2) | theme(up 2) | turn]
  delay 30%, time: 3/16
  bars 9..16 of 16 {
    line [9: theme(up 1oct) | answer(up 1oct) | theme(first 1bar, up 1oct) | theme(first 1bar, up 2) | f5/4:bend db5/8 f5 bb5/4 f5 | g5/2 e5/4 c5:fall]
  }
}

stem lift: riser {
  rhythm   [x | - | - | -]
  highpass ramp(300hz, 9khz)
  fade     in
}

mix {
  kick   0db
  clap   -7db
  hats   -10db, pan: 15R
  bass   -4db
  keys   -8db, pan: 10L
  motif  -9db, pan: 12R
  pad    -11db
  lead   -9db
  lift   -12db
  duck bass, keys, pad under kick, depth: 75%, recover: 110ms
  reverb decay: 1.8s, tone: 5khz
  master ceiling: -1db

  in break {
    pad   ramp(-17db, -11db)
    keys  -6db
  }
  in outro {
    hats   ramp(-10db, -16db)
    motif  ramp(-9db, -15db)
  }
}
```

## The mix table

```ode
group drums: kick, clap, hats

mix {
  kick   0db
  clap   -7db
  hats   -10db, pan: 15R
  bass   -4db
  pad    -11db, mute
  drums  -1db
  duck bass, pad under kick, depth: 75%, recover: 110ms
  reverb decay: 1.8s, tone: 5khz
}
```

The mix is one table at the end of the track.

| row | what it means |
|---|---|
| `hats -10db, pan: 15R` | A stem's level and pan. `0db` is the sound at its catalog level. Pan runs from `50L` to `50R`, and `C` is the centre. |
| `pad -11db, mute` | A muted stem keeps its level. |
| `drums -1db` | A group's level, on top of its stems' own levels. A group is declared with `group`. |
| `duck bass, pad under kick` | Those stems dip each time the kick plays. `depth` is how far and `recover` is how long they take to come back. |
| `reverb decay: 1.8s, tone: 5khz` | The one reverb that every stem's `reverb` amount feeds. |

The table and the [stems view](https://docs.songco.de/app/stems/) are the same thing. Dragging the bass fader rewrites `bass -4db`, and typing `-6db` moves the fader. Level and pan live only here. A stem that sets either is an error that says where they go.

Solo is not in the code. It is a way of listening, so it stays in the app.

### A mix that changes

The rows above are the track's resting mix. Blocks under them change it for part of the track. They are the same three blocks a stem takes, and each holds rows.

```ode
group drums: kick, clap, hats

mix {
  kick   0db
  clap   -7db
  hats   -10db, pan: 15R
  bass   -4db
  pad    -11db
  voice  -6db

  in verse {
    voice  -8db
    pad    pan: ramp(30L, 30R)
  }
  in break {
    pad    ramp(-18db, -11db)
    drums  -3db
  }
  bar 8 of 8 {
    hats  mute
  }
  last 4bars into end {
    master  fade out
  }
}
```

| row in a block | what it does |
|---|---|
| `voice -8db` | The stem's level for as long as the block lasts. It is the level itself, taking the place of the stem's row there, so `-8db` against a row of `-6db` is 2 dB down. |
| `pad ramp(-18db, -11db)` | A level that climbs or falls across the block. `sweep(-14db, -9db, every: 2bars)` goes there and back. |
| `pad pan: ramp(30L, 30R)` | A pan that travels across the block. `pan: 25L` holds the stem there, and `pan: sweep(40L, 40R, every: 4bars)` goes from side to side. |
| `pad fade in` `pad fade out` | Up from silence across the block, or down to it. |
| `hats mute` | Silent for the block. |
| `drums -3db` | A group's row moves every stem in it together, on top of their own rows. |
| `master fade out` | `master` is the whole mix. It takes a level, a ramp or a fade. |

A row names its stem, then the level if it has one, then `pan:`, `fade in`, `fade out` and `mute`, with commas between. Pan is set stem by stem, so a group and `master` take none. `duck`, `reverb` and `master ceiling` are set once for the track, above the blocks.

Where two blocks cover the same bar and name the same stem, the later one in the table wins, setting by setting: one can set the level while the other sets the pan.

These moves run through a note while it sounds. A pad held for eight bars fades and travels smoothly, where a filter `ramp` on a stem is read once at the start of each note.

A fader in the [stems view](https://docs.songco.de/app/stems/) writes the stem's row above the blocks and leaves the blocks as they are.

## Lyrics

```ode
stem voice: alto {
  line [r/4 g4/8 g4 a4/4 b4 | c5/2 b4/4 r/4 | r/4 a4/8 a4 b4/4 g4 | e4/2. r/4]
  lyrics 2bars {
    "the river keeps its name"
    "long after the rain"
  }
  reverb 30%
}
```

A vocal is a stem like any other: a [singer](https://docs.songco.de/audio-engine/sounds/#singers) as its sound, a melody as a [line](https://docs.songco.de/ode/rows-and-settings/#lines), and the words in a `lyrics` block.

- **One syllable per note, in order.**
- **The length is how long each quoted line takes.** `lyrics 2bars` sings the first line over two bars and the next line over the next two.
- **Sections get their own words** with a block: `in chorus { lyrics 2bars { … } }`.
- **A harmony** is a second singer stem with its own line.

Inside the quotes, a few marks place the words:

| mark | what it does |
|---|---|
| `-` | Splits a word into syllables: `riv-er` takes two notes. |
| `_` | Holds the syllable before for one more note. |
| `/k.ae.t/` | Spells a word in phonemes, for when a singer says it wrong. |
| `"~"` | A line that is only `~` is a silent line. |

Lyrics are English. To hear a vocal in a generated track, ask for one in the prompt: "with a sung chorus about the last train home". A track is instrumental unless the prompt asks for singing or lyrics.

## Score blocks

Music that never repeats is written a few bars at a time, with every part together.

```ode
ode
title "small minuet"
tempo 112
meter 3/4
key g major
form a 8

stem violin: violin {
  reverb 30%
}
stem cello: cello {
  reverb 25%
}

score a bars 1..4 {
  violin [1: mf b4/4 d5/8 c5 b4 a4 | g4/4 b4 d5 | c5/4 e5/8 d5 c5 b4 | a4/2 r/4]
  cello  [1: mp g2/2. | b2/2 d3/4 | c3/2. | d3/2 d2/4]
}
score a bars 5..8 {
  violin [5: b4/4 d5/8 c5 b4 a4 | g4/4 e5 d5 | c5/8 b4 a4/4 f#4 | g4/2.]
  cello  [5: g2/2. | e3/2 b2/4 | c3/4 d3 d2 | g2/2.]
}
```

- Each row is a stem's name and a [line](https://docs.songco.de/ode/rows-and-settings/#lines). The stems are declared above the blocks with their sound and settings.
- Every row in a block holds the same number of bars, so bar 3 of the violin sits above bar 3 of the cello.
- `bars 5..8` is checked against the bars written. Bar numbers start at 1 in each section.
- A section's blocks must cover the whole section between them. A stem with no row in a block rests for those bars, the way an instrument does in a printed score.
- A stem may have two rows in one block, which sound together: a piano's right hand, then its left.
- A row can quote a [theme](https://docs.songco.de/ode/rows-and-settings/#themes), as it is or changed: `violin [1: theme | theme(up 2)]`. This is how a written piece develops an idea without writing every note again.

The two ways of writing mix freely. A track can keep its drums as grids and write its melody as a line.

## Names for things you reuse

```ode
let clave = rhythm [x..x ..x. ..x. x...]

phrase hook {
  line [g4/8 a4 c5/4 a4/8 g4 e4/4 | d4/2 r/2]
}

stem rim: wood { rim clave }
stem lead: sawlead { play hook }
stem brass: synthbrass {
  play hook
  octave 3
}
```

| word | what it gives |
|---|---|
| `let` | A named row that any stem can use. Change it once and every stem that uses it follows. A named `line` is a [theme](https://docs.songco.de/ode/rows-and-settings/#themes): other lines quote it, moved, cut, slowed or turned upside down. |
| `phrase` and `play` | A named musical idea, played by more than one instrument. |
| `group` | Stems under one level in the mix table. |

## What the app checks

A track is checked before you hear it, and every problem names its line.

- **Unknown is an error.** A word, a sound, a unit or a name the track does not define stops the track. Nothing is skipped in silence.
- **Every count is checked.** Steps in a bar, pitches in a bar, note lengths in a bar, bars in a section and marks in an arrange row all have to add up.
- **Every sound is in the [catalog](https://docs.songco.de/audio-engine/sounds/).**

See [errors](https://docs.songco.de/app/code/#errors) for what the messages look like.

## Tracks from earlier versions

A track made before ode does not start with `ode` and does not open. A file saved from an earlier version stays as it is on your disk.

---

This page on the web: https://docs.songco.de/ode/language/
Every page of the Songcode docs, for agents: https://docs.songco.de/llms.txt (index) and https://docs.songco.de/llms-full.txt (all of it in one file).
