Lesson 11: Modes in depth
Sections
Reading settings
No voice for this language in this browser.
More voices
Code and English terms
Off: the page’s voice reads everything, with no pause between two voices.
No voice for this language in this browser.
More voices
More voices: Microsoft Edge has natural online voices, and Windows (Settings › Time & language › Speech), macOS and Android install others.
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.
dotnet run --project code/music-theory-ga/GaTheory -c Release -- l13The modes of melodic minor
Section titled “The modes of melodic minor”The idea
Section titled “The idea”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 1mode course GA checkmelodic minor 1 2 b3 4 5 >♮6 >♮7 1 2 b3 4 5 >♮6 >♮7 okDorian ♭2 1 >b2 b3 4 5 >♮6 b7 1 >b2 b3 4 5 >♮6 b7 okLydian augmented 1 2 3 >♯4 >♯5 6 7 1 2 3 >♯4 >♯5 6 7 okLydian dominant 1 2 3 >♯4 5 6 >b7 1 2 3 >♯4 5 6 >b7 okMixolydian ♭6 1 2 3 4 5 >b6 >b7 1 2 3 4 5 >b6 >b7 okLocrian ♮2 1 2 b3 4 >b5 b6 b7 1 2 b3 4 >b5 b6 b7 okaltered 1 >b2 b3 >b4 >b5 b6 b7 1 >b2 b3 >b4 >b5 b6 b7 ok
notes course GA checkmelodic minor A B C D E F# G# A B C D E F# G# okDorian ♭2 B C D E F# G# A B C D E F# G# A okLydian augmented C D E F# G# A B C D E F# G# A B okLydian dominant D E F# G# A B C D E F# G# A B C okMixolydian ♭6 E F# G# A B C D E F# G# A B C D okLocrian ♮2 F# G# A B C D E F# G# A B C D E okaltered G# A B C D E F# G# A B C D E F# ok
textbook name GA's Namemelodic minor Melodic MinorDorian ♭2 Dorian b2Lydian augmented Lydian AugmentedLydian dominant Lydian DominantMixolydian ♭6 Mixolydian b6Locrian ♮2 Locrian Natural 2altered AlteredGA 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.
The modes of harmonic minor
Section titled “The modes of harmonic minor”The idea
Section titled “The idea”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 1mode course GA checkharmonic minor 1 2 b3 4 5 b6 >♮7 1 2 b3 4 5 b6 >♮7 okLocrian ♮6 1 >b2 b3 4 >b5 >♮6 b7 1 >b2 b3 4 >b5 >♮6 b7 okIonian ♯5 1 2 3 4 >♯5 6 7 1 2 3 4 >♯5 6 7 okDorian ♯4 1 2 b3 >♯4 5 >♮6 b7 1 2 b3 >♯4 5 >♮6 b7 okPhrygian dominant 1 >b2 3 4 5 >b6 >b7 1 >b2 3 4 5 >b6 >b7 okLydian ♯2 1 >♯2 3 >♯4 5 6 7 1 >♯2 3 >♯4 5 6 7 okaltered ♭♭7 1 >b2 b3 >b4 >b5 b6 >bb7 1 >b2 b3 >b4 >b5 b6 >bb7 ok
notes course GA checkharmonic minor A B C D E F G# A B C D E F G# okLocrian ♮6 B C D E F G# A B C D E F G# A okIonian ♯5 C D E F G# A B C D E F G# A B okDorian ♯4 D E F G# A B C D E F G# A B C okPhrygian dominant E F G# A B C D E F G# A B C D okLydian ♯2 F G# A B C D E F G# A B C D E okaltered ♭♭7 G# A B C D E F G# A B C D E F ok
textbook name GA's Nameharmonic minor Harmonic MinorLocrian ♮6 Locrian Natural 6Ionian ♯5 Ionian AugmentedDorian ♯4 Dorian Sharp 4Phrygian dominant Phrygian DominantLydian ♯2 Lydian Sharp 2altered ♭♭7 Altered bb7Seven out of seven again, double flat included. GA calls the seventh mode “Altered bb7”, Wikipedia’s “Super-Locrian” with a doubly flattened seventh.
One interface for every kind of degree
Section titled “One interface for every kind of degree”The idea
Section titled “The idea”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 degreedegree type course GA checkmajor I ii iii IV V vi vii° I II III IV V VI VII DIFFnatural minor i ii° III iv v VI VII i ii° III iv v VI VII okharmonic minor i ii° III+ iv V VI vii° i ii° III+ iv#4 V VI vii° DIFFmelodic minor i ii III+ IV V vi° vii° i ii III+ IV7 V vi° vii° DIFFharmonic major I ii° iii iv V VI+ vii° I II III IV V VI VII DIFFdegrees that differ: 11 of 35The 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.
Brightness
Section titled “Brightness”The idea
Section titled “The idea”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).
In GA: three measures
Section titled “In GA: three measures”GA has three things called brightness:
PitchClassSet.StepBrightness“measures brightness based on the preponderance of large steps”: it averages the steps between consecutive pitch classes, around the circle, and divides by 6. The code calls it a “Very rough proxy”. It feeds one dimension of GA’s embeddings (ModalVectorService.cs#L157).IcvBrightness, inTheoryVectorService.cs#L159-L172, weighs the major thirds and perfect fifths of the interval-class vector (lesson 4) against its minor seconds and tritones, and maps the balance to the range 0 to 1. It is dimension 21 of the structure vectorTheoryVectorServicecomputes (#L82-L83), which GA’s embedding generator writes from index 6 (MusicalEmbeddingGenerator.cs#L125,EmbeddingSchema.cs#L334): index 27 of the full embedding. The method is internal, so the program copies it as it is (Lesson13.IcvBrightness).UnifiedModeService.RankByBrightnessadds up the pitch classes of each member of a modal family: the course’s measure. It comes in the next section.
== Brightness: the course's sum of degrees against GA's StepBrightness and IcvBrightnessmode course sum StepBrightness IcvBrightnessIonian 38 0.2857 0.642857Dorian 36 0.2857 0.642857Phrygian 34 0.2857 0.642857Lydian 39 0.2857 0.642857Mixolydian 37 0.2857 0.642857Aeolian 35 0.2857 0.642857Locrian 33 0.2857 0.642857melodic minor 37 0.2857 0.595238Dorian ♭2 35 0.2857 0.595238Lydian augmented 40 0.2857 0.595238Lydian dominant 38 0.2857 0.595238Mixolydian ♭6 36 0.2857 0.595238Locrian ♮2 34 0.2857 0.595238altered 32 0.2857 0.595238harmonic minor 36 0.2857 0.571429Locrian ♮6 34 0.2857 0.571429Ionian ♯5 39 0.2857 0.571429Dorian ♯4 37 0.2857 0.571429Phrygian dominant 35 0.2857 0.571429Lydian ♯2 40 0.2857 0.571429altered ♭♭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 valuesStepBrightness 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).
In GA: ranking a family
Section titled “In GA: ranking a family”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 modesrank course GA check1 Lydian 39 Lydian 39 ok2 Ionian 38 Ionian 38 ok3 Mixolydian 37 Mixolydian 37 ok4 Dorian 36 Dorian 36 ok5 Aeolian 35 Aeolian 35 ok6 Phrygian 34 Phrygian 34 ok7 Locrian 33 Locrian 33 ok
== UnifiedModeService.RankByBrightness (GA.Domain.Services, compiled) for the family of melodic minor, against the course's ranking of its modesrank course GA check1 Lydian augmented 40 Lydian augmented 40 ok2 Lydian dominant 38 Lydian dominant 38 ok3 melodic minor 37 melodic minor 37 ok4 Mixolydian ♭6 36 Mixolydian ♭6 36 ok5 Dorian ♭2 35 Dorian ♭2 35 ok6 Locrian ♮2 34 Locrian ♮2 34 ok7 altered 32 altered 32 ok
== UnifiedModeService.RankByBrightness (GA.Domain.Services, compiled) for the family of harmonic minor, against the course's ranking of its modesrank course GA check1 Lydian ♯2 40 Lydian augmented ♯2 41 DIFF2 Ionian ♯5 39 Lydian ♯2 40 DIFF3 Dorian ♯4 37 Ionian ♯5 39 DIFF4 harmonic minor 36 Lydian ♭3 38 DIFF5 Phrygian dominant 35 Dorian ♯4 37 DIFF6 Locrian ♮6 34 harmonic major 37 DIFF7 altered ♭♭7 31 Mixolydian ♭2 36 DIFF8 (none) harmonic minor 36 DIFF9 (none) Phrygian dominant 35 DIFF10 (none) Dorian ♭5 35 DIFF11 (none) Locrian ♮6 34 DIFF12 (none) Phrygian ♭4 33 DIFF13 (none) Locrian ♭♭7 32 DIFF14 (none) altered ♭♭7 31 DIFFFor 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.
Modal families in a configuration file
Section titled “Modal families in a configuration file”The idea
Section titled “The idea”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.
In GA: Modes.yaml
Section titled “In GA: Modes.yaml”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 notes31 families, 165 modes, 18 families with a declared vectorGA's PitchClassSet and the course give the same vector for the notes of 164 of the 165 modescourse: the vector of the first mode's notes; GA: the vector the family declaresfamily course GA checkMajor Scale <2 5 4 3 6 1> <2 5 4 3 6 1> okHarmonic Minor <3 3 5 4 4 2> <2 4 3 5 4 3> DIFFMelodic Minor <2 5 4 4 4 2> <2 4 5 3 6 2> DIFFMajor Pentatonic <0 3 2 1 4 0> <0 3 2 2 2 1> DIFFWhole Tone <0 6 0 6 0 3> <0 6 0 0 6 0> DIFFDiminished <4 4 8 4 4 4> <4 6 4 6 4 4> DIFFBlues Scale <2 3 3 2 4 1> <1 4 3 2 5 0> DIFFChromatic <12 12 12 12 12 6> <11 11 11 11 11 6> DIFFPerfect Fourth <0 0 0 0 1 0> <0 0 0 0 1 0> okMajor Third <0 0 0 1 0 0> <0 0 0 1 0 0> okMinor Third <0 0 1 0 0 0> <0 0 1 0 0 0> okMajor Second <0 1 0 0 0 0> <0 1 0 0 0 0> okMinor Second <1 0 0 0 0 0> <1 0 0 0 0 0> okMajor Triad <0 0 1 1 1 0> <0 0 1 1 1 0> okDiminished Triad <0 0 2 0 0 1> <0 0 2 0 0 1> okAugmented Triad <0 0 0 3 0 0> <0 1 0 0 2 0> DIFFMajor Seventh Chord <1 0 1 2 2 0> <0 1 2 1 1 1> DIFFAll Interval Tetrachord <1 1 1 1 1 1> <1 1 1 1 1 1> okdeclared 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 460 of 134Half 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 vectorHarmonic 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 vectorMelodic 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.
In GA: looking a mode up by vector
Section titled “In GA: looking a mode up by 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 computescourse: the Modes.yaml entry that names the scale or chord (written on C); GA: what the lookup returnsset course GA checkC major Ionian Ionian okA harmonic minor Harmonic Minor (none) DIFFA melodic minor Melodic Minor (none) DIFFCmaj7 Major Seventh (none) DIFFG7 Dominant Seventh Major Seventh DIFFBm7b5 Half Diminished Seventh Major Seventh DIFFC Major Triad Major Triad okCm Minor Triad Major Triad DIFFHarmonic 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.
In GA: looking a mode up by name
Section titled “In GA: looking a mode up by name”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 classesname foundMelodic 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 foundAltered Altered (Melodic Minor Family)Harmonic Minor Harmonic Minor (Harmonic Minor Family)Locrian Natural 6 not foundIonian Augmented Ionian Augmented (Double Harmonic Family)Dorian Sharp 4 not foundPhrygian Dominant Phrygian Dominant (Harmonic Minor Family)Lydian Sharp 2 not foundAltered bb7 not foundSuper Locrian not foundAcoustic Scale not foundSpanish Phrygian not foundUltralocrian Ultralocrian (Harmonic Minor Family)GA's names found: 9 of 14alternate names: GetModalFamilies keeps 104; GetAllModes keeps them on 0 of 165 modesThree 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 returnscourse: the name as the file writes it; GA: the name the loader returns (YAML reads " #" as the start of a comment)line course GA check631 Lydian Augmented #2 Lydian Augmented DIFF639 Lydian #2 #6 Lydian DIFF655 Ionian Augmented #2 Ionian Augmented DIFF663 Lydian #6 Lydian DIFF667 Aeolian #4 (Lydian Diminished) Aeolian DIFF671 Ionian #2 Ionian DIFF679 Lydian Augmented #6 Lydian Augmented DIFF681 Lydian Dominant #5 Lydian Dominant DIFFnames that differ: 8 of 165names 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 ChordEight 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).
Exercises
Section titled “Exercises”- 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?
- Rank the seven modes of harmonic minor from brightest to darkest, with their sums.
- What does
StepBrightnessgive a dominant seventh chord? Which other sets get the same value? - Which mode does
TryGetModeByName("Lydian Augmented")return? Which other modes ofModes.yamlanswer to that name, and why?
Solutions
- 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♯.
- 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.
- 0.5: a seventh chord has four notes, and 2/4 = 0.5. The 508 sets of 0, 1 and 4 notes share it.
- 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.
Key takeaways
Section titled “Key takeaways”- 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 itsToShortNamemixes 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
RankByBrightnesscomputes exactly that. GA’s two other brightness measures cannot rank modes:StepBrightnessis 2/n, the number of notes, andIcvBrightnessis 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.
Sources
Section titled “Sources”- Mark Gotham et al., Open Music Theory, version 2, 2023, CC BY-SA 4.0: John Kocur, Chord-Scale Theory, and Introduction to Diatonic Modes and the Chromatic Scale.
- Wikipedia: Jazz scale, Harmonic minor scale, Harmonic major scale, Phrygian dominant scale.
- GuitarAlchemist/ga at
a826864:Common/GA.Domain.Core/Theory/Tonal/Modes/ScaleMode.cs,Theory/Tonal/Modes/Diatonic/MelodicMinorMode.cs,HarmonicMinorMode.cs,Theory/Tonal/Primitives/IScaleDegreeNaming.csand the degree types,Theory/Atonal/PitchClassSet.cs,ModalFamily.cs,IntervalClassVectorId.cs,Common/GA.Business.ML/Embeddings/Services/TheoryVectorService.cs,Common/GA.Business.ML/Embeddings/MusicalEmbeddingGenerator.cs,EmbeddingSchema.cs,Common/GA.Domain.Services/Unified/UnifiedModeService.cs,Common/GA.Business.Config/Modes.yaml,ModesConfig.fs,GaMcpServer/Tools/ModeTool.cs,ChordAtonalTool.cs.