### Installing and Building the MusicTheory Library via Bash Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/overview.md These bash commands provide a step-by-step guide for setting up the MusicTheory library from its GitHub repository. It covers cloning the project, building the solution using `dotnet build`, and verifying the setup by running the unit tests with `dotnet test`, ensuring a functional development environment. ```bash git clone https://github.com/phmatray/MusicTheory.git cd MusicTheory dotnet build dotnet test ``` -------------------------------- ### C# Class Definition Example Adhering to Style Guide Source: https://github.com/phmatray/musictheory/blob/main/CONTRIBUTING.md A C# class example demonstrating coding conventions such as PascalCase for public members, camelCase for private fields, and XML documentation for methods, as outlined in the project's style guide. ```csharp public class Scale { private readonly Note root; public Note Root => root; public ScaleType Type { get; } public Scale(Note root, ScaleType type) { this.root = root ?? throw new ArgumentNullException(nameof(root)); Type = type; } /// /// Gets the notes in the scale. /// /// An enumerable of notes in the scale. public IEnumerable GetNotes() { // Implementation } } ``` -------------------------------- ### Convert Between Musical Notation and MIDI in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/getting-started.md Illustrates the conversion between musical notes and MIDI numbers, including handling preferences for flats/sharps and calculating note frequencies. It shows how to get a MIDI number from a `Note` object and create a `Note` from a MIDI number. ```C# // Note to MIDI var c4 = new Note(NoteName.C, Alteration.Natural, 4); int midiNumber = c4.MidiNumber; // 60 // MIDI to Note var note = Note.FromMidiNumber(69); // A4 var flatNote = Note.FromMidiNumber(61, preferFlats: true); // Db4 instead of C#4 // Check frequency double frequency = c4.Frequency; // 261.63 Hz (using A4 = 440 Hz) ``` -------------------------------- ### Creating Notes in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/getting-started.md Demonstrates how to instantiate Note objects in C# using constructors with specific names, alterations, and octaves, parsing from string notation (e.g., 'C#4'), and creating from MIDI numbers. Notes are the fundamental building blocks for all other musical constructs. ```C# // Create notes using constructor var c4 = new Note(NoteName.C, Alteration.Natural, 4); var fSharp5 = new Note(NoteName.F, Alteration.Sharp, 5); var bFlat3 = new Note(NoteName.B, Alteration.Flat, 3); // Parse from string notation var note = Note.Parse("C#4"); var anotherNote = Note.Parse("Eb5"); // Create from MIDI number var middleC = Note.FromMidiNumber(60); var a440 = Note.FromMidiNumber(69); ``` -------------------------------- ### Working with Chord Progressions in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/getting-started.md Demonstrates how to create and analyze chord progressions using Roman numeral analysis within a specified key signature in C#. This includes obtaining diatonic chords for a key, parsing a progression from Roman numerals, and retrieving specific chords by their degree. ```C# // Create a key signature var key = new KeySignature(new Note(NoteName.C), KeyMode.Major); // Create a progression var progression = new ChordProgression(key); // Get diatonic chords var chords = progression.GetDiatonicChords(); // I, ii, iii, IV, V, vi, vii° // Parse Roman numerals var iiVi = progression.ParseProgression("ii - V - I"); // Get specific chord by degree var dominant = progression.GetChordByDegree(5); // G major ``` -------------------------------- ### Building and Manipulating Chords in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/getting-started.md Demonstrates how to create various chord types (including triads, seventh chords, extended, altered, and suspended chords) using the MusicTheory library in C#. It also shows how to retrieve the individual notes that form a chord and obtain its symbolic representation. ```C# // Triads var cMajor = new Chord(c4, ChordType.Major); var aMinor = new Chord(new Note(NoteName.A), ChordType.Minor); var bDim = new Chord(new Note(NoteName.B), ChordType.Diminished); var fAug = new Chord(new Note(NoteName.F), ChordType.Augmented); // Get chord notes var notes = cMajor.GetNotes(); // Returns C, E, G // Seventh chords var cMaj7 = new Chord(c4, ChordType.Major7); var dm7 = new Chord(new Note(NoteName.D), ChordType.Minor7); var g7 = new Chord(new Note(NoteName.G), ChordType.Dominant7); var bHalfDim = new Chord(new Note(NoteName.B), ChordType.HalfDiminished7); // Get chord symbol Console.WriteLine(cMaj7.GetSymbol()); // "Cmaj7" Console.WriteLine(bHalfDim.GetSymbol()); // "Bø7" // Extended and altered chords var cMaj9 = new Chord(c4, ChordType.Major9); var dm11 = new Chord(new Note(NoteName.D), ChordType.Minor11); var g13 = new Chord(new Note(NoteName.G), ChordType.Dominant13); var g7b9 = new Chord(new Note(NoteName.G), ChordType.Dominant7Flat9); var alt = new Chord(new Note(NoteName.C), ChordType.Dominant7Alt); // Suspended chords var csus2 = new Chord(c4, ChordType.Sus2); var gsus4 = new Chord(new Note(NoteName.G), ChordType.Sus4); ``` -------------------------------- ### Transpose Musical Elements in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/getting-started.md Demonstrates how to transpose musical notes, chords, and scales using the library's `Transpose` and `TransposeBySemitones` methods. It highlights the immutability of objects, returning new instances after transposition. ```C# // Transpose a note var c = new Note(NoteName.C, Alteration.Natural, 4); var d = c.Transpose(new Interval(IntervalQuality.Major, 2), Direction.Up); // Transpose by semitones var eb = c.TransposeBySemitones(3); // Transpose a chord var cMajor = new Chord(c, ChordType.Major); var dMajor = cMajor.Transpose(new Interval(IntervalQuality.Major, 2)); // Transpose a scale var cScale = new Scale(c, ScaleType.Major); var gScale = cScale.Transpose(new Interval(IntervalQuality.Perfect, 5)); ``` -------------------------------- ### Generating and Querying Scales in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/getting-started.md Explains how to create various traditional and modal scales in C# using a root note and a scale type. It also demonstrates how to retrieve all notes within a scale, check if a specific note is contained in the scale, and determine a note's degree within the scale. ```C# // Traditional scales var cMajor = new Scale(c4, ScaleType.Major); var aMinor = new Scale(new Note(NoteName.A), ScaleType.NaturalMinor); var dHarmonic = new Scale(new Note(NoteName.D), ScaleType.HarmonicMinor); // Modal scales var dDorian = new Scale(new Note(NoteName.D), ScaleType.Dorian); var ePhrygian = new Scale(new Note(NoteName.E), ScaleType.Phrygian); var fLydian = new Scale(new Note(NoteName.F), ScaleType.Lydian); // Get scale notes var notes = cMajor.GetNotes(); // C, D, E, F, G, A, B, C // Check if a note is in the scale var isInScale = cMajor.Contains(new Note(NoteName.F, Alteration.Sharp)); // false // Get scale degree var degree = cMajor.GetDegree(new Note(NoteName.G)); // 5 ``` -------------------------------- ### Creating a Blues Scale Lick in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/examples.md Demonstrates how to construct a simple blues lick using notes from a `Blues` scale. It also shows how to add octave variations to notes using `TransposeBySemitones`. ```C# // A blues scale var aBlues = new Scale(new Note(NoteName.A, 3), ScaleType.Blues); var bluesNotes = aBlues.GetNotes().Take(6).ToList(); // Create a simple blues lick var lick = new[] { bluesNotes[0], // A (root) bluesNotes[2], // D (4th) bluesNotes[3], // Eb (b5 - blue note) bluesNotes[4], // E (5th) bluesNotes[2], // D bluesNotes[0] // A }; // Add some octave variation var lickWithOctaves = new[] { lick[0], lick[1], lick[2], lick[3].TransposeBySemitones(12), // E up an octave lick[4], lick[5].TransposeBySemitones(-12) // A down an octave }; ``` -------------------------------- ### Install and Build MusicTheory Library Source: https://github.com/phmatray/musictheory/blob/main/README.md Instructions for cloning the MusicTheory repository, building the solution, and running tests using the .NET CLI. This snippet provides the necessary steps to set up the development environment for the library. ```bash git clone https://github.com/phmatray/MusicTheory.git cd MusicTheory dotnet build dotnet test ``` -------------------------------- ### Transposing Chords in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/examples.md Shows how to transpose a sequence of chords from one key to another using `Interval`. It defines an original chord progression and applies a perfect 5th transposition to each chord. ```C# // Original song in C major var originalKey = new KeySignature(new Note(NoteName.C), KeyMode.Major); var originalChords = new[] { new Chord(new Note(NoteName.C, 4), ChordType.Major), new Chord(new Note(NoteName.A, 3), ChordType.Minor), new Chord(new Note(NoteName.F, 4), ChordType.Major), new Chord(new Note(NoteName.G, 4), ChordType.Major) }; // Transpose to G major (up a perfect 5th) var transpositionInterval = new Interval(IntervalQuality.Perfect, 5); var transposedChords = originalChords .Select(chord => chord.Transpose(transpositionInterval)) .ToList(); // Result: G, Em, C, D foreach (var chord in transposedChords) { Console.WriteLine(chord.GetSymbol()); } ``` -------------------------------- ### Working with Intervals in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/getting-started.md Illustrates how to create Interval objects with specific qualities and sizes, calculate the interval between two existing notes, and transpose notes by a given interval in C#. Intervals represent the musical distance between notes. ```C# // Create intervals var perfectFifth = new Interval(IntervalQuality.Perfect, 5); var majorThird = new Interval(IntervalQuality.Major, 3); var minorSeventh = new Interval(IntervalQuality.Minor, 7); // Calculate interval between two notes var c = new Note(NoteName.C, Alteration.Natural, 4); var g = new Note(NoteName.G, Alteration.Natural, 4); var interval = Interval.Between(c, g); // Perfect Fifth // Transpose notes by intervals var e = c.Transpose(majorThird, Direction.Up); var f = c.Transpose(perfectFifth, Direction.Down); ``` -------------------------------- ### C# Unit Test Example with Shouldly Source: https://github.com/phmatray/musictheory/blob/main/CONTRIBUTING.md An example of a C# unit test using the XUnit framework and Shouldly assertions, demonstrating the Arrange-Act-Assert (AAA) pattern for testing new features. ```csharp [Fact] public void NewFeature_ShouldBehaveCorrectly() { // Arrange var input = new Note(NoteName.C); // Act var result = input.NewMethod(); // Assert result.ShouldBe(expected); } ``` -------------------------------- ### Combine Musical Intervals Conceptually and Programmatically in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/intervals.md This example demonstrates the conceptual addition of musical intervals and how it translates to note transposition. It shows that combining a major third and a minor third results in a perfect fifth when applied sequentially to a starting note, illustrating interval composition. ```C# // Adding intervals (conceptually) var majorThird = new Interval(IntervalQuality.Major, 3); // 4 semitones var minorThird = new Interval(IntervalQuality.Minor, 3); // 3 semitones // Together they make a perfect fifth (7 semitones) var c = new Note(NoteName.C, Alteration.Natural, 4); var e = c.Transpose(majorThird); // E var g = e.Transpose(minorThird); // G // C to G is a perfect fifth ``` -------------------------------- ### Conventional Commits: Generic Example Source: https://github.com/phmatray/musictheory/blob/main/README.md A generic example of a conventional commit message, illustrating the `type(scope): description` format used for consistent commit history. ```Text feat(domain): description ``` -------------------------------- ### Instantiate Chord Objects in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/api-chord.md Demonstrates how to create `Chord` instances using both the `Note, ChordType` and `Note, ChordQuality` constructors. Shows examples for major, minor, dominant, and basic quality chords. ```C# var cMajor = new Chord(new Note(NoteName.C, 4), ChordType.Major); var dm7 = new Chord(new Note(NoteName.D, 4), ChordType.Minor7); var g13 = new Chord(new Note(NoteName.G, 4), ChordType.Dominant13); var cMajorQuality = new Chord(new Note(NoteName.C, 4), ChordQuality.Major); ``` -------------------------------- ### Apply Voice Leading Principles in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/chord-progressions.md Provides C# examples demonstrating good voice leading practices for smooth chord transitions, highlighting common tones between chords and the use of inversions to improve voice leading. ```C# // Good voice leading example var smoothProg = prog.ParseProgression("I - vi - ii - V"); // Each chord shares common tones with the next: // C (C-E-G) → Am (A-C-E) - Common tones: C, E // Am (A-C-E) → Dm (D-F-A) - Common tone: A // Dm (D-F-A) → G (G-B-D) - Common tone: D // Consider inversions for smoother voice leading var c = new Chord(new Note(NoteName.C, 4), ChordType.Major); var am = new Chord(new Note(NoteName.A, 3), ChordType.Minor) .WithInversion(ChordInversion.First); // C in bass var dm = new Chord(new Note(NoteName.D, 4), ChordType.Minor); var g = new Chord(new Note(NoteName.G, 3), ChordType.Major); ``` -------------------------------- ### Building Basic Diatonic Chords in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/examples.md Illustrates how to generate all diatonic triads for a given key signature (C major) using `KeySignature` and `ChordProgression`. It then prints the chord symbols and their Roman numeral degrees. ```C# // Create all triads in C major var key = new KeySignature(new Note(NoteName.C), KeyMode.Major); var progression = new ChordProgression(key); var diatonicChords = progression.GetDiatonicChords().ToList(); // Print chord symbols foreach (var (chord, degree) in diatonicChords.Select((c, i) => (c, i + 1))) { var roman = progression.GetRomanNumeral(degree); Console.WriteLine($"{roman}: {chord.GetSymbol()}"); } // Output: // I: C // ii: Dm // iii: Em // IV: F // V: G // vi: Am // vii°: B° ``` -------------------------------- ### Generate Major Scales Across All Keys in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/examples.md This C# example illustrates the programmatic generation of major scales for all twelve chromatic notes. It constructs `Scale` objects from `Note` roots and displays the constituent notes, showcasing fundamental music theory object usage. ```C# // Generate major scales in all 12 keys var scalesByKey = new Dictionary(); var chromaticNotes = new[] { new Note(NoteName.C), new Note(NoteName.D, Alteration.Flat), new Note(NoteName.D), new Note(NoteName.E, Alteration.Flat), new Note(NoteName.E), new Note(NoteName.F), new Note(NoteName.G, Alteration.Flat), new Note(NoteName.G), new Note(NoteName.A, Alteration.Flat), new Note(NoteName.A), new Note(NoteName.B, Alteration.Flat), new Note(NoteName.B) }; foreach (var root in chromaticNotes) { var scale = new Scale(root, ScaleType.Major); var keyName = root.ToString(); scalesByKey[keyName] = scale; var notes = scale.GetNotes().Take(7).Select(n => n.ToString()); Console.WriteLine($"{keyName} Major: {string.Join(" ", notes)}"); } ``` -------------------------------- ### Applying Chord Substitutions in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/examples.md Explains how to perform a tritone substitution on a dominant 7th chord within a ii-V-I progression. It shows the original chords and the substituted progression, highlighting the resolution difference. ```C# // Original ii-V-I in C major var dm7 = new Chord(new Note(NoteName.D, 4), ChordType.Minor7); var g7 = new Chord(new Note(NoteName.G, 3), ChordType.Dominant7); var cMaj7 = new Chord(new Note(NoteName.C, 4), ChordType.Major7); // Tritone substitution on V7 var db7 = new Chord(new Note(NoteName.D, Alteration.Flat, 3), ChordType.Dominant7); // New progression: ii-V-I with tritone sub var substitutedProgression = new[] { dm7, db7, cMaj7 }; // The Db7 resolves to C by half-step instead of fifth ``` -------------------------------- ### Explore and Display the Circle of Fifths in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/examples.md This C# class provides functionality to programmatically traverse and display the Circle of Fifths. It calculates and presents the number of sharps or flats for each major key, leveraging `KeySignature` and `Note` objects to represent musical keys. ```C# public class CircleOfFifthsExplorer { public void ExploreCircle(bool clockwise = true) { var current = new KeySignature(new Note(NoteName.C), KeyMode.Major); var keys = new List { current }; // Go around the circle for (int i = 0; i < 11; i++) { current = clockwise ? current.NextInCircle() : current.PreviousInCircle(); keys.Add(current); } // Display results Console.WriteLine($"Circle of Fifths ({(clockwise ? "Clockwise" : "Counter-clockwise")}):"); foreach (var key in keys) { var sharpsFlats = key.AccidentalCount > 0 ? $"{key.AccidentalCount} sharps" : key.AccidentalCount < 0 ? $"{-key.AccidentalCount} flats" : "no sharps/flats"; Console.WriteLine($"{key.Tonic} major: {sharpsFlats}"); } } } ``` -------------------------------- ### Create KeySignature Instances in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/api-keysignature.md Demonstrates how to instantiate `KeySignature` objects using different tonic notes and modes, including examples with natural, sharp, and flat alterations. ```C# var cMajor = new KeySignature(new Note(NoteName.C), KeyMode.Major); var aMinor = new KeySignature(new Note(NoteName.A), KeyMode.Minor); var gMajor = new KeySignature(new Note(NoteName.G), KeyMode.Major); var ebMinor = new KeySignature(new Note(NoteName.E, Alteration.Flat), KeyMode.Minor); ``` -------------------------------- ### C# Interval Class Usage Examples Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/api-overview.md Illustrates construction, property access (Semitones, ToString), static factory methods (Between), and instance methods (IsEnharmonicWith, Invert) for the `Interval` class, demonstrating how to work with musical distances. ```C# // Construction var interval = new Interval(IntervalQuality.Major, 3); // Properties int semitones = interval.Semitones; // 4 string name = interval.ToString(); // "Major 3rd" // Static factory var between = Interval.Between(note1, note2); // Methods bool isEnharmonic = interval.IsEnharmonicWith(otherInterval); var inverted = interval.Invert(); ``` -------------------------------- ### Performing Operations on Note Collections in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/notes.md Shows examples of common operations with multiple notes, including creating a chromatic scale, finding the interval between two notes, and checking octave relationships and note classes. ```C# // Create a chromatic scale var chromaticScale = new List(); var c4 = new Note(NoteName.C, Alteration.Natural, 4); for (int i = 0; i < 12; i++) { chromaticScale.Add(c4.TransposeBySemitones(i)); } // Find interval between notes var e4 = new Note(NoteName.E, Alteration.Natural, 4); var interval = Interval.Between(c4, e4); // Major third // Check octave relationships var c5 = new Note(NoteName.C, Alteration.Natural, 5); bool isSameNoteClass = c4.Name == c5.Name; // true int octaveDifference = c5.Octave - c4.Octave; // 1 ``` -------------------------------- ### Build Musical Scales Using Intervals in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/intervals.md This example illustrates how to define a musical scale pattern using an array of `Interval` objects. It then shows how to apply these intervals to a root `Note` to generate the notes of a complete scale, such as a C major scale. ```C# // Major scale intervals from root var majorScaleIntervals = new[] { new Interval(IntervalQuality.Perfect, 1), // Root new Interval(IntervalQuality.Major, 2), // Major 2nd new Interval(IntervalQuality.Major, 3), // Major 3rd new Interval(IntervalQuality.Perfect, 4), // Perfect 4th new Interval(IntervalQuality.Perfect, 5), // Perfect 5th new Interval(IntervalQuality.Major, 6), // Major 6th new Interval(IntervalQuality.Major, 7), // Major 7th new Interval(IntervalQuality.Perfect, 8) // Octave }; // Build C major scale var c = new Note(NoteName.C, Alteration.Natural, 4); var cMajorScale = majorScaleIntervals .Select(interval => c.Transpose(interval)) .ToList(); ``` -------------------------------- ### C# Chord Class Usage Examples Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/api-overview.md Covers construction, property access (Root, Type), and methods (GetNotes, GetSymbol, Transpose, GetEnharmonicEquivalent) for the `Chord` class, demonstrating how to work with musical chords. ```C# // Construction var chord = new Chord(root, ChordType.Major7); // Properties Note root = chord.Root; ChordType type = chord.Type; // Methods var notes = chord.GetNotes(); // IEnumerable string symbol = chord.GetSymbol(); // "CMaj7" var transposed = chord.Transpose(interval); var enharmonic = chord.GetEnharmonicEquivalent(); ``` -------------------------------- ### Analyze Chord Progressions in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/examples.md This C# code demonstrates how to parse and analyze chord progressions. It calculates root motion intervals and identifies common tones between consecutive chords, utilizing custom `ChordProgression`, `Interval`, and `Note` objects for music theory computations. ```C# public class ProgressionAnalyzer { private readonly ChordProgression progression; public ProgressionAnalyzer(KeySignature key) { progression = new ChordProgression(key); } public void Analyze(string progressionString) { var chords = progression.ParseProgression(progressionString).ToList(); for (int i = 0; i < chords.Count - 1; i++) { var current = chords[i]; var next = chords[i + 1]; // Analyze movement var rootInterval = Interval.Between(current.Root, next.Root); Console.WriteLine($"{current.GetSymbol()} → {next.GetSymbol()}:"); Console.WriteLine($" Root motion: {rootInterval.Quality} {rootInterval.Number}"); // Check for common tones var currentNotes = current.GetNotes().ToList(); var nextNotes = next.GetNotes().ToList(); var commonTones = currentNotes.Intersect(nextNotes, new NoteComparer()).ToList(); Console.WriteLine($" Common tones: {string.Join(", ", commonTones)}"); } } } // Usage var analyzer = new ProgressionAnalyzer( new KeySignature(new Note(NoteName.C), KeyMode.Major) ); analyzer.Analyze("I - vi - ii - V"); ``` -------------------------------- ### Create Notes from MIDI Numbers in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/notes.md Shows how to convert MIDI note numbers to `Note` objects in C#. Examples include common MIDI numbers like Middle C (60) and A440 (69), and demonstrate the `preferFlats` option for black keys. ```C# // Middle C (MIDI 60) var middleC = Note.FromMidiNumber(60); // A440 (MIDI 69) var a440 = Note.FromMidiNumber(69); // Prefer flats for black keys var db4 = Note.FromMidiNumber(61, preferFlats: true); // Db4 instead of C#4 var eb4 = Note.FromMidiNumber(63, preferFlats: true); // Eb4 instead of D#4 ``` -------------------------------- ### Working with Chord Progressions and Diatonic Chords in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/chords.md Illustrates how to define a key signature and create a `ChordProgression` object. It shows methods for retrieving diatonic chords, parsing common progressions (e.g., ii-V-I, I-V-vi-IV), and getting chords by their scale degree. ```C# // Define the key var cMajorKey = new KeySignature(new Note(NoteName.C), KeyMode.Major); var progression = new ChordProgression(cMajorKey); // Get diatonic chords var diatonicChords = progression.GetDiatonicChords().ToList(); // I (C), ii (Dm), iii (Em), IV (F), V (G), vi (Am), vii° (Bdim) // Common progressions var twoFiveOne = progression.ParseProgression("ii7 - V7 - IMaj7"); var popProgression = progression.ParseProgression("I - V - vi - IV"); // Get chord by scale degree var dominant = progression.GetChordByDegree(5); // G major var submediant = progression.GetChordByDegree(6); // A minor ``` -------------------------------- ### Creating Complex Jazz Voicings in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/examples.md Shows how to construct extended jazz chords like Cmaj7#11 and C13(#11) using the `AddExtension` method. It also demonstrates how to extract all notes of a voicing and create a rootless voicing, common in jazz piano. ```C# // Create extended jazz chords var root = new Note(NoteName.C, 4); // Cmaj7#11 var cMaj7Sharp11 = new Chord(root, ChordType.Major7) .AddExtension(11, IntervalQuality.Augmented); // C13(#11) var c13Sharp11 = new Chord(root, ChordType.Dominant13) .AddExtension(11, IntervalQuality.Augmented); // Get all notes var voicing = c13Sharp11.GetNotes().ToList(); // C, E, G, Bb, D, F#, A // Create rootless voicing (common in jazz piano) var rootless = voicing.Skip(1).ToList(); // Remove root // E, G, Bb, D, F#, A ``` -------------------------------- ### C# Note Class Usage Examples Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/api-overview.md Demonstrates construction, property access (MidiNumber, Frequency, SemitonesFromC), and methods (Transpose, IsEnharmonicWith, GetEnharmonicEquivalent) for the `Note` class, including static factory methods like `FromMidiNumber` and `TryParse`. ```C# // Construction var note = new Note(NoteName.C, Alteration.Sharp, 4); // Properties int midiNumber = note.MidiNumber; // 61 double frequency = note.Frequency; // 277.18 Hz int semitones = note.SemitonesFromC; // 1 // Methods var transposed = note.Transpose(interval); var bySteps = note.TransposeBySemitones(5); bool isEnharmonic = note.IsEnharmonicWith(otherNote); var equivalent = note.GetEnharmonicEquivalent(); // Static methods var fromMidi = Note.FromMidiNumber(60); bool parsed = Note.TryParse("C#4", out var parsedNote); ``` -------------------------------- ### Creating Chord Progressions in MusicTheory.NET Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/faq.md This C# example illustrates how to create and parse chord progressions using the ChordProgression class in MusicTheory.NET, allowing for parsing Roman numerals or retrieving individual chords by degree within a specified key signature. ```C# var key = new KeySignature(new Note(NoteName.C), KeyMode.Major); var progression = new ChordProgression(key); // Parse Roman numerals var chords = progression.ParseProgression("I - vi - IV - V"); // Or get individual chords var tonic = progression.GetChordByDegree(1); var dominant = progression.GetChordByDegree(5); ``` -------------------------------- ### Identify Enharmonic Key Equivalents (C#) Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/key-signatures.md Illustrates how to work with enharmonic key signatures, which sound identical but are spelled differently (e.g., F# major and Gb major). The example shows how to retrieve enharmonic equivalents using the library's functionality. ```C# // F# major and Gb major are enharmonic var fSharpMajor = new KeySignature( new Note(NoteName.F, Alteration.Sharp), KeyMode.Major ); // 6 sharps var gbMajor = new KeySignature( new Note(NoteName.G, Alteration.Flat), KeyMode.Major ); // 6 flats // Get enharmonic equivalents var enharmonics = fSharpMajor.GetEnharmonicEquivalents(); // Returns Gb major // Common enharmonic pairs: // C# major (7 sharps) = Db major (5 flats) // F# major (6 sharps) = Gb major (6 flats) // B major (5 sharps) = Cb major (7 flats) ``` -------------------------------- ### Build and Test Commands for .NET Project Source: https://github.com/phmatray/musictheory/blob/main/CLAUDE.md Provides a set of `dotnet` commands for building the solution, running all tests, running tests with detailed output, running a specific test by filter, and running tests for a specific class within the `phmatray/musictheory` repository. ```bash # Build the solution dotnet build # Run all tests dotnet test # Run tests with detailed output dotnet test --logger "console;verbosity=detailed" # Run a specific test dotnet test --filter "FullyQualifiedName~ScaleTests.Scale_ShouldGenerateCorrectNotes_ForGMajor" # Run tests for a specific class dotnet test --filter "ClassName=NoteTests" ``` -------------------------------- ### Building the Music Theory Library Source: https://github.com/phmatray/musictheory/blob/main/README.md Instructions for setting up the development environment and building the C# music theory library from source. This covers cloning the repository, restoring NuGet packages, and compiling the project using standard `dotnet` commands. ```bash git clone https://github.com/phmatray/MusicTheory.git cd MusicTheory dotnet restore dotnet build ``` -------------------------------- ### Understand Relative and Parallel Scale Relationships in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/scales.md Explains the concepts of relative major/minor (scales sharing the same notes but starting on different tonics) and parallel major/minor (scales sharing the same tonic but having different notes) using C# `Scale` objects as examples. ```C# // Relative major/minor var cMajor = new Scale(new Note(NoteName.C, 4), ScaleType.Major); var aMinor = new Scale(new Note(NoteName.A, 3), ScaleType.NaturalMinor); // Same notes, different tonic // Parallel major/minor var cMinor = new Scale(new Note(NoteName.C, 4), ScaleType.NaturalMinor); // Same tonic, different notes (Eb, Ab, Bb instead of E, A, B) ``` -------------------------------- ### Running Tests for the Music Theory Library Source: https://github.com/phmatray/musictheory/blob/main/README.md Provides command-line instructions for executing the comprehensive test suite of the music theory library. This includes running all tests, specific test classes, and generating code coverage reports using the `dotnet test` command. ```bash # Run all tests dotnet test # Run with detailed output dotnet test --logger "console;verbosity=detailed" # Run specific test class dotnet test --filter "ClassName=NoteTests" # Generate code coverage dotnet run --project MusicTheory.UnitTests -- --coverage ``` -------------------------------- ### Initialize Key Signatures and Chord Progressions in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/chord-progressions.md Demonstrates how to define `KeySignature` objects for major and minor keys, and then initialize `ChordProgression` instances using these key signatures, setting up the foundation for harmonic analysis. ```C# // Define the key var cMajor = new KeySignature(new Note(NoteName.C), KeyMode.Major); var aMinor = new KeySignature(new Note(NoteName.A), KeyMode.Minor); // Create progression objects var majorProgression = new ChordProgression(cMajor); var minorProgression = new ChordProgression(aMinor); ``` -------------------------------- ### Convert Chords to MIDI Numbers in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/midi-integration.md This snippet presents the 'MidiChordHelper' class, designed to extract MIDI numbers from a 'Chord' object. It includes two methods: 'GetMidiNumbers' returns a simple list of MIDI integers, while 'GetMidiMap' provides a dictionary mapping musical degrees (Root, Third, Fifth, etc.) to their corresponding MIDI numbers. Usage examples demonstrate how to get MIDI data for a C Major 7th chord. ```C# public class MidiChordHelper { public static List GetMidiNumbers(Chord chord) { return chord.GetNotes() .Select(note => note.MidiNumber) .ToList(); } public static Dictionary GetMidiMap(Chord chord) { var notes = chord.GetNotes().ToList(); var degrees = new[] { "Root", "Third", "Fifth", "Seventh", "Ninth", "Eleventh", "Thirteenth" }; var map = new Dictionary(); for (int i = 0; i < notes.Count && i < degrees.Length; i++) { map[degrees[i]] = notes[i].MidiNumber; } return map; } } // Usage var cMaj7 = new Chord(new Note(NoteName.C, 4), ChordType.Major7); var midiNumbers = MidiChordHelper.GetMidiNumbers(cMaj7); // [60, 64, 67, 71] (C, E, G, B) var midiMap = MidiChordHelper.GetMidiMap(cMaj7); // { "Root": 60, "Third": 64, "Fifth": 67, "Seventh": 71 } ``` -------------------------------- ### Conventional Commits: Feature Example Source: https://github.com/phmatray/musictheory/blob/main/README.md An example of a commit message adhering to the Conventional Commits specification, specifically for adding a new feature with a defined scope. ```Text feat(scales): add modal scales ``` -------------------------------- ### Simulate MIDI Playback for Chords and Arpeggios in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/examples.md This C# class demonstrates converting musical chords into MIDI note numbers and simulating their playback. It includes methods for playing individual notes as arpeggios and entire chord progressions, relying on `Chord` and `ChordProgression` objects for musical data. ```C# public class MidiChordPlayer { public List GetMidiNumbers(Chord chord) { return chord.GetNotes() .Select(note => note.MidiNumber) .ToList(); } public void PlayArpeggio(Chord chord, int delayMs = 100) { var midiNumbers = GetMidiNumbers(chord); foreach (var midiNumber in midiNumbers) { Console.WriteLine($"Play MIDI note: {midiNumber}"); // In real implementation, send MIDI message Thread.Sleep(delayMs); } } public void PlayChordProgression(string progression, KeySignature key) { var prog = new ChordProgression(key); var chords = prog.ParseProgression(progression); foreach (var chord in chords) { var midiNotes = GetMidiNumbers(chord); Console.WriteLine($"{chord.GetSymbol()}: [{string.Join(", ", midiNotes)}]"); // Play chord Thread.Sleep(1000); // 1 second per chord } } } ``` -------------------------------- ### Conventional Commit Message Examples Source: https://github.com/phmatray/musictheory/blob/main/CONTRIBUTING.md Examples of various conventional commit types (`feat`, `fix`, `docs`, `test`) with their respective scopes and messages, illustrating the project's commit message guidelines. ```text feat(scale): add harmonic major scale type fix(chord): correct enharmonic calculation for augmented chords docs(readme): add examples for chord progressions test(interval): add edge cases for compound intervals ``` -------------------------------- ### KeySignature Class API Documentation Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/api-keysignature.md Detailed API documentation for the `KeySignature` class, outlining its constructors, properties, and instance methods. This includes how to create key signatures, access their musical properties, and perform operations like finding relative/parallel keys, enharmonic equivalents, and navigating the circle of fifths. ```APIDOC KeySignature Class: Description: Represents a musical key signature, including its tonic, mode, accidental count, and altered notes. Implements IEquatable. Constructors: KeySignature(Note tonic, KeyMode mode) Description: Creates a new key signature with the specified tonic and mode. Parameters: - tonic: The tonic (root) note of the key (Type: Note) - mode: The mode (Major or Minor) (Type: KeyMode) Properties: Tonic: Note { get; } Description: Gets the tonic (root) note of the key. Mode: KeyMode { get; } Description: Gets the mode (Major or Minor). AccidentalCount: int { get; } Description: Gets the number of accidentals in the key signature. - Positive values indicate sharps - Negative values indicate flats - Zero indicates no accidentals (C major/A minor) Examples: C major: 0, G major: 1 (one sharp), F major: -1 (one flat), D major: 2 (two sharps), Bb major: -2 (two flats) AlteredNotes: List { get; } Description: Gets the list of note names that are altered in this key. Order (Sharps): F, C, G, D, A, E, B Order (Flats): B, E, A, D, G, C, F Instance Methods: GetAlteration(NoteName noteName): Alteration Description: Gets the alteration for a specific note in this key. Parameters: - noteName: The note name to check (Type: NoteName) Returns: The alteration (Sharp, Flat, or Natural) GetRelativeKey(): KeySignature Description: Gets the relative major or minor key. Returns: - For major keys: the relative minor (down a minor 3rd) - For minor keys: the relative major (up a minor 3rd) GetParallelKey(): KeySignature Description: Gets the parallel major or minor key. Returns: The key with the same tonic but opposite mode GetEnharmonicEquivalents(): List Description: Gets enharmonically equivalent key signatures. Returns: List of enharmonic keys (e.g., C# major ↔ Db major) NextInCircle(Direction direction = Direction.Up): KeySignature Description: Gets the next key in the circle of fifths. Parameters: - direction: Up for clockwise/sharps, Down for counterclockwise/flats (Type: Direction, Default: Direction.Up) Returns: The next key in the circle of fifths PreviousInCircle(): KeySignature Description: Gets the previous key in the circle of fifths. Returns: The previous key (equivalent to NextInCircle(Direction.Down)) ToString(): string Description: Returns a string representation of the key signature. Format: "{Tonic} {mode}" Examples: "C major", "A minor", "G major", "Eb minor" ``` -------------------------------- ### C# Modulating Chord Progression Example Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/transposition.md This C# example illustrates how to modulate a chord progression chromatically within a musical piece. It takes an array of chords and transposes each chord by a specified number of semitones, demonstrating a technique for creating dramatic effects in music. ```C# // Start in C major var section1 = new[] { new Chord(new Note(NoteName.C), ChordType.Major), new Chord(new Note(NoteName.F), ChordType.Major), new Chord(new Note(NoteName.G), ChordType.Major) }; // Modulate up a half step for dramatic effect var section2 = section1 .Select(chord => chord.TransposeBySemitones(1)) .ToArray(); // Db, Gb, Ab ``` -------------------------------- ### C# Transposing Song Key Example Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/transposition.md This C# example demonstrates how to transpose an entire song's key by calculating the interval between the original and new tonic notes. It applies this interval to a melody to shift it to the desired key, illustrating a common use case for musical transposition. ```C# // Original song in G major var originalKey = new KeySignature(new Note(NoteName.G), KeyMode.Major); // Singer needs it in E major (down a minor 3rd) var newKey = new KeySignature(new Note(NoteName.E), KeyMode.Major); var interval = Interval.Between(originalKey.Tonic, newKey.Tonic); // Transpose all elements var originalMelody = new[] { /* notes */ }; var transposedMelody = originalMelody .Select(n => n.Transpose(interval)) .ToArray(); ``` -------------------------------- ### Use Chord Instance Methods in C# Source: https://github.com/phmatray/musictheory/blob/main/Writerside/topics/api-chord.md Examples of using `Chord` instance methods like `GetNotes()`, `Transpose()`, and `GetEnharmonicEquivalent()` to manipulate and retrieve information about chords. ```C# var cMaj7 = new Chord(new Note(NoteName.C, 4), ChordType.Major7); var notes = cMaj7.GetNotes().ToList(); // [C4, E4, G4, B4] var c7 = new Chord(new Note(NoteName.C, 4), ChordType.Dominant7); var f7 = c7.Transpose(new Interval(IntervalQuality.Perfect, 4)); var cSharpMajor = new Chord(new Note(NoteName.C, Alteration.Sharp, 4), ChordType.Major); var dFlatMajor = cSharpMajor.GetEnharmonicEquivalent(); // Db major; ```