Skip to content
learn

Lesson 11: Modes in depth

Lesson 2 turned the major scale into seven modes. This lesson does the same with two other seven-note scales, melodic minor and harmonic minor, whose modes give jazz most of its dominant scales. Then it ranks modes from bright to dark, and asks what a modal family is. Guitar Alchemist (GA) answers in five places: generic mode classes, an interface that names scale degrees, three brightness measures, a service that ranks modes, and a configuration file of 165 modes. The course program checks each one, and runs GA’s own code wherever it can.

All GA links point to commit a826864. The outputs come from the command below; the entry point is l13.

Terminal window
dotnet run --project code/music-theory-ga/GaTheory -c Release -- l13

Wikipedia: “A great deal of modern jazz harmony arises from the modes of the ascending form of the melodic minor scale, also known as the jazz melodic minor scale. This scale is essentially a diatonic major scale with a lowered third, for example A-B-C-D-E-F♯-G♯-A” (Jazz scale). Its steps are 2 1 2 2 2 2 1 (lesson 2), and its modes are the rotations of those steps. The same article names them and gives each the chord it goes with: Dorian ♭2, Lydian augmented, Lydian dominant (also called the acoustic scale), Mixolydian ♭6, Locrian ♮2 (it lists “Half-diminished, Locrian ♯2, or Aeolian ♭5”) and the altered scale, or Super Locrian. Lydian dominant goes with “C7 (9, ♯11, 13)” and the altered scale with “C7 (♭9 or ♯9, ♯11, ♭13)”: two ways to color a dominant seventh.

Open Music Theory builds chord-scales from the modes of major, then adds: “A similar approach to the one above can be used to derive more chord-scale relationships from the melodic minor, harmonic minor, and harmonic major modes” (Open Music Theory, “Chord-Scale Theory”). The Streeling module MUS-005 · Jazz Harmony for Guitar does it in section 6, “Chord-Scale Theory”: V7♯11 takes Lydian dominant and V7alt the altered scale, both from “The Melodic Minor Mother Scale”.

The course writes each mode with lesson 2’s notation: each degree compared with the major scale, > on a degree that differs from the reference mode (Aeolian when the third is minor, Ionian otherwise), and ♮ on a degree the reference lowers (Lesson13.Formula).

MelodicMinorMode is a mode of Scale.MelodicMinor, which is new("A B C D E F# G#") (Scale.cs#L116-L121). As with the major modes of lesson 2, its notes are the list of notes rotated, and its formula is GA’s ModeFormula. Its name comes from its degree: MelodicMinorScaleDegree.ToName. The program builds the three tables with one generic method, which takes any of GA’s mode classes (Lesson13.ModeTable):

== The modes of melodic minor: GA's ModeFormula against the course's, from the steps 2 1 2 2 2 2 1
mode course GA check
melodic minor 1 2 b3 4 5 >♮6 >♮7 1 2 b3 4 5 >♮6 >♮7 ok
Dorian ♭2 1 >b2 b3 4 5 >♮6 b7 1 >b2 b3 4 5 >♮6 b7 ok
Lydian augmented 1 2 3 >♯4 >♯5 6 7 1 2 3 >♯4 >♯5 6 7 ok
Lydian dominant 1 2 3 >♯4 5 6 >b7 1 2 3 >♯4 5 6 >b7 ok
Mixolydian ♭6 1 2 3 4 5 >b6 >b7 1 2 3 4 5 >b6 >b7 ok
Locrian ♮2 1 2 b3 4 >b5 b6 b7 1 2 b3 4 >b5 b6 b7 ok
altered 1 >b2 b3 >b4 >b5 b6 b7 1 >b2 b3 >b4 >b5 b6 b7 ok
notes course GA check
melodic minor A B C D E F# G# A B C D E F# G# ok
Dorian ♭2 B C D E F# G# A B C D E F# G# A ok
Lydian augmented C D E F# G# A B C D E F# G# A B ok
Lydian dominant D E F# G# A B C D E F# G# A B C ok
Mixolydian ♭6 E F# G# A B C D E F# G# A B C D ok
Locrian ♮2 F# G# A B C D E F# G# A B C D E ok
altered G# A B C D E F# G# A B C D E F# ok
textbook name GA's Name
melodic minor Melodic Minor
Dorian ♭2 Dorian b2
Lydian augmented Lydian Augmented
Lydian dominant Lydian Dominant
Mixolydian ♭6 Mixolydian b6
Locrian ♮2 Locrian Natural 2
altered Altered

GA agrees on all seven formulas and all seven spellings, and its names are the textbook’s, written in ASCII. The names say what the formulas show: each mode is a mode of major with one or two degrees moved. The altered scale on G♯ lowers almost everything, and its ♭4, C, is B♯ in disguise: the major third of G♯7.

Wikipedia: “A harmonic minor scale can be built by lowering the 3rd and 6th degrees of the parallel major scale by one semitone”, and its steps are “whole, half, whole, whole, half, augmented second, half” (Harmonic minor scale): 2 1 2 2 1 3 1. Its table of modes, on A: harmonic minor, Locrian ♮6, Ionian ♯5 (“augmented major”), Dorian ♯4 (also Romanian minor), Phrygian dominant, Lydian ♯2, and a seventh mode it calls “Super-Locrian scale” with a doubly flattened seventh, “or altered diminished, Ultralocrian”. Phrygian dominant is the mode of the fifth degree, the one a minor key’s V7 colors: the article gives it “A7 (♭9, 11, ♭13)”.

The augmented second shows in the formulas. The seventh mode, on G♯, is the altered scale with its seventh lowered once more: from G♯ to F is a diminished seventh, so the course writes ♭♭7.

HarmonicMinorMode is a mode of Scale.HarmonicMinor, new("A B C D E F G#"), named by HarmonicMinorScaleDegree.ToName. The same method prints it:

== The modes of harmonic minor: GA's ModeFormula against the course's, from the steps 2 1 2 2 1 3 1
mode course GA check
harmonic minor 1 2 b3 4 5 b6 >♮7 1 2 b3 4 5 b6 >♮7 ok
Locrian ♮6 1 >b2 b3 4 >b5 >♮6 b7 1 >b2 b3 4 >b5 >♮6 b7 ok
Ionian ♯5 1 2 3 4 >♯5 6 7 1 2 3 4 >♯5 6 7 ok
Dorian ♯4 1 2 b3 >♯4 5 >♮6 b7 1 2 b3 >♯4 5 >♮6 b7 ok
Phrygian dominant 1 >b2 3 4 5 >b6 >b7 1 >b2 3 4 5 >b6 >b7 ok
Lydian ♯2 1 >♯2 3 >♯4 5 6 7 1 >♯2 3 >♯4 5 6 7 ok
altered ♭♭7 1 >b2 b3 >b4 >b5 b6 >bb7 1 >b2 b3 >b4 >b5 b6 >bb7 ok
notes course GA check
harmonic minor A B C D E F G# A B C D E F G# ok
Locrian ♮6 B C D E F G# A B C D E F G# A ok
Ionian ♯5 C D E F G# A B C D E F G# A B ok
Dorian ♯4 D E F G# A B C D E F G# A B C ok
Phrygian dominant E F G# A B C D E F G# A B C D ok
Lydian ♯2 F G# A B C D E F G# A B C D E ok
altered ♭♭7 G# A B C D E F G# A B C D E F ok
textbook name GA's Name
harmonic minor Harmonic Minor
Locrian ♮6 Locrian Natural 6
Ionian ♯5 Ionian Augmented
Dorian ♯4 Dorian Sharp 4
Phrygian dominant Phrygian Dominant
Lydian ♯2 Lydian Sharp 2
altered ♭♭7 Altered bb7

Seven out of seven again, double flat included. GA calls the seventh mode “Altered bb7”, Wikipedia’s “Super-Locrian” with a doubly flattened seventh.

A mode is a scale plus a degree of it. In harmony, a Roman numeral names a degree by the triad built on it (lesson 6): upper case for major, lower case for minor, ° for diminished, + for augmented. On the fourth degree of A harmonic minor, D F A is minor: iv. On the fourth degree of A melodic minor, D F♯ A is major: IV. The course writes the triads of each scale this way (Lesson13.TriadNumerals).

GA makes the pair literal: ScaleMode<TScaleDegree> is generic over the type of the degree, and each scale has its own: MajorScaleDegree, NaturalMinorScaleDegree, HarmonicMinorScaleDegree, MelodicMinorScaleDegree, HarmonicMajorScaleDegree and fifteen more, each a value from 1 to the scale’s size that checks its range. It is the “smart enum” pattern: a type per kind of degree, with behavior attached, so a melodic minor degree cannot be passed where a major one is expected. Each type names its degrees through IScaleDegreeNaming: ToName() returns “the full name of the scale degree (e.g., “Ionian”, “Dorian”)“, and ToShortName() “the short name of the scale degree (e.g., “I”, “II”)“. Because the interface is the same, one generic method reads every type (Lesson13.ShortNames), and the course compares the short names with the triads:

== The short names: IScaleDegreeNaming.ToShortName against the triad on each degree
degree type course GA check
major I ii iii IV V vi vii° I II III IV V VI VII DIFF
natural minor i ii° III iv v VI VII i ii° III iv v VI VII ok
harmonic minor i ii° III+ iv V VI vii° i ii° III+ iv#4 V VI vii° DIFF
melodic minor i ii III+ IV V vi° vii° i ii III+ IV7 V vi° vii° DIFF
harmonic major I ii° iii iv V VI+ vii° I II III IV V VI VII DIFF
degrees that differ: 11 of 35

The five types follow three conventions. MajorScaleDegree and HarmonicMajorScaleDegree write the degree number, as the interface’s example does. NaturalMinorScaleDegree writes the triads, all right. The two others write triads too, except for one degree each: harmonic minor’s fourth is “iv#4” (#L67-L77), the triad’s numeral with the name of the Dorian ♯4 mode attached, and melodic minor’s fourth is “IV7” (#L64-L74), the only seventh chord of the list: D F♯ A C, the chord of Lydian dominant. A caller cannot know which convention it gets. None exists yet: at a826864, nothing in GA calls ToShortName.

Lesson 2 cited Open Music Theory’s ranking of the modes from bright to dark, and showed why it is so regular: from Lydian to Locrian, each mode lowers one note of the previous one. A number captures it: add up the semitones of the degrees above the tonic. Ionian gives 0 + 2 + 4 + 5 + 7 + 9 + 11 = 38; Lydian raises the fourth, 39; Locrian, the darkest, 33. Each lowered degree takes one away, so the sum ranks the modes of major exactly as the textbook does, and it applies to any scale. The Streeling module MUS-006 · The Scale Universe defines it the same way: “Brightness is the sum of the pitch classes (bit positions set)”. The course computes it from the steps (Lesson13.Brightness).

GA has three things called brightness:

== Brightness: the course's sum of degrees against GA's StepBrightness and IcvBrightness
mode course sum StepBrightness IcvBrightness
Ionian 38 0.2857 0.642857
Dorian 36 0.2857 0.642857
Phrygian 34 0.2857 0.642857
Lydian 39 0.2857 0.642857
Mixolydian 37 0.2857 0.642857
Aeolian 35 0.2857 0.642857
Locrian 33 0.2857 0.642857
melodic minor 37 0.2857 0.595238
Dorian ♭2 35 0.2857 0.595238
Lydian augmented 40 0.2857 0.595238
Lydian dominant 38 0.2857 0.595238
Mixolydian ♭6 36 0.2857 0.595238
Locrian ♮2 34 0.2857 0.595238
altered 32 0.2857 0.595238
harmonic minor 36 0.2857 0.571429
Locrian ♮6 34 0.2857 0.571429
Ionian ♯5 39 0.2857 0.571429
Dorian ♯4 37 0.2857 0.571429
Phrygian dominant 35 0.2857 0.571429
Lydian ♯2 40 0.2857 0.571429
altered ♭♭7 31 0.2857 0.571429
StepBrightness over GA's 4096 sets, by value:
1.0000 sets of 2 notes (66 sets)
0.6667 sets of 3 notes (220 sets)
0.5000 sets of 0, 1, 4 notes (508 sets)
0.4000 sets of 5 notes (792 sets)
0.3333 sets of 6 notes (924 sets)
0.2857 sets of 7 notes (792 sets)
0.2500 sets of 8 notes (495 sets)
0.2222 sets of 9 notes (220 sets)
0.2000 sets of 10 notes (66 sets)
0.1818 sets of 11 notes (12 sets)
0.1667 sets of 12 notes (1 sets)
11 values

StepBrightness gives all 21 modes the same value. The steps of a set go once around the circle, so they always add up to 12: with n notes their average is 12/n, and the value is 2/n, the number of notes in disguise. Over all 4,096 sets it takes 11 values, one per size, except that sets of 4 notes (2/4) share 0.5 with the empty set and single notes, for which the code returns 0.5. IcvBrightness tells the three scales apart, but not their modes: the rotations of a scale have the same interval-class vector (lesson 4), so they get the same value. Only the course’s sum ranks modes. TheoryVectorService.ComputeEmbedding still takes consonance and brightness parameters which, its comment says, “are accepted for backwards compatibility with older callers but are IGNORED” (#L22-L36).

UnifiedModeService is registered as a service of GA (ServiceCollectionExtensions.cs#L25); at a826864 only GA’s tests call RankByBrightness. FromScaleMode moves a mode’s notes so that the root becomes C and looks up the set’s modal family, if the family has more than one member (#L15-L51); RankByBrightness sums each member’s pitch classes and sorts in descending order. The program compiles the service as it is and ranks the family of the first mode of each scale; it labels each member with the course’s name for that mode on C (Lesson13.cs#L186-L216):

== UnifiedModeService.RankByBrightness (GA.Domain.Services, compiled) for the family of major, against the course's ranking of its modes
rank course GA check
1 Lydian 39 Lydian 39 ok
2 Ionian 38 Ionian 38 ok
3 Mixolydian 37 Mixolydian 37 ok
4 Dorian 36 Dorian 36 ok
5 Aeolian 35 Aeolian 35 ok
6 Phrygian 34 Phrygian 34 ok
7 Locrian 33 Locrian 33 ok
== UnifiedModeService.RankByBrightness (GA.Domain.Services, compiled) for the family of melodic minor, against the course's ranking of its modes
rank course GA check
1 Lydian augmented 40 Lydian augmented 40 ok
2 Lydian dominant 38 Lydian dominant 38 ok
3 melodic minor 37 melodic minor 37 ok
4 Mixolydian ♭6 36 Mixolydian ♭6 36 ok
5 Dorian ♭2 35 Dorian ♭2 35 ok
6 Locrian ♮2 34 Locrian ♮2 34 ok
7 altered 32 altered 32 ok
== UnifiedModeService.RankByBrightness (GA.Domain.Services, compiled) for the family of harmonic minor, against the course's ranking of its modes
rank course GA check
1 Lydian ♯2 40 Lydian augmented ♯2 41 DIFF
2 Ionian ♯5 39 Lydian ♯2 40 DIFF
3 Dorian ♯4 37 Ionian ♯5 39 DIFF
4 harmonic minor 36 Lydian ♭3 38 DIFF
5 Phrygian dominant 35 Dorian ♯4 37 DIFF
6 Locrian ♮6 34 harmonic major 37 DIFF
7 altered ♭♭7 31 Mixolydian ♭2 36 DIFF
8 (none) harmonic minor 36 DIFF
9 (none) Phrygian dominant 35 DIFF
10 (none) Dorian ♭5 35 DIFF
11 (none) Locrian ♮6 34 DIFF
12 (none) Phrygian ♭4 33 DIFF
13 (none) Locrian ♭♭7 32 DIFF
14 (none) altered ♭♭7 31 DIFF

For major and melodic minor, GA’s ranking is the course’s. For harmonic minor it ranks 14 scales, and that is lesson 2’s defect: a ModalFamily groups the sets that contain C by interval-class vector, and harmonic major, the mirror image of harmonic minor, has the same vector. Its seven modes, named after Wikipedia’s Harmonic major scale (which writes the sixth “Lydian ♯2 ♯5”), are mixed with harmonic minor’s. The sum itself is right for all fourteen; ties, like Dorian ♯4 and harmonic major at 37, keep the family’s order, since LINQ’s sort is stable (lesson 10). To rank the modes of one scale, the family has to be the scale’s rotations.

For the course, a modal family is the set of rotations of one scale (lesson 2), and all the rotations share one interval-class vector (lesson 4). So a family can declare its vector once, and the notes of each member must have it. The converse does not hold: harmonic major has harmonic minor’s vector without being one of its modes.

GA also lists modes in a configuration file, Modes.yaml, 828 lines read by the F# module ModesConfig. Each family has a name, sometimes an IntervalClassVector, and modes: their notes on C, a description for 77 of the 165 modes and alternate names for 79. GetAllModes gives every mode its family’s declared vector (ModesConfig.fs#L265-L298, #L281). The program, which already compiles GA.Business.Config, checks each declared vector against the notes of the family’s first mode, and each member against the first (Lesson13.cs#L218-L259):

== Modes.yaml (GA.Business.Config, read by ModesConfig): each family's declared vector against the vector of its first mode's notes
31 families, 165 modes, 18 families with a declared vector
GA's PitchClassSet and the course give the same vector for the notes of 164 of the 165 modes
course: the vector of the first mode's notes; GA: the vector the family declares
family course GA check
Major Scale <2 5 4 3 6 1> <2 5 4 3 6 1> ok
Harmonic Minor <3 3 5 4 4 2> <2 4 3 5 4 3> DIFF
Melodic Minor <2 5 4 4 4 2> <2 4 5 3 6 2> DIFF
Major Pentatonic <0 3 2 1 4 0> <0 3 2 2 2 1> DIFF
Whole Tone <0 6 0 6 0 3> <0 6 0 0 6 0> DIFF
Diminished <4 4 8 4 4 4> <4 6 4 6 4 4> DIFF
Blues Scale <2 3 3 2 4 1> <1 4 3 2 5 0> DIFF
Chromatic <12 12 12 12 12 6> <11 11 11 11 11 6> DIFF
Perfect Fourth <0 0 0 0 1 0> <0 0 0 0 1 0> ok
Major Third <0 0 0 1 0 0> <0 0 0 1 0 0> ok
Minor Third <0 0 1 0 0 0> <0 0 1 0 0 0> ok
Major Second <0 1 0 0 0 0> <0 1 0 0 0 0> ok
Minor Second <1 0 0 0 0 0> <1 0 0 0 0 0> ok
Major Triad <0 0 1 1 1 0> <0 0 1 1 1 0> ok
Diminished Triad <0 0 2 0 0 1> <0 0 2 0 0 1> ok
Augmented Triad <0 0 0 3 0 0> <0 1 0 0 2 0> DIFF
Major Seventh Chord <1 0 1 2 2 0> <0 1 2 1 1 1> DIFF
All Interval Tetrachord <1 1 1 1 1 1> <1 1 1 1 1 1> ok
declared vectors that differ: 9
Modes whose notes do not have the vector of their family's first mode:
Harmonic Minor Family 1 of 6
Major Pentatonic Family 1 of 4
Diminished Triad Family 2 of 2
Augmented Triad Family 2 of 2
Major Seventh Chord Family 7 of 7
All Interval Tetrachord Family 15 of 15
Double Harmonic Family 1 of 6
Neapolitan Minor Family 1 of 6
Neapolitan Major Family 4 of 6
Dominant Bebop Family 3 of 7
Major Bebop Family 5 of 7
Prometheus Family 3 of 5
Enigmatic Family 5 of 6
Hungarian Major Family 6 of 6
In Sen Family 4 of 4
60 of 134

Half of the declared vectors are wrong: 9 of 18, among them harmonic minor’s, melodic minor’s and the whole-tone scale’s. The chromatic scale contains each interval class twelve times and the tritone six times; the file declares 11. And 60 of the 134 members do not have the vector of their family’s first mode, so they are not its rotations. The Major Seventh Chord family lists seven other kinds of seventh chord; the Diminished Triad family’s “first inversion”, C E A (#L465-L466), is an A minor triad; none of the six other “modes” of Hungarian major is a rotation of it. The two families of this lesson:

Harmonic Minor Family Notes GA's vector
Harmonic Minor C D Eb F G Ab B <3 3 5 4 4 2>
Locrian #6 C Db Eb F Gb A Bb <3 3 5 4 4 2>
Ionian #5 C D E F G# A B <3 3 5 4 4 2>
Dorian #4 C D Eb F# G A Bb <3 3 5 4 4 2>
Phrygian Dominant C Db E F G Ab Bb <3 3 5 4 4 2>
Lydian #2 C D# E F# G A B <3 3 5 4 4 2>
Ultralocrian C Db Eb Fb Gb Ab Bb <2 5 4 4 4 2>
Melodic Minor Family Notes GA's vector
Melodic Minor C D Eb F G A B <2 5 4 4 4 2>
Dorian b2 C Db Eb F G A Bb <2 5 4 4 4 2>
Lydian Augmented C D E F# G# A B <2 5 4 4 4 2>
Lydian Dominant C D E F# G A Bb <2 5 4 4 4 2>
Mixolydian b6 C D E F G Ab Bb <2 5 4 4 4 2>
Locrian #2 C D Eb F Gb Ab Bb <2 5 4 4 4 2>
Altered C Db Eb Fb Gb Ab Bb <2 5 4 4 4 2>

The Ultralocrian (#L242-L247) is spelled with the notes of the Melodic Minor Family’s Altered mode (#L286-L287). Its seventh should be B♭♭, which sounds as A: the same diminished seventh as G♯ to F in the harmonic minor table above. With one note wrong, it gets melodic minor’s vector.

ModesConfig.TryGetModeByIntervalClassVector returns the first mode whose family declares the vector it is given. GA’s MCP server prints its answer as the “Scale:” line of ga_chord_to_set (ChordAtonalTool.cs#L105-L125), and in brackets after each set of ga_icv_neighbors (#L249). The program calls the lookup with the vectors GA computes (Lesson13.cs#L261-L279); the course column is the Modes.yaml entry that names the scale or chord, which the file writes on C.

== ModesConfig.TryGetModeByIntervalClassVector, the "Scale:" line of ga_chord_to_set, with the vectors GA computes
course: the Modes.yaml entry that names the scale or chord (written on C); GA: what the lookup returns
set course GA check
C major Ionian Ionian ok
A harmonic minor Harmonic Minor (none) DIFF
A melodic minor Melodic Minor (none) DIFF
Cmaj7 Major Seventh (none) DIFF
G7 Dominant Seventh Major Seventh DIFF
Bm7b5 Half Diminished Seventh Major Seventh DIFF
C Major Triad Major Triad ok
Cm Minor Triad Major Triad DIFF

Harmonic and melodic minor are not found: their families declare the wrong vector. Cmaj7 is not found either, because the Major Seventh Chord family (#L493-L535) declares <0 1 2 1 1 1>, the vector of a dominant seventh, and that is how G7 comes back as “Major Seventh”. So does Bm7♭5: a half-diminished seventh is the inversion of a dominant seventh, and inversions have the same vector (lesson 4). For the same reason C minor comes back as “Major Triad”. Even with the right vectors, a lookup by vector cannot tell a chord from its inversion; it needs the prime form, or a list. The MCP tools themselves were not run: the course runs ModesConfig, which they call.

ModesConfig.TryGetModeByName, behind the MCP tool get_mode_info (ModeTool.cs#L18-L34), compares the name, ignoring case, with each mode’s name and alternate names. The program asks it for the names of GA’s own two mode classes, and four names from Wikipedia: Super Locrian and Acoustic Scale (Jazz scale), Spanish Phrygian (Phrygian dominant scale) and Ultralocrian (Harmonic minor scale) (Lesson13.cs#L281-L295):

== ModesConfig.TryGetModeByName, behind get_mode_info, with the names of GA's two mode classes
name found
Melodic Minor Melodic Minor (Melodic Minor Family)
Dorian b2 Dorian b2 (Melodic Minor Family)
Lydian Augmented Lydian Augmented (Melodic Minor Family)
Lydian Dominant Lydian Dominant (Melodic Minor Family)
Mixolydian b6 Mixolydian b6 (Melodic Minor Family)
Locrian Natural 2 not found
Altered Altered (Melodic Minor Family)
Harmonic Minor Harmonic Minor (Harmonic Minor Family)
Locrian Natural 6 not found
Ionian Augmented Ionian Augmented (Double Harmonic Family)
Dorian Sharp 4 not found
Phrygian Dominant Phrygian Dominant (Harmonic Minor Family)
Lydian Sharp 2 not found
Altered bb7 not found
Super Locrian not found
Acoustic Scale not found
Spanish Phrygian not found
Ultralocrian Ultralocrian (Harmonic Minor Family)
GA's names found: 9 of 14
alternate names: GetModalFamilies keeps 104; GetAllModes keeps them on 0 of 165 modes

Three of GA’s names are not in the file: it writes “Locrian #2”, “Dorian #4” and “Lydian #2”. Others are there, as alternate names: “Locrian Natural 6” and “Ionian Augmented” (#L209-L219), “Spanish Phrygian” (#L230), “Altered bb7” (#L247), “Acoustic Scale” (#L273) and “Super Locrian” (#L290). GetModalFamilies keeps 104 alternate names, but the lookup runs on GetAllModes, which sets them to nothing: let alternateNames = None (ModesConfig.fs#L284). No alternate name can be found, and get_mode_info ends every answer with “Alternate Names: None” (ModeTool.cs#L27-L33); it prints the declared vector on a line called “Intervals”. Read, not run.

“Ionian Augmented” is found, but in the wrong family: the Double Harmonic Family’s mode written “Ionian Augmented #2” (#L655-L656), whose notes are C D♯ E F G♯ A B. Why it lost its “#2” is the next test.

Added after the first run: names cut short

Section titled “Added after the first run: names cut short”

YAML reads an unquoted “ #” as the start of a comment. The file quotes some names (“‘Locrian #6’”, #L209) but not all. The first run showed one name cut; the program then compared every name as the file writes it with the name ModesConfig returns, in a commit of its own after the first run (Lesson13.cs#L297-L327):

== Added after the first run: the names written in Modes.yaml against the names ModesConfig returns
course: the name as the file writes it; GA: the name the loader returns (YAML reads " #" as the start of a comment)
line course GA check
631 Lydian Augmented #2 Lydian Augmented DIFF
639 Lydian #2 #6 Lydian DIFF
655 Ionian Augmented #2 Ionian Augmented DIFF
663 Lydian #6 Lydian DIFF
667 Aeolian #4 (Lydian Diminished) Aeolian DIFF
671 Ionian #2 Ionian DIFF
679 Lydian Augmented #6 Lydian Augmented DIFF
681 Lydian Dominant #5 Lydian Dominant DIFF
names that differ: 8 of 165
names ModesConfig returns more than once: 7
Ionian: Major Scale, Neapolitan Minor
Lydian: Major Scale, Double Harmonic, Neapolitan Minor
Aeolian: Major Scale, Neapolitan Minor
Lydian Augmented: Melodic Minor, Harmonic Major, Neapolitan Major
Lydian Dominant: Melodic Minor, Neapolitan Major
Minor Seventh: Major Second, Major Seventh Chord
Major Seventh: Minor Second, Major Seventh Chord

Eight names lose their alterations, and seven names now belong to more than one mode. A lookup by name returns the first in the file: “Lydian” is always the major scale’s mode, never “Lydian #2 #6” or “Lydian #6”. The last two lines are not cut names: the Minor Second and Major Second families list their inversions, C B and C B♭, as “Major Seventh” and “Minor Seventh”, the names of two chords of the Major Seventh Chord family. A lookup of “Major Seventh” returns the interval.

The modes whose vector GA's PitchClassSet and the course disagree on:
Chromatic: C C# D D# E F F# G G# A A# B, GA <1 1 1 1 0 6>, course <12 12 12 12 12 6>

The one mode whose vector GA and the course compute differently is the chromatic scale. GA packs a vector into one integer in base 12, a digit per interval class, and its comment admits the limit: “KNOWN LIMITATION: a single count of exactly 12 still overflows a base-12 digit, so the full chromatic aggregate <12 12 12 12 12 6> does NOT round-trip (decodes to <1 1 1 1 0 6>)” (IntervalClassVectorId.cs#L3-L15).

  1. The altered scale on G♯ is G♯ A B C D E F♯. Which notes of G♯7 does it contain, and which alterations does it add?
  2. Rank the seven modes of harmonic minor from brightest to darkest, with their sums.
  3. What does StepBrightness give a dominant seventh chord? Which other sets get the same value?
  4. Which mode does TryGetModeByName("Lydian Augmented") return? Which other modes of Modes.yaml answer to that name, and why?
Solutions
  1. G♯7 is G♯ B♯ D♯ F♯. The scale has G♯, F♯, and C, which sounds as B♯; it has no D♯. It adds A (♭9), B (♯9), D (♭5, or ♯11) and E (♭13): Wikipedia’s “C7 (♭9 or ♯9, ♯11, ♭13)”, moved to G♯.
  2. Lydian ♯2 40, Ionian ♯5 39, Dorian ♯4 37, harmonic minor 36, Phrygian dominant 35, Locrian ♮6 34, altered ♭♭7 31: the course column of the brightness table, and of the ranking.
  3. 0.5: a seventh chord has four notes, and 2/4 = 0.5. The 508 sets of 0, 1 and 4 notes share it.
  4. The Melodic Minor Family’s Lydian Augmented, the first in the file. The Harmonic Major Family’s “Lydian Augmented #2” (line 631) and the Neapolitan Major Family’s “Lydian Augmented #6” (line 679) lose their alteration to a YAML comment and come back with the same name.
  • Melodic minor is a major scale with a lowered third, harmonic minor a natural minor with a raised seventh. Each has seven modes, among them Lydian dominant, the altered scale and Phrygian dominant, the dominant scales of jazz. GA’s generic ScaleMode<TScaleDegree> spells and writes all fourteen as the textbook does.
  • One interface, IScaleDegreeNaming, names the degrees of every scale type, but its ToShortName mixes three conventions: degree numbers, triad numerals, and two short names that are neither (iv#4, IV7). Nothing calls it yet.
  • The sum of a mode’s degrees ranks modes from bright to dark, and GA’s RankByBrightness computes exactly that. GA’s two other brightness measures cannot rank modes: StepBrightness is 2/n, the number of notes, and IcvBrightness is the same for every mode of a scale.
  • A GA modal family is the set of sets that share an interval-class vector, so harmonic minor’s family holds harmonic major’s modes too, and the ranking has 14 rows.
  • In Modes.yaml, 9 of 18 declared vectors are wrong, 60 of 134 members lack their family’s vector, 8 names are cut by YAML comments and the loader drops every alternate name. Looked up by vector, harmonic minor is found nowhere and G7 is “Major Seventh”; looked up by name, 5 of GA’s own 14 names are missing and “Ionian Augmented” lands in the wrong family.