Skip to content

Chords (31EDO)

chords31(beats, scale, progression)

Returns a ChordPattern that steps through a chord progression in 31-tone equal temperament. All intervals are calculated in 31EDO steps; chord tones are not constrained to 12EDO semitones.

chords31(beats: number, scale: ScalePattern | string, progression: string): ChordPattern

The scale argument should come from scales31().

Progression format

Space- or comma-separated chord tokens:

'Ineu IVneu V^maj Ineu'

Each token has the form:

<Roman><microShift?><quality?><slash?>

Roman numerals

Uppercase only. I through VII.

Microtonal accidentals (microShift)

Written after the Roman numeral, before the quality. Multiple symbols accumulate.

SymbolStep changeCentsExample
^+1+39V^maj → V raised 39 cents
^^+2+77IV^^neu
v−1−39Iv → I lowered 39 cents
vv−2−77IIIvvmaj
#+5+194IVb#maj (chromatic sharp)
b−5−194IIIbneu (chromatic flat)

Symbols can be combined: Iv^ = −1 + 1 = net 0; IVb^ = −5 + 1 = −4 steps.

Chord qualities

Triads

QualityStepsSound
maj0, 10, 18Major (387 cent third)
min0, 8, 18Minor (310 cent third)
neu0, 9, 18Neutral (348 cent third) — exclusive to 31EDO
dim0, 8, 16Diminished
aug0, 10, 21Augmented

Seventh chords

QualityStepsSound
maj70, 10, 18, 28Major 7th
min70, 8, 18, 27Minor 7th
neu70, 9, 18, 27Neutral triad + neutral 7th
70, 10, 18, 27Dominant 7th (major triad + neutral 7th)

Omitting a quality gives a diatonic triad built from the current scale’s intervals.

Ties

~ or _ after a chord extends it by one step (same as chords()):

chords31(4, key, 'Ineu~~ Vmaj') // Ineu for 3 beats, Vmaj for 1

Octave shift

Append < (down) or > (up) to shift all chord tones by one octave (31 steps). Repeat for multiple octaves, or use <N> with a signed integer.

SyntaxOctaves
IVmaj<−1
IVmaj>+1
IVmaj<<−2
IVmaj<-2>−2 (explicit)

Compatible with microShift prefixes — ^^IVmaj< raises the root 2 steps and voices the chord one octave lower.

// Neutral chord voiced an octave lower for bass texture
const prog = chords31(4, key, 'Ineu IVneu< Vmaj Ineu')

Inversions & slash chords

Identical syntax to chords():

  • Imaj/1 — first inversion (bottom tone raised one octave)
  • Vmaj/I — V major over I bass

Examples

Basic neutral progression

const key = scales31(4, 'D4:neutral')
const prog = chords31(4, key, 'Ineu IVneu Vmaj Ineu')
yield cast(pad, prog, seq(4, '{0,2,4},~,~,~'), ctx)

Microtonal root inflection

// V^maj: dominant root raised 39 cents — adds upward pull before resolution
// IV^neu: subdominant root raised 39 cents with neutral quality — dreamlike colour
const progA = chords31(8, key, 'Ineu IVneu V^maj Ineu')
const progB = chords31(8, key, 'Imaj IV^neu Vvmaj Imaj')

Exposing the neutral third via arpeggio

When cast() uses a ChordPattern, sequence degree 1 is the chord’s third. With neu quality that third is the 31EDO-exclusive 348-cent interval:

// degree 0 = root, degree 1 = 3rd (neu/maj/min), degree 2 = 5th
yield cast(harp, prog, seq(8, '0,_,_,1,_,_,2,_'), ctx)

Alternating between Ineu and Imaj progressions makes the tuning difference clearly audible through this arpeggio.

Chromatic flat to reach a distant root

// IIIbneu: degree III (step 9 in neutral) shifted −5 steps → step 4
// Neutral triad built on that lowered root
chords31(8, key, 'Imaj IVmaj IIIbneu Vmaj')

Combining with scales31()

function* song(ctx) {
const c = ctx.cycle
const mode = Math.floor(c / 8) % 2 === 0 ? 'neutral' : 'major'
const key = scales31(8, `E4:${mode}`)
const prog = mode === 'neutral'
? chords31(8, key, 'Ineu IVneu V^maj Ineu')
: chords31(8, key, 'Imaj IV^neu Vvmaj Imaj')
yield cast(strings({ attack: 1.4, gain: 0.20 }), prog,
seq(8, '{0,2,4},~,~,~,~,~,~,~'), ctx)
}

See the Dusk Gate preset for a complete working example.