diff options
| -rw-r--r-- | scale.mjs | 23 |
1 files changed, 19 insertions, 4 deletions
@@ -8,6 +8,16 @@ export const chromaticScale = new Proxy( ['A', 'A♯', 'B', 'C', 'C♯', 'D', 'D♯', 'E', 'F', 'F♯', 'G', 'G♯'], ringHandler); +function notesBetween(a, b) { + const [tonicA, tonicB] = [a[0], b[0]] + const abs = tonicB.charCodeAt() - tonicA.charCodeAt(); + if (abs < 0) { + return abs + 7; + } else { + return abs; + } +} + function scaleFromIntervals(tonic, intervals) { const scaleIndex = chromaticScale.indexOf(tonic); if (scaleIndex < 0) { @@ -23,14 +33,19 @@ function scaleFromIntervals(tonic, intervals) { const note = chromaticScale[scaleIndex + steps]; // don't display two base notes in a row by changing // accidentals. - if (note[0] === lastBase) { + const delta = notesBetween(lastBase, note); + if (delta === 0) { const nextBase = chromaticScale[scaleIndex + steps + 1][0]; scale.push(`${nextBase}♭`) - lastBase = nextBase[0]; + } else if (delta === 1) { + scale.push(`${note}`) } else { - scale.push(note); - lastBase = note[0]; + // we can only be two away, so take the sharp of the + // previous note. + const nextBase = chromaticScale[scaleIndex + steps - 1][0]; + scale.push(`${nextBase}♯`) } + lastBase = scale[scale.length-1]; } return new Proxy(scale, ringHandler); } |
