### 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;
```