# ode reference

> All of ode on one page, for a person or an agent who wants the whole language in one read. How it is written, every statement, every row, every setting and every sound name, with two complete tracks.

ode is Songcode's language for a song: plain text that the Songcode Audio Engine reads, checks and plays. This page is the whole of ode, kept short. Each part links to the page that explains it at length. The same page as Markdown is at `https://docs.songco.de/ode/reference/index.md`.

## How it is written

| piece | rule | example |
|---|---|---|
| first line | `ode`, or `ode` and a version. Anything else does not open. The current version is 0.3.0; see [versions](https://docs.songco.de/ode/versions/). | `ode` |
| statement | A word, then its values, to 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` `12st` `20cents` |
| detail | Follows a setting after a comma, as `name: value`. | `reverb 40%, decay: 6s` |
| name | Lowercase letters, digits and `_`. Used once each. | `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: no loops, no conditions, no functions. Unknown is an error. A word, sound, unit or name the track does not define stops it with a message naming the line, and every count (steps in a bar, note lengths in a bar, bars in a section, marks in an arrange row) has to add up.

## How a track is laid out

Songcode writes its tracks in this order, top to bottom, and it reads best that way:

1. `ode`
2. The plan: `title`, `tempo`, `meter`, `key`, `tuning`, `swing`, `loose`, `seed`, `allow`, `form`, `chords`, then any `in <section> { }` that changes the chords or key for a section.
3. Shared names: `let` and `phrase`.
4. `arrange { }`, when the track has more than one section.
5. The stems: `stem <name>: <sound> { rows, settings, blocks }`.
6. Score blocks, when music is written a few bars at a time with every part together.
7. `group` lines, then `mix { }`.

## The plan

| statement | sets |
|---|---|
| `title "glass elevator"` | The name. |
| `tempo 126` | Beats a minute. A beat is a quarter note, or a dotted quarter in 6/8, 9/8 and 12/8. |
| `meter 3/4` | Time signature. Default 4/4. Odd meters name their grouping: `meter 7/8, beats: 2+2+3`. |
| `key f minor` | Tonic and scale. Scale steps and chord tones are read from it. |
| `tuning e -50cents, b -50cents` | Moves those notes, in every octave, up to 100 cents either way. |
| `swing 54%` | The track's swing. |
| `loose 8ms` | How far each note may land from the grid. |
| `seed 7` | What `chance`, `humanize` and `loose` draw from. Same seed, same track, every time. |
| `allow range` | Lets every stem break one of the playability rules: `range`, `reach`, `hands`, `breath`, `speed` or `all`. |
| `form intro 8, verse 16, chorus 8` | The sections in order, with their lengths in bars. `form loop 8` is a loop. A name used twice is the same section played again; `chorus 2` is its second time. |
| `chords [Fm9 \| % \| Dbmaj7 \| Eb6]` | The chord chart. `\|` ends a bar, `%` repeats the bar before, chords in one bar split it evenly, `-` holds. It repeats for as long as its section lasts. |

Scales: minor, major, dorian, phrygian, lydian, mixolydian, locrian, harmonic minor, melodic minor, minor pentatonic, major pentatonic, blues, whole tone, chromatic. A wider set for jazz and for scales from outside the western seven is listed in [the song format](https://docs.songco.de/ode/language/#the-plan).

[The song format](https://docs.songco.de/ode/language/#the-plan) has the rest.

## Stems

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

A stem is one instrument: `stem`, a name, a colon, a sound, and a block. Every stem is a stem in the [stems view](https://docs.songco.de/app/stems/) and in the export. The app reads a role from the name: kick, snare, clap, hats, perc, bass, sub, chords, stab, lead, arp, pad, vocal, texture, fx. A stem carries its music one of three ways.

| way | rows | for |
|---|---|---|
| lanes | One row per drum on a kit: `kick` `snare` `clap` `hat` `openhat` `rim` `cowbell` `lowtom` `midtom` `hightom` `crash` `ride` `shaker` `tambourine`. | drums |
| rhythm and pitch | `rhythm` says when, and one of `notes`, `degrees` or `tones` says what. | basslines, stabs, pads, arpeggios |
| line | `line` writes each note with its length. | melodies, anything note by note |

### Step rows

Sixteen steps to a bar in 4/4. Spaces only help the eye.

| mark | means |
|---|---|
| `x` | hit |
| `X` | accent, 1.3 times as hard |
| `o` | ghost, a little under half as hard |
| `f` | flam |
| `.` | rest |
| `-` | hold the note before |
| `2` to `8` | that many hits in the step, a roll |
| `%` | the bar before again |

### Pitch rows

| row | holds | example |
|---|---|---|
| `notes` | Note names with octave. `eb` is E flat, `f#` is F sharp. | `[c2 eb2 f#3]` |
| `degrees` | Steps of the key's scale. `8` is the octave, `b7` the lowered seventh. | `[1 3 5 b7 8]` |
| `tones` | Notes of the chord the chart is on. `root`, `all`, or numbers counted from the root. | `[root]` `[all]` `[1 2 3]` |

A pitch row is read hit by hit against the rhythm and loops. A stem on `tones` follows the chord chart, so changing a chord changes every stem that reads it.

### Lines

| mark | means |
|---|---|
| `c4/4` | Pitch, then length: `/1` `/2` `/4` `/8` `/16` `/32`. |
| `/4.` | A dot adds half. |
| `/12` `/6` `/24` | Triplet 8th, quarter and 16th. |
| `e4` | No length: the same as the note before. |
| `r/4` | Rest. |
| `c4+e4+g4/2` | Chord. |
| `~` | Tie to the next note, or slide when the pitch changes. |
| `'` `_` `!` | Staccato, held full length, accent. |
| `(c5/8 d5 e5)` | Slur: one bow or one breath. |
| `d5/g` | Grace note, taking no room in the bar. |
| `g5/2:trill` | Ornament: `:trill` `:mordent` `:turn` `:roll` `:bend` `:fall` `:slide`. |
| `pp` `p` `mp` `mf` `f` `ff`, `<` `>` | Dynamics and hairpins, standing between notes. |
| `pizz` `arco` `stacc` `marc` | Ways and styles of playing, standing between notes until the next one. |
| `5:` | A bar number at the start of a bar, checked. |

Each bar of a line has to add up to a whole bar. [Rows and settings](https://docs.songco.de/ode/rows-and-settings/#lines) covers ways and styles of playing and themes.

### Settings

One value each, except `velocity` and `take`, which take a looping list. Any value can move with `ramp(a, b)` across the block it sits in, or `sweep(a, b, every: 8bars)` there and back.

| group | settings |
|---|---|
| notes | `velocity 96` `octave 3` `transpose 12st` `chance 90%` `pulse 20%` `humanize 8` `loose 10ms` `vary 100%` `length 50%` `glide 60ms` `behind 8ms` `ahead 4ms` `choke hats` `take 3` `voicing open` `straight` `legato` `overlap 60ms` `bow 40%` `breath 40%` `strum 20ms` `pedal chord` `technique pizzicato` `allow breath` |
| voicing | `close` `rootless` `open` `wide` `shell` `smooth` |
| envelope | `attack 400ms` `decay 200ms` `sustain 60%` `release 1.5s` |
| filter | `lowpass 700hz` `highpass 240hz` `bandpass 1.2khz`, with `resonance: 30%` and `contour: 3oct` |
| tone | `voices 5` `detune 20cents` `fm 4, ratio: 2` `vibrato 5hz, depth: 30cents` `tremolo 4hz, depth: 40%` `vowel a` `chorus 40%, rate: 0.8hz` `phaser 0.5hz, depth: 60%` |
| tone controls | `lowshelf 120hz, gain: -3db` `highshelf 8khz, gain: 2db` `bell 2khz, gain: -3db, width: 1oct` |
| dirt and space | `drive 40%` `bitcrush 8bits` `reverb 40%` (or `reverb 40%, decay: 2s, tone: 4khz` for a room of its own) `delay 25%, time: 3/16, feedback: 40%` |
| moves | `fade in` `fade out` `trim -3db` |

Level and pan are never set in a stem. They live in the mix table.

[Rows and settings](https://docs.songco.de/ode/rows-and-settings/#settings) says what each one does.

## Blocks inside a stem

| block | covers |
|---|---|
| `in intro, outro { }` | Those sections. `in verse 2 { }` is the second verse only. |
| `last 1bar into main, peak { }` | The last bar before those sections. Fills, drops, a bar of silence. |
| `last 2bars into end { }` | The last bars of the track. |
| `bar 8 of 8 { }` `bars 7..8 of 8 { }` | Those bars of every 8. |

A block holds rows and settings that replace the stem's own there, or a move: `silent`, `ratchet 2`, `halftime`, `doubletime`, `reverse`, `shift 2`, `transpose 12st`, `octave 5`. The most specific block wins: `last … into`, then `bar … of`, then `in`, then the stem.

## Arrange, mix and names

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

group drums: kick, clap, hats

mix {
  kick   0db
  hats   -10db, pan: 15R
  pad    -11db, mute
  drums  -1db
  duck bass, pad under kick, depth: 75%, recover: 110ms
  reverb decay: 1.8s, tone: 5khz
  in verse {
    pad  ramp(-18db, -11db)
  }
  last 4bars into end {
    master  fade out
  }
}
```

- **arrange**: one row per stem, one column per section in form order. `x` plays, `.` rests, a number plays only the last that many bars. A stem with no row plays throughout. A loop needs none.
- **mix**: each stem's level in dB (`0db` is its catalog level) and pan from `50L` through `C` to `50R`, `mute`, group levels, `duck … under …`, the shared `reverb`, and blocks (`in`, `last … into`, `bar … of`) with levels, `ramp`, `sweep`, `fade in`, `fade out`, `mute`, and `master`. Solo is a way of listening and stays out of the code.
- **let** names a row any stem can use; a named `line` is a theme that lines quote as `theme`, `theme(up 2)`, `theme(inverted)`, `theme(first 1bar)`. **phrase** and **play** share one musical idea between stems. **group** puts stems under one level.

## Lyrics and score

A singer is a sound like any other. Its words go in a `lyrics` block, one syllable per note: `lyrics 2bars { "the river keeps its name" }`. `-` splits a word into syllables, `_` holds one, `/k.ae.t/` spells phonemes, and a line of `~` is silent. Lyrics are English.

A `score a bars 1..4 { violin [1: …] cello [1: …] }` block writes every part together, a few bars at a time. Every row in it holds the same bars, and a section's score blocks cover the whole section.

[The song format](https://docs.songco.de/ode/language/#lyrics) has both in full.

## Sound names

Every name a stem may use. A name not listed here is an error. [Sounds](https://docs.songco.de/audio-engine/sounds/) says what each one sounds like and its range.

**Drum kits**, with all 14 lanes:

`analog`, `hard`, `sub`, `fm`, `live`, `rock`, `brush`

**More kits**, each with its own set of drums:

`club`, `boom`, `tight`, `sharp`, `lofi`, `arena`, `round`, `funk`, `grit`, `warm`, `clean`, `studio`, `bright`, `rave`, `crunch`, `laser`, `soft`, `wood`

**Bass**:

`subbass`, `reese`, `acid`, `acidsq`, `pulsebass`, `fmbass`, `fatbass`, `wobble`, `boombass`, `organbass`, `fingerbass`, `upright`, `hoover`, `donk`, `growl`, `logdrum`

**Leads and stabs**:

`sawlead`, `hypersaw`, `squarelead`, `chip`, `synthpluck`, `stab`, `synthbrass`, `fmbell`, `glass`, `gfunk`, `whistle`, `zap`, `blip`

**Keys**:

`epiano`, `reedpiano`, `organ`, `houseorgan`, `clav`, `celesta`

**Pads**:

`warmpad`, `ensemble`, `glasspad`, `choir`, `ooh`, `darkpad`, `airpad`, `dubchord`

**Plucked strings**:

`nylon`, `steel`, `koto`, `pizz`, `mutegtr`, `harpsichord`

**Transitions**:

`riser`, `downer`, `impact`, `subdrop`

**Singers**:

`soprano`, `alto`, `tenor`, `baritone`, `robot`, `whisper`

**Oscillators and noise**:

`sawtooth`, `square`, `triangle`, `sine`, `pulse`, `supersaw`, `white`, `pink`, `brown`, `crackle`

**Recorded instruments**:

`piano`, `upright_piano`, `fm_piano`, `kalimba`, `marimba`, `vibraphone`, `xylophone`, `glockenspiel`, `balafon`, `harp`, `sax`, `sax_stacc`, `harmonica`, `electric_bass`, `powerchord`, `palmmute`, `crunch_guitar`, `violins`, `violas`, `contrabass`, `double_bass`, `bassoon`, `piccolo`, `tuba`, `recorder`, `ocarina`, `tubular_bells`, `dan_tranh`

**Percussion**, one `rhythm` row and no pitches:

`conga`, `bongo`, `cajon`, `darbuka`, `framedrum`, `timpani`, `slitdrum`, `clave`, `woodblock`, `cowbell`, `agogo`, `cabasa`, `guiro`, `tambourine`, `triangles`, `sleighbells`, `vibraslap`, `ratchet`, `gong`, `sus_cymbal`, `anvil`, `brakedrum`, `fingercymbal`, `marktrees`, `oceandrum`, `siren`, `slapstick`, `flexatone`, `clap`, `didgeridoo`

**Textures**:

`wind`, `space`, `metal`, `insect`, `crow`, `thunder`

**Ambience**:

`rain`, `vinyl`, `tape`, `birds`, `crickets`, `stream`, `waves`, `fire`

**General MIDI instruments**:

`trumpet`, `muted_trumpet`, `trombone`, `french_horn`, `brass_section`, `flute`, `pan_flute`, `shakuhachi`, `clarinet`, `oboe`, `violin`, `cello`, `string_ensemble_1`, `tremolo_strings`, `choir_aahs`, `voice_oohs`, `accordion`, `church_organ`, `steel_drums`, `music_box`, `sitar`, `banjo`, `koto`, `electric_guitar_clean`, `electric_guitar_jazz`, `overdriven_guitar`, `distortion_guitar`, `slap_bass_1`, `fretless_bass`, `taiko_drum`, `orchestra_hit`, `reverse_cymbal`, `pad_warm`, `pad_halo`

## A whole loop

```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
}
```

## A whole full track

```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)
  }
}
```

## Check what you wrote

The Songcode Studio checks a track every time it changes and names the line of every problem; see [errors](https://docs.songco.de/app/code/#errors). Over MCP, `check_code` returns the same check, line by line, with nothing saved. See [for agents](https://docs.songco.de/agents/).

---

This page on the web: https://docs.songco.de/ode/reference/
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).
