Usage:
"<I7 [ii7:V V7:V] V7 [ii7 V7]>"
.roman("d:major")
.chord()
.voicing()
.sound("piano")| const romanNumerals = ['i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii']; | |
| function romanToIndex(s) { | |
| for (let index = romanNumerals.length - 1; index >= 0; index--) { | |
| const numeral = romanNumerals[index]; | |
| if (s.startsWith(numeral)) { | |
| return { index, isMinor: true, suffix: s.substring(numeral.length) }; | |
| } else if (s.startsWith(numeral.toUpperCase())) { | |
| return { index, isMinor: false, suffix: s.substring(numeral.length) }; | |
| } | |
| } | |
| } | |
| register('roman', function (scaleName, pat) { | |
| return pat.as("roman1:roman2").fmap(({ roman1, roman2 }) => { | |
| let targetScale = scaleName; | |
| if (roman2) { | |
| const { index, isMinor } = romanToIndex(roman2); | |
| targetScale = n(index).scale(scaleName).fmap(({ note }) => note + ':' + (isMinor ? 'minor' : 'major')); | |
| } | |
| const { index, isMinor, suffix } = romanToIndex(roman1); | |
| return n(index).scale(targetScale).fmap(({ note }) => { | |
| return note.slice(0, -1) + (isMinor ? 'm' : '') + suffix; | |
| }); | |
| }).outerJoin(); | |
| }); |
Usage:
"<I7 [ii7:V V7:V] V7 [ii7 V7]>"
.roman("d:major")
.chord()
.voicing()
.sound("piano")