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. | 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:
ode- The plan:
title,tempo,meter,key,tuning,swing,loose,seed,allow,form,chords, then anyin <section> { }that changes the chords or key for a section. - Shared names:
letandphrase. arrange { }, when the track has more than one section.- The stems:
stem <name>: <sound> { rows, settings, blocks }. - Score blocks, when music is written a few bars at a time with every part together.
grouplines, thenmix { }.
#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.
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.
| 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 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 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
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.
xplays,.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 (
0dbis its catalog level) and pan from50LthroughCto50R,mute, group levels,duck … under …, the sharedreverb, and blocks (in,last … into,bar … of) with levels,ramp,sweep,fade in,fade out,mute, andmaster. Solo is a way of listening and stays out of the code. - let names a row any stem can use; a named
lineis a theme that lines quote astheme,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.