MusicTheory Help

Enharmonic Equivalence

Enharmonic equivalence refers to notes, intervals, or chords that sound the same but are written differently. Understanding enharmonics is crucial for proper music notation and key relationships.

Understanding Enharmonics

Enharmonic Notes

Different spellings of the same pitch (C# = Db, F# = Gb)

Enharmonic Keys

Keys that sound identical but use different notation

Context Matters

The correct spelling depends on the musical context and key

Readability

Proper enharmonic spelling makes music easier to read

Enharmonic Notes

Basic Enharmonic Pairs

// Common enharmonic equivalents var cSharp = new Note(NoteName.C, Alteration.Sharp, 4); var dFlat = new Note(NoteName.D, Alteration.Flat, 4); // Check if they're enharmonic bool areEnharmonic = cSharp.IsEnharmonicWith(dFlat); // true // Get enharmonic equivalent var cSharpEquiv = cSharp.GetEnharmonicEquivalent(); // Db4 var dFlatEquiv = dFlat.GetEnharmonicEquivalent(); // C#4 // Verify same pitch Console.WriteLine(cSharp.MidiNumber == dFlat.MidiNumber); // true (61) Console.WriteLine(cSharp.Frequency == dFlat.Frequency); // true (~277.18 Hz)

All Enharmonic Relationships

Sharp Spelling

Flat Spelling

MIDI Number

C#

Db

61

D#

Eb

63

F#

Gb

66

G#

Ab

68

A#

Bb

70

Note

Enharmonic

Context

B

Cb

Gb major scale

C

B#

C# major scale

E

Fb

Cb major scale

F

E#

F# major scale

Double Sharp

Natural/Sharp

Example

C##

D

A# minor scale

F##

G

G# minor scale

Double Flat

Natural/Flat

Example

Dbb

C

Bbb major

Bbb

A

Diminished 7th

Choosing Correct Spelling

Based on Key Signature

public class EnharmonicSpelling { public static Note SpellNoteInKey(int midiNumber, KeySignature key) { // Basic conversion var note = Note.FromMidiNumber(midiNumber, key.AccidentalCount < 0); // Check if note fits the key var scale = new Scale(key.Tonic, key.Mode == KeyMode.Major ? ScaleType.Major : ScaleType.NaturalMinor); if (scale.Contains(note)) { return note; } // Try enharmonic equivalent var enharmonic = note.GetEnharmonicEquivalent(); if (enharmonic != null && scale.Contains(enharmonic)) { return enharmonic; } // Return original if neither fits perfectly return note; } public static Note SpellChromatic(Note startNote, int semitones) { // Ascending chromatics typically use sharps // Descending chromatics typically use flats if (semitones > 0) { // Ascending - prefer sharps return Note.FromMidiNumber( startNote.MidiNumber + semitones, preferFlats: false ); } else { // Descending - prefer flats return Note.FromMidiNumber( startNote.MidiNumber + semitones, preferFlats: true ); } } } // Examples var gMajor = new KeySignature(new Note(NoteName.G), KeyMode.Major); var note = EnharmonicSpelling.SpellNoteInKey(66, gMajor); // F# (not Gb) var ebMajor = new KeySignature(new Note(NoteName.E, Alteration.Flat), KeyMode.Major); var note2 = EnharmonicSpelling.SpellNoteInKey(68, ebMajor); // Ab (not G#)

Based on Chord Context

public class ChordSpelling { public static List<Note> SpellChordProperly(Chord chord) { var notes = chord.GetNotes().ToList(); var correctedNotes = new List<Note> { notes[0] }; // Keep root // Ensure each scale degree is represented var expectedDegrees = GetExpectedDegrees(chord.Type); for (int i = 1; i < notes.Count; i++) { var note = notes[i]; var expectedDegree = expectedDegrees[i]; // Check if note name matches expected degree var degreeFromRoot = (note.Name - chord.Root.Name + 7) % 7; if (degreeFromRoot != expectedDegree - 1) { // Try enharmonic var enharmonic = note.GetEnharmonicEquivalent(); if (enharmonic != null) { var enhDegree = (enharmonic.Name - chord.Root.Name + 7) % 7; if (enhDegree == expectedDegree - 1) { correctedNotes.Add(enharmonic); continue; } } } correctedNotes.Add(note); } return correctedNotes; } private static List<int> GetExpectedDegrees(ChordType type) { // Return expected scale degrees for chord type return type switch { ChordType.Major => new List<int> { 1, 3, 5 }, ChordType.Minor => new List<int> { 1, 3, 5 }, ChordType.Major7 => new List<int> { 1, 3, 5, 7 }, ChordType.Dominant7 => new List<int> { 1, 3, 5, 7 }, _ => new List<int>() }; } }

Enharmonic Intervals

Interval Enharmonics

// Augmented 4th and Diminished 5th var aug4 = new Interval(IntervalQuality.Augmented, 4); var dim5 = new Interval(IntervalQuality.Diminished, 5); // Both are 6 semitones (tritone) Console.WriteLine(aug4.Semitones); // 6 Console.WriteLine(dim5.Semitones); // 6 Console.WriteLine(aug4.IsEnharmonicWith(dim5)); // true // Context determines spelling var c = new Note(NoteName.C, 4); var fSharp = c.Transpose(aug4); // C to F# (augmented 4th) var gFlat = c.Transpose(dim5); // C to Gb (diminished 5th) // Other enharmonic interval pairs var examples = new[] { (new Interval(IntervalQuality.Minor, 3), new Interval(IntervalQuality.Augmented, 2)), // 3 semitones (new Interval(IntervalQuality.Major, 6), new Interval(IntervalQuality.Diminished, 7)), // 9 semitones (new Interval(IntervalQuality.Augmented, 6), new Interval(IntervalQuality.Minor, 7)) // 10 semitones };

Enharmonic Keys

Key Signature Enharmonics

// Major key enharmonics var cSharpMajor = new KeySignature(new Note(NoteName.C, Alteration.Sharp), KeyMode.Major); var dFlatMajor = new KeySignature(new Note(NoteName.D, Alteration.Flat), KeyMode.Major); // Get enharmonic equivalents var cSharpEnharmonics = cSharpMajor.GetEnharmonicEquivalents(); // Returns Db major // Common enharmonic key pairs var enharmonicPairs = new[] { ("B major (5#)", "Cb major (7b)"), ("F# major (6#)", "Gb major (6b)"), ("C# major (7#)", "Db major (5b)"), ("G# minor (5#)", "Ab minor (7b)"), ("D# minor (6#)", "Eb minor (6b)"), ("A# minor (7#)", "Bb minor (5b)") }; // Choose simpler key signature public KeySignature ChooseSimpleKey(Note tonic, KeyMode mode) { var key1 = new KeySignature(tonic, mode); var enharmonics = key1.GetEnharmonicEquivalents(); if (enharmonics.Any()) { var key2 = enharmonics.First(); // Choose key with fewer accidentals return Math.Abs(key1.AccidentalCount) <= Math.Abs(key2.AccidentalCount) ? key1 : key2; } return key1; }

Enharmonic Chords

Chord Enharmonics

// Enharmonic chord examples var cSharpMajor = new Chord(new Note(NoteName.C, Alteration.Sharp, 4), ChordType.Major); var dFlatMajor = cSharpMajor.GetEnharmonicEquivalent(); Console.WriteLine(cSharpMajor.GetSymbol()); // C# Console.WriteLine(dFlatMajor?.GetSymbol()); // Db // Augmented sixth chords (classical enharmonics) // German 6th in C: Ab-C-Eb-F# // Enharmonically equals dominant 7th: Ab-C-Eb-Gb // Diminished seventh chord (fully symmetric) var dim7 = new Chord(new Note(NoteName.C, 4), ChordType.Diminished7); // C-Eb-Gb-Bbb can be spelled from any note: // C°7 = Eb°7 = Gb°7 = A°7 (enharmonically)

Practical Applications

Smart Transposition

public class SmartTransposer { public static Note TransposeWithContext( Note original, Interval interval, KeySignature targetKey) { // First transpose normally var transposed = original.Transpose(interval); // Check if it fits the target key var scale = new Scale(targetKey.Tonic, targetKey.Mode == KeyMode.Major ? ScaleType.Major : ScaleType.NaturalMinor); if (!scale.Contains(transposed)) { // Try enharmonic var enharmonic = transposed.GetEnharmonicEquivalent(); if (enharmonic != null && scale.Contains(enharmonic)) { return enharmonic; } } return transposed; } }

Readability Optimizer

public class ReadabilityOptimizer { public static Note OptimizeNoteSpelling(Note note) { // Avoid double sharps/flats when possible if (note.Alteration == Alteration.DoubleSharp || note.Alteration == Alteration.DoubleFlat) { var enharmonic = note.GetEnharmonicEquivalent(); if (enharmonic != null && Math.Abs((int)enharmonic.Alteration) < 2) { return enharmonic; } } // Avoid E#, B#, Cb, Fb in isolation var awkwardNotes = new[] { (NoteName.E, Alteration.Sharp), // Use F (NoteName.B, Alteration.Sharp), // Use C (NoteName.C, Alteration.Flat), // Use B (NoteName.F, Alteration.Flat) // Use E }; if (awkwardNotes.Contains((note.Name, note.Alteration))) { var enharmonic = note.GetEnharmonicEquivalent(); if (enharmonic != null) return enharmonic; } return note; } }

Circle of Fifths Navigation

public class CircleOfFifthsEnharmonics { public static void NavigateWithEnharmonics() { var start = new KeySignature(new Note(NoteName.C), KeyMode.Major); var current = start; // Go clockwise (sharps) for (int i = 0; i < 12; i++) { Console.WriteLine($"{current.Tonic} major: {current.AccidentalCount} accidentals"); // Check for enharmonic equivalent var enharmonics = current.GetEnharmonicEquivalents(); if (enharmonics.Any()) { var enh = enharmonics.First(); Console.WriteLine($" = {enh.Tonic} major: {enh.AccidentalCount} accidentals"); } current = current.NextInCircle(); } } }

Best Practices

  • Consider the key: Use spellings that fit the key signature

  • Maintain consistency: Don't mix enharmonic spellings arbitrarily

  • Think melodically: Ascending lines use sharps, descending use flats

  • Simplify when possible: Avoid double sharps/flats unless necessary

  • Respect voice leading: Proper spelling clarifies melodic direction

Common Enharmonic Situations

Leading Tones

// Leading tones should be spelled to show resolution var gMinor = new KeySignature(new Note(NoteName.G), KeyMode.Minor); // Harmonic minor has F# (leading tone to G) // Not Gb, even though they sound the same var harmonicMinor = new Scale(gMinor.Tonic, ScaleType.HarmonicMinor); var leadingTone = harmonicMinor.GetNotes().ElementAt(6); // F#

Chromatic Passages

// Chromatic scale spelling rules public static List<Note> GetChromaticScale(Note start, Direction direction) { var notes = new List<Note> { start }; var current = start; for (int i = 1; i < 12; i++) { if (direction == Direction.Up) { // Ascending: C C# D D# E F F# G G# A A# B current = Note.FromMidiNumber(current.MidiNumber + 1, preferFlats: false); } else { // Descending: C B Bb A Ab G Gb F E Eb D Db current = Note.FromMidiNumber(current.MidiNumber - 1, preferFlats: true); } notes.Add(current); } return notes; }

See Also

13 June 2025