songcodedocs open songcode

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

pieceruleexample
first lineode, or ode and a version. Anything else does not open. The current version is 0.3.0; see versions.ode
statementA word, then its values, to the end of the line.tempo 126
blockA statement that opens { and holds statements until }.stem bass: fmbass { }
rowMusic between [ and ]. `\` ends a bar. A row may run over several lines.[x... x... x... x...]
quantityA number with its unit attached, no space.400hz 8ms -6db 30% 16bars 12st 20cents
detailFollows a setting after a comma, as name: value.reverb 40%, decay: 6s
nameLowercase letters, digits and _. Used once each.bass verse_2
textIn 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

statementsets
title "glass elevator"The name.
tempo 126Beats a minute. A beat is a quarter note, or a dotted quarter in 6/8, 9/8 and 12/8.
meter 3/4Time signature. Default 4/4. Odd meters name their grouping: meter 7/8, beats: 2+2+3.
key f minorTonic and scale. Scale steps and chord tones are read from it.
tuning e -50cents, b -50centsMoves those notes, in every octave, up to 100 cents either way.
swing 54%The track’s swing.
loose 8msHow far each note may land from the grid.
seed 7What chance, humanize and loose draw from. Same seed, same track, every time.
allow rangeLets every stem break one of the playability rules: range, reach, hands, breath, speed or all.
form intro 8, verse 16, chorus 8The 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.

The song format has the rest.

#Stems

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 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.

wayrowsfor
lanesOne row per drum on a kit: kick snare clap hat openhat rim cowbell lowtom midtom hightom crash ride shaker tambourine.drums
rhythm and pitchrhythm says when, and one of notes, degrees or tones says what.basslines, stabs, pads, arpeggios
lineline 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.

markmeans
xhit
Xaccent, 1.3 times as hard
oghost, a little under half as hard
fflam
.rest
-hold the note before
2 to 8that many hits in the step, a roll
%the bar before again

#Pitch rows

rowholdsexample
notesNote names with octave. eb is E flat, f# is F sharp.[c2 eb2 f#3]
degreesSteps of the key’s scale. 8 is the octave, b7 the lowered seventh.[1 3 5 b7 8]
tonesNotes 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

markmeans
c4/4Pitch, then length: /1 /2 /4 /8 /16 /32.
/4.A dot adds half.
/12 /6 /24Triplet 8th, quarter and 16th.
e4No length: the same as the note before.
r/4Rest.
c4+e4+g4/2Chord.
~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/gGrace note, taking no room in the bar.
g5/2:trillOrnament: :trill :mordent :turn :roll :bend :fall :slide.
pp p mp mf f ff, < >Dynamics and hairpins, standing between notes.
pizz arco stacc marcWays 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 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.

groupsettings
notesvelocity 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
voicingclose rootless open wide shell smooth
envelopeattack 400ms decay 200ms sustain 60% release 1.5s
filterlowpass 700hz highpass 240hz bandpass 1.2khz, with resonance: 30% and contour: 3oct
tonevoices 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 controlslowshelf 120hz, gain: -3db highshelf 8khz, gain: 2db bell 2khz, gain: -3db, width: 1oct
dirt and spacedrive 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%
movesfade in fade out trim -3db

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

Rows and settings says what each one does.

#Blocks inside a stem

blockcovers
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

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 has both in full.

#Sound names

Every name a stem may use. A name not listed here is an error. 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
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
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. Over MCP, check_code returns the same check, line by line, with nothing saved. See for agents.

esc