Skip to content

Instantly share code, notes, and snippets.

@marcoonroad
Last active February 25, 2026 18:05
Show Gist options
  • Select an option

  • Save marcoonroad/d486b7f4704c324c04ac3c983332aceb to your computer and use it in GitHub Desktop.

Select an option

Save marcoonroad/d486b7f4704c324c04ac3c983332aceb to your computer and use it in GitHub Desktop.
Xenharmonic Chords (at 311EDO/TET) in Strudel REPL JS
const edo = 311
const semitones = Array.from(
{ length: edo },
(_, semitone) => semitone
)
const ratios =
semitones.map(ratio =>
Math.pow(2, ratio/edo))
const tail = pattern =>
pattern
.xen(ratios)
.sound("gm_synth_brass_2")
register('tail', tail)
const play = semitones =>
i(slowcat(...semitones))
.tail()
const harmonicRatios = divisor =>
Array.from({
length: divisor - 1
}, (_, dividend) =>
divisor + dividend + 1)
.map(dividend => dividend / divisor)
const closestSemitone = (ratio, edo) => {
if (Math.abs(ratio - 2) < 1e-10) {
return edo
}
var freq = 1200 * Math.log2(ratio)
var cents = 1200 / edo
var ideal = freq / cents
var close = Math.round(ideal)
close = Math.max(0, close)
close = Math.min(close, edo)
return close
}
const f = i => harmonicRatios(i).map(r =>
closestSemitone(r, edo))
// harmonic chords
const sm2 = f(2) // 3/2
const sm3 = f(3) // 4/3 ... 5/3
const sm4 = f(4) // 5/4 ... 7/4
const sm5 = f(5) // 6/5 ... 9/5
const sm6 = f(6) // 7/6 ... 11/6
$: stack(
play([ 0, 0, 0, 0, 0 ]),
play([ sm2[0], sm3[0], sm4[0], sm5[0], sm6[0] ]),
play([ sm2[0], sm3[1], sm4[1], sm5[1], sm6[1] ]),
play([ sm2[0], sm3[1], sm4[2], sm5[2], sm6[2] ]),
play([ sm2[0], sm3[1], sm4[2], sm5[3], sm6[3] ]),
play([ sm2[0], sm3[1], sm4[2], sm5[3], sm6[4] ]),
play([ edo, edo, edo, edo, edo ]),
).slow(2)
._pitchwheel({ edo: edo })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment