Skip to content

Scales, Chords & Intervals

The names Scale(), Key(), chord(), interval() and chord literals accept. The functions and the Scale and Key types are in the std/theory reference.

Accepted by Scale(name), Key(root, name) and track.set_key(name, root). scale_names() returns the names, without the aliases.

ScaleAliasesNotesIntervals (semitones)Character
"major""ionian"70 2 4 5 7 9 11Bright, happy, resolved
"minor""aeolian"70 2 3 5 7 8 10Dark, melancholic
"dorian"—70 2 3 5 7 9 10Minor with a bright 6th
"phrygian"—70 1 3 5 7 8 10Spanish, exotic
"lydian"—70 2 4 6 7 9 11Dreamy, floating
"mixolydian"—70 2 4 5 7 9 10Bluesy major, rock
"locrian"—70 1 3 5 6 8 10Unstable, diminished
"harmonic_minor"—70 2 3 5 7 8 11Classical tension
"melodic_minor"—70 2 3 5 7 9 11Jazz minor
"pentatonic_major"—50 2 4 7 9Open, folk
"pentatonic_minor"—50 3 5 7 10Blues, rock riffs
"blues"—60 3 5 6 7 10Gritty, soulful
"whole_tone"—60 2 4 6 8 10Dreamlike, ambiguous
"chromatic"—120 1 2 3 4 5 6 7 8 9 10 11All semitones
assert scale_names().length() == 14;
assert Scale("pentatonic_minor").length() == 5;
print(Scale("ionian").intervals()); // [0, 2, 4, 5, 7, 9, 11] — the major scale

A custom scale is an interval array starting at 0 and strictly ascending; fractional values are microtonal. Scale(intervals, period) sets a repeat period other than 12 semitones. load_scala(name) reads a Scala .scl file.

Accepted by chord(root, quality), key.chord(degree, quality), and chord literals (C4:min7, ^2:min7). chord_names() returns the names.

A chord literal writes each quality by its short name (maj, min, 5 for major, minor, power). Literals also accept five shorthands that chord() and key.chord() do not: m (min), m7 (min7), m9 (min9), m6 (min6) and dom (dom7).

QualityAliasesNotesIntervals (semitones)Character
"major""maj"30 4 7Bright, stable
"minor""min"30 3 7Dark, melancholic
"dim"—30 3 6Tense, unstable
"aug"—30 4 8Bright, unsettled
"7""dom7"40 4 7 10Bluesy, wants to resolve
"maj7"—40 4 7 11Lush, jazzy
"min7"—40 3 7 10Smooth, mellow
"dim7"—40 3 6 9Dramatic, symmetrical
"aug7"—40 4 8 10Altered dominant
"sus2"—30 2 7Open, ambiguous
"sus4"—30 5 7Suspended, tense
"6""maj6"40 4 7 9Warm, vintage
"min6"—40 3 7 9Bittersweet
"9"—50 4 7 10 14Rich dominant
"maj9"—50 4 7 11 14Lush, expansive
"min9"—50 3 7 10 14Smooth, complex
"add9"—40 4 7 14Bright, open
"power""5"20 7Neutral, heavy
assert chord_names().length() == 18;
print(chord(C4, "min7")); // [C4, Eb4, G4, Bb4]
print(chord(C4, "power")); // [C4, G4]

An inversion (chord(root, quality, n), or ~n in a literal) moves the lowest n notes up an octave; a negative n moves the highest notes down.

Accepted by interval(note, name). Case matters: "M3" is a major third, "m3" a minor third.

NameAliasesIntervalSemitones
"m2"—Minor 2nd1
"M2"—Major 2nd2
"m3"—Minor 3rd3
"M3"—Major 3rd4
"P4"—Perfect 4th5
"tritone""TT"Tritone6
"P5"—Perfect 5th7
"m6"—Minor 6th8
"M6"—Major 6th9
"m7"—Minor 7th10
"M7"—Major 7th11
"P8""oct"Octave12
assert interval(C4, "P5") == G4;
assert interval(C4, "TT") == interval(C4, "tritone");
print(interval(C4, "m3")); // Eb4