Skip to content

std/theory

Always in scope — no import required.

Scales, keys, chords, and interval helpers.

A Key — a Scale rooted at a note, for scale-relative composition. All rooted operations (degrees, diatonic chords, quantize) live here. Construct with Key(root, name) or Key(root, scale). Access the underlying Scale with k.scale, the root with k.root, and the scale name with k.name.

Example:

Key(D4, "dorian") or Key(D4, Scale(#[0, 2, 3.5, 5, 7, 8.5, 10])).

fn Key(root: Note or Number, name: String or Scale) -> Key

Creates a Key value for scale-relative composition. Methods: degree(n), chord(deg), chord7(deg), notes(), quantize(note), transpose(semitones).

Example:

Key(D4, "dorian") or Key(D4, Scale(#[0, 2, 3, 5, 7, 9, 10])).

Parameters:

  • root (Note | Number) — root note (e.g. D4 or a MIDI number)
  • name (String | Scale) — scale name (see scale_names()) or a Scale value

Returns: Key — the constructed key

fn degree(n: Number) -> Note

Returns the Note at the given scale degree. Degrees are 1-indexed; degrees > scale length wrap up an octave. Non-positive degrees go below the root: 0 = one step below, -1 = two below.

Parameters:

  • n (Number) — scale degree (1 = root, 5 = fifth, 8 = root + octave, etc.)

Returns: Note — the note at that scale degree

fn chord(deg: Number, quality: String or Number?, inv: Number?) -> Array

Returns a chord (array of Notes) built on the given scale degree. With only deg: the diatonic triad. The optional second argument is either a chord-quality String (e.g. “min7”) or an inversion Number. A third argument adds an inversion to an explicit quality.

Example:

k.chord(1), k.chord(1, 1), k.chord(1, "min7").

Parameters:

  • deg (Number) — scale degree (1-indexed, >= 1)
  • quality (String | Number) — chord quality String, OR an inversion Number (optional)
  • inv (Number) — inversion to apply when quality is given (optional)

Returns: Array — the chord as an array of Notes

fn chord7(deg: Number, inv: Number?) -> Array

Returns a diatonic 7th chord (4 Notes) on the given scale degree.

Parameters:

  • deg (Number) — scale degree (1-indexed, >= 1)
  • inv (Number) — inversion to apply (optional)

Returns: Array — the 7th chord as an array of four Notes

fn notes() -> Array

Returns one octave of the key’s scale as an array of Notes (rooted).

Returns: Array — one octave of the scale as rooted Notes

fn quantize(note: Note or Number) -> Note

Snaps a note to the nearest tone in this key’s scale.

Parameters:

  • note (Note | Number) — the note (or MIDI number) to quantize

Returns: Note — the nearest in-scale note

fn transpose(semitones: Number) -> Key

Returns a new Key with the root shifted by the given semitones.

Parameters:

  • semitones (Number) — semitones to shift (positive or negative)

Returns: Key — a new key with the shifted root

A musical scale — a rootless, ordered set of pitch intervals. Construct with Scale("name") for built-in scales, or Scale(#[0, 2, 4, 5, 7, 9, 11]) from a semitone array. Microtonal scales use fractional semitones: Scale(#[0, 1.5, 3.5, 5, 7, 8.5, 10]). Pass a Scale to Key(root, scale) or track.key(scale, root) to play it.

fn Scale(arg: String or Array, period: Number = NUL) -> Scale

Creates a Scale value, optionally with a custom period.

Examples:

  • Scale("minor"), Scale(#[0, 2, 3, 5, 7, 8, 10]),
  • Scale(#[0, 2, 4, 5, 7, 9, 11], 19).

Parameters:

  • arg (String | Array) — scale name (e.g. “major”, “dorian”) or an array of semitone intervals (must start with 0 and be strictly ascending, e.g. #[0, 2, 4, 5, 7, 9, 11])
  • period (Number) — period in semitones (optional; e.g. 19 for 19-TET). Use a non-12 period for non-octave tunings; only valid with an array arg.

Returns: Scale — the constructed scale

fn name() -> String

Returns the scale’s name.

Returns: String — the scale name

fn intervals() -> Array

Returns the interval array (semitones from root).

Returns: Array — the semitone intervals from the root

fn period() -> Number

Returns the period in semitones (12 for a standard octave).

Returns: Number — the period in semitones

fn length() -> Number

Returns the number of scale degrees.

Returns: Number — the number of degrees in the scale

fn mode(n: Number) -> Scale

Returns a new Scale rotated to the nth mode (1-indexed).

Example:

Scale("major").mode(2) returns the dorian mode.

Parameters:

  • n (Number) — mode index (1-indexed)

Returns: Scale — the scale rotated to the nth mode

fn contains(semitones: Number) -> Boolean

Returns true if the scale contains the given interval (in semitones).

Parameters:

  • semitones (Number) — interval from the root, in semitones

Returns: Boolean — true if the interval is in the scale

fn chord(root: Note or Number, name: String, inversion: Number = NUL) -> Array

Returns an array of Notes forming a chord, optionally inverted.

Examples:

  • chord(C4, "min7") returns [C4, Eb4, G4, Bb4];
  • chord(C4, "major", 1) returns [E4, G4, C5] (1st inversion)

Parameters:

  • root (Note | Number) — root note (e.g. C4 or a MIDI number)
  • name (String) — chord name: “major”, “minor”, “dim”, “aug”, “7”, “maj7”, “min7”, “dim7”, “aug7”, “sus2”, “sus4”, “6”, “min6”, “9”, “maj9”, “min9”, “add9”, “power”
  • inversion (Number) — inversion (optional): positive = classical inversion (raise lowest notes), negative = drop voicing (lower highest notes)

Returns: Array — the chord as an array of Notes

fn chord_names() -> Array

Returns an array of all available chord names.

Returns: Array — the built-in chord names as Strings

fn interval(note: Note or Number, name: String) -> Note

Returns a single Note at the given interval above the input note.

Example:

interval(C4, "P5") returns G4

Parameters:

  • note (Note | Number) — starting note (e.g. C4 or a MIDI number)
  • name (String) — interval name: “m2”, “M2”, “m3”, “M3”, “P4”, “tritone” (“TT”), “P5”, “m6”, “M6”, “m7”, “M7”, “P8” (“oct”)

Returns: Note — the note that interval above note

fn load_scala(name: String) -> Scale

Load a Scala (.scl) tuning file and return a Scale value. Searches: relative to source file, ~/.resonon/scales/, bundled scales. The .scl extension is optional.

Example:

load_scala("maqam/rast"), load_scala("my_scale.scl")

Parameters:

  • name (String) — Scala file name or path (.scl extension optional)

Returns: Scale — the scale loaded from the tuning file

fn scale_names() -> Array

Returns an array of all available scale names.

Returns: Array — the built-in scale names as Strings