Lesson 1: Notes, pitch classes and the fretboard
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.
Every other lesson builds on four ideas: a pitch is a note at a given height, a pitch class is that note in any octave, an interval is the distance between two notes, and on a guitar each fret adds one of those distances, a semitone. This lesson goes through them in that order: the musical idea first, then how it is written, then the types that Guitar Alchemist (GA) uses for it.
All GA links point to commit a826864 of GuitarAlchemist/ga, the one the course program is built against.
Running the lesson’s program
Section titled “Running the lesson’s program”The course program is in code/music-theory-ga. fetch-ga.sh clones GA at that commit without its file contents (--filter=blob:none), then checks out only three projects with git sparse-checkout. The C# project references one of them, GA.Domain.Core, like any other project of a solution (GaTheory.csproj). You need the .NET 10 SDK and Git; on Windows, run the commands from Git Bash.
bash code/music-theory-ga/check.sh # every lesson, compared with expected/dotnet run --project code/music-theory-ga/GaTheory -c Release -- l1 # this lesson only, after check.shEach table prints the course’s own computation, written from the textbook definitions in Theory.cs, next to GA’s answer, and ok or DIFF. A DIFF is not a failure of the program: it is something GA does differently, and the lesson explains it. check.sh compares the whole output, DIFF lines included, with expected/l1.txt, on Linux, Windows and macOS in CI.
Pitch and pitch class
Section titled “Pitch and pitch class”The idea
Section titled “The idea”Play the open low E string, then the same note twelve frets higher: the second note sounds “the same, only higher”. Musicians call that octave equivalence. A pitch is one specific note, such as the E of the low string; a pitch class is every E in every octave (Open Music Theory, “Pitch and Pitch Class”).
Western music divides the octave into twelve equal semitones (half steps). If you know TimeOnly or LocalTime, a pitch class is the hour on a 12-hour clock and a pitch is a full timestamp: adding twelve semitones changes the octave, not the pitch class.
The notation
Section titled “The notation”- Scientific (American Standard) pitch notation writes a pitch as a note name and an octave number. Octave numbers change on C, and middle C is C4 (Open Music Theory, “ASPN”).
- MIDI note numbers count semitones from 0 to 127: middle C is 60 and A4 (440 Hz) is 69 (MIDI tuning standard). So
midi = 12 × (octave + 1) + pitch class. - Integer notation numbers the pitch classes from C = 0 to B = 11. All enharmonic spellings of a note share its number: B♯ is 0 and D♭ is 1 (Open Music Theory, “Pitch and Pitch Class”). To keep every pitch class one character long, 10 and 11 are often written T and E, as in the set class table of Open Music Theory, “Set Class and Prime Form”, where the major scale is
(013568T).
The first table of the program converts the six open strings of a guitar, middle C, A4 and C♯4:
== Pitches: MIDI number and pitch class (C4 = 60)pitch course GA checkE2 midi 40 pc 4 midi 40 pc 4 okA2 midi 45 pc 9 midi 45 pc 9 okD3 midi 50 pc 2 midi 50 pc 2 okG3 midi 55 pc 7 midi 55 pc 7 okB3 midi 59 pc 11 midi 59 pc 11 okE4 midi 64 pc 4 midi 64 pc 4 okC4 midi 60 pc 0 midi 60 pc 0 okA4 midi 69 pc 9 midi 69 pc 9 okC#4 midi 61 pc 1 midi 61 pc 1 okGA prints pitch classes as: 0 1 2 3 4 5 6 7 8 9 T EPitchClassis areadonly record structholding anintfrom 0 to 11: a value object, as you would write aMoneyor anEmailAddress. Its setter normalizes the value modulo 12 throughEnsureValueRange(…, normalize: true), soPitchClass.FromValue(-1)is 11: pitch-class arithmetic never leaves the clock face.ToString()prints 10 and 11 as T and E. Careful: pitch classEis B, not the note E.Pitchis anabstract recordwith anOctaveand aPitchClass, and three subtypes depending on how the note is spelled:Chromatic,SharpandFlat.MidiNotederives the octave and pitch class by dividing by 12, andMidiNote.Createis the formula above, withOctave.Min= −1.
Note names and accidentals
Section titled “Note names and accidentals”The idea
Section titled “The idea”The seven natural notes C D E F G A B are the white keys of a piano. Between most of them sits one more pitch class (a black key), except between E and F and between B and C, which are only a semitone apart. An accidental raises (♯, sharp) or lowers (♭, flat) a letter by a semitone; double sharps (𝄪, written x) and double flats (𝄫) move it by two.
So one pitch class has several names: C♯ and D♭ are the same key on the piano, and so are B♯ and C. These are enharmonic spellings (Open Music Theory, “Pitch and Pitch Class”). Octave numbers follow the letter, not the sound: B♯3 and C4 are the same key, in two octaves (Open Music Theory, “ASPN”). The name you choose depends on the context: lesson 3 shows why a C minor chord is spelled C E♭ G, not C D♯ G.
== Spellings: many names, one pitch classnote course GA checkC# 1 1 okDb 1 1 okB# 0 0 okCb 11 11 okE# 5 5 okFb 4 4 okBbb 9 9 okFx 7 7 okNote is a closed hierarchy of records, GA’s discriminated union: the C# counterpart of a Java sealed interface with record implementations.
classDiagram class Note { <<abstract record>> PitchClass PitchClass } class Chromatic { int Value } class KeyNote { <<abstract>> NaturalNote NaturalNote } class Sharp { SharpAccidental? SharpAccidental } class Flat { FlatAccidental? FlatAccidental } class Accidented { Accidental? Accidental } Note <|-- Chromatic Note <|-- KeyNote KeyNote <|-- Sharp KeyNote <|-- Flat Note <|-- AccidentedNote.Chromaticis a pitch class without a spelling; it prints asC#/Db.Note.SharpandNote.Flatare the names used in sharp and flat keys.Note.Accidentedtakes anyAccidentalfrom triple flat to triple sharp. Its pitch class is the letter’s, fromNaturalNote.PitchClass, plus the accidental, normalized: that is howCbbecomes 11.
Intervals
Section titled “Intervals”The idea
Section titled “The idea”An interval has two names at once (Open Music Theory, “Intervals”):
- its number counts letters, both ends included: C up to E is a third (C, D, E), whatever the accidentals;
- its quality comes from the number of semitones. Unisons, fourths, fifths and octaves are perfect (P) and become augmented (A) or diminished (d) when one semitone wider or narrower. Seconds, thirds, sixths and sevenths are major (M) or minor (m), a semitone apart, then augmented or diminished beyond.
That is why C–D♯ and C–E♭ are both three semitones but different intervals: an augmented second and a minor third. Turning an interval upside down (C up to E, then E up to C) is an inversion: the numbers add up to 9 (a third becomes a sixth), perfect stays perfect, major becomes minor and augmented becomes diminished (same chapter, “Intervallic Inversion”).
When only the pitch classes matter, the distance is folded to at most 6 semitones: that is the interval class, and C–E (4) and E–C (8) are both interval class 4 (Open Music Theory, “Intervals in Integer Notation”). Lesson 4 counts interval classes.
== Intervals: name from the letters, size in semitones, interval classnotes course GA checkC-E M3 4 ic4 M3 4 ic4 okC-Eb m3 3 ic3 m3 3 ic3 okC-D# A2 3 ic3 A2 3 ic3 okC-G P5 7 ic5 P5 7 ic5 okC-F# A4 6 ic6 A4 6 ic6 okC-Gb d5 6 ic6 d5 6 ic6 okB-F d5 6 ic6 d5 6 ic6 okE-C m6 8 ic4 m6 8 ic4 ok!M3 m6 m6 okInterval.Simpleis a record with aSize(the number,SimpleIntervalSize, 1 to 8, which knows whether it is perfect and its major/perfect size in semitones) and aQuality(IntervalQuality, −3 for doubly diminished to +3 for doubly augmented). Its semitones are the size’s plus the quality turned into an accidental.- The
!operator isToInverse:9 - Valuefor the size and the opposite quality. GetIntervaltakes the number from the letters and the semitones from the pitch classes, then looks the quality up inDetermineQuality, the same algorithm as the course’sTheory.Interval. GA’s methods are C# 14 extension members (extension(Note note1) { … }).IntervalClass.FromValuefolds any number of semitones into 0–6.
The fretboard and tunings
Section titled “The fretboard and tunings”The idea
Section titled “The idea”A guitar’s strings are numbered from the highest-sounding one: string 1 is the thin high E, string 6 the low E. Standard tuning is E2 A2 D3 G3 B3 E4 from string 6 to string 1 (Guitar tunings). Each fret raises the string by one semitone, so the note at string s, fret f is the open string’s MIDI number plus f. The same pitch appears on several strings: C4 is string 2 fret 1, string 3 fret 5 and string 4 fret 10. The Streeling module GTR-001 · The Fretboard Map walks through the natural notes on each string.
E2A2D3G3B3E4The diagram draws frets 0 to 12 in standard tuning, string 1 at the top as in tablature, and marks every position of pitch class C with its pitch. There are six: C3 on string 6 at fret 8 and on string 5 at fret 3, C4 on string 4 at fret 10, string 3 at fret 5 and string 2 at fret 1, and C5 on string 1 at fret 8. Three positions play the very same pitch, C4.
== Standard tuning: string 1 is the higheststring course GA check1 E4 E4 ok2 B3 B3 ok3 G3 G3 ok4 D3 D3 ok5 A2 A2 ok6 E2 E2 ok
== Fretboard: each fret adds one semitonestring/fret course GA check6/0 E2 40 E2 40 ok6/3 G2 43 G2 43 ok5/3 C3 48 C3 48 ok2/1 C4 60 C4 60 ok3/5 C4 60 C4 60 ok1/8 C5 72 C5 72 ok4/10 C4 60 C4 60 ok
== Where is pitch class C on frets 0-12? (string/fret)course 6/8 5/3 4/10 3/5 2/1 1/8GA, Note.Chromatic 6/8 5/3 4/10 3/5 2/1 1/8GA, Note.Sharp (none)Tuningis built from a string of pitches:Tuning.Defaultparses"E2 A2 D3 G3 B3 E4", low to high, andBuildPitchArrayreverses it when the first pitch is the lowest, so that the indexertuning[new Str(1)]is the highest string, as guitarists count.Str(1 to 26) andFret(−1 for a muted string, 0 open, up to 36) are value objects again.Fretboard.GetNoteadds the fret to the open string’s MIDI note, as above, but takes a 0-based string index:GetNote(0, 0)is string 1.GetPositionsForNotecompares each position’s note withEquals.GetNotereturns aNote.Chromatic, and records of different types are never equal, so asking forNote.Sharp.Cfinds nothing: the(none)line above.
Surprises found while writing this lesson
Section titled “Surprises found while writing this lesson”Writing the comparisons turned up a few places where GA answers something else than the theory. The course program keeps them as DIFF lines, so that CI notices if a later GA commit changes them; they are also in the journal.
== Surprises found while writing this lessoncall course GA checkPitch.Flat.DFlat(4) Db4 D4 DIFFPitch.Flat.GFlat(4) Gb4 A4 DIFFPitch.Flat.FFlat(4) Fb4 G4 DIFFPitch.Sharp.TryParse Eb2 rejected B2 DIFFNote.Flat.Parse B B Bb DIFFPitchClass.Parse A 9 10 DIFFIntervalSize.TryParse x False throws ArgumentException DIFFPitch.Flat.DFlat(octave),FFlatandGFlatbuild D, G and A instead of D♭, F♭ and G♭. The propertiesDFlat4and friends are right; only the methods are wrong.PitchParsersearches its pattern([A-G])(#?)(10|11|[0-9])without^…$anchors and ignores case: in"Eb2", the sharp parser skips the E and matchesb2as B2.Note.Flat.TryParseupper-cases its input before replacing♭withb, then treats a trailingBas a flat sign. Those two lines break it in both directions:"B"itself becomes B♭, and a real"D♭"is rejected, because the replacement leaves a lowercasebwhere the case-sensitiveEndsWith("B")no longer recognises it.PitchClass.TryParsereadsAandBas the digits 10 and 11, on purpose: the comment calls them “common hex-like aliases sometimes used in set notation”. The convention is real; the bug is the order. The aliases are tried before the note names, so"A"is pitch class 10 and the note A, pitch class 9, can never be parsed at all.SimpleIntervalSize.TryParsethrows on bad input instead of returningfalse, unlike theIParsable<TSelf>.TryParsecontract, andCompoundIntervalSize.TryParsedoes the same. The table shortens the name: the type isSimpleIntervalSize.
Exercises
Section titled “Exercises”- Which pitch, MIDI number and pitch class is string 4, fret 7 in standard tuning?
- Name the intervals E–B♭ and A–C♯, with their size in semitones and their interval class.
- In drop D tuning, string 6 is lowered to D2 (Guitar tunings). Where is pitch class D on frets 0 to 5? Build that fretboard with GA’s
TuningandFretboardtypes.
Solutions
-
String 4 is D3 (MIDI 50); seven frets higher is A3, MIDI 57, pitch class 9.
-
E to B♭ covers five letters (E F G A B) and 6 semitones, one less than a perfect fifth: a diminished fifth, interval class 6. A to C♯ covers three letters and 4 semitones: a major third, interval class 4.
-
Strings 6 and 4 open, string 5 fret 5 and string 2 fret 3. With GA, a tuning is a parsed pitch collection (
Lesson1.cs):var dropD = new Fretboard(new Tuning(PitchCollection.Parse("D2 A2 D3 G3 B3 E4")), 5);var positions = dropD.GetPositionsForNote(Note.Chromatic.D);== Exercise solutionsquestion course GA check1. string 4, fret 7 A3 midi 57 pc 9 A3 midi 57 pc 9 ok2. E-Bb d5 6 ic6 d5 6 ic6 ok2. A-C# M3 4 ic4 M3 4 ic4 ok3. D in drop D, 0-5 6/0 5/5 4/0 2/3 6/0 5/5 4/0 2/3 ok
Key takeaways
Section titled “Key takeaways”- A pitch is a pitch class plus an octave; with MIDI numbers,
pitch class = midi % 12and middle C is 60. - A note name is a letter plus accidentals; several names share a pitch class. GA keeps both:
PitchClassfor the number, theNoterecords for the spelling. - An interval’s number comes from the letters and its quality from the semitones; the interval class forgets both the direction and the octave.
- On a guitar, a position is a string and a fret: the open string’s pitch plus one semitone per fret. GA numbers strings from the highest, like guitarists.
- GA’s primitives are small value objects,
readonly record structs that validate or normalize their range, and records for the unions: the same modelling you would use for money or identifiers.
Sources
Section titled “Sources”- Mark Gotham et al., Open Music Theory, version 2, 2023: chapters Pitch and Pitch Class, ASPN, Intervals, Intervals in Integer Notation, Set Class and Prime Form. The book is published under CC BY-SA 4.0.
- MIDI tuning standard (MIDI 60 = C4, 69 = A4) and Guitar tunings (standard and drop D tunings, string numbering), Wikipedia.
- GuitarAlchemist/ga at
a826864:Primitives/Notes,Primitives/Intervals,Theory/Atonal/PitchClass.cs,Instruments.