# MusicKit ### Pitch * `Pitch` is the basic unit of `MusicKit`. * A `Pitch` can be created with a MIDI number, or with a chroma and octave number. ```swift let A4 = Pitch(midi: 69) print(A4.noteName) // A4 print(A4.frequency) // 440.0 let DSharp2 = Pitch(chroma: .Ds, octave: 2) let C5 = Chroma.C*5 ``` * Changing the value of MusicKit's concert A changes the computed frequency of all pitches. ```swift MusicKit.concertA = 444 print(A4.frequency) // 444.0 MusicKit.concertA = 440 ``` ### Chroma * A `Pitch` has a `Chroma` if it has an integral MIDI number. ```swift print(A4.chroma) // Optional(A) let AHalfSharp = Pitch(midi: 69.5) print(AHalfSharp.chroma) // nil ``` * A `Chroma` and an octave number can be used to create a `Pitch`. ```swift let D5 = Pitch(chroma: .D, octave: 5) print(D5) // D5 ``` * A `Chroma` can be created with an index or using one of the provided constants. ```swift let C = Chroma.C print(C) // C let CSharp = Chroma.Cs print(CSharp) // C♯ let D = C + 2 print(D) // D ``` ### PitchSet * A `PitchSet` is a collection of unique `Pitch` instances ordered by frequency. ```swift var CMajor = PitchSet(pitches: Chroma.C*2, Chroma.E*2, Chroma.G*2) print(CMajor) // [C2, E2, G2] let pitches = [Chroma.Fs*2, Chroma.As*2, Chroma.Cs*3] var FSharpMajor = PitchSet(pitches) print(FSharpMajor) // [F♯2, B♭2, C♯3] ``` * `PitchSet` supports many operations. ```swift var petrushka = CMajor + FSharpMajor print(petrushka) // [C2, E2, F♯2, G2, B♭2, C♯3] print(CMajor == FSharpMajor) // false print(petrushka.gamut()) // [F♯, G, B♭, C, E, C♯] petrushka.remove(Pitch(chroma: Chroma.G, octave: 2)) print(petrushka) // [C2, E2, F♯2, B♭2, C♯3] let F = Chroma.F print(CMajor / F) // [F1, C2, E2, G2] ``` ### Harmonizer * A `Harmonizer` is a function with the signature `(Pitch -> PitchSet)`. * `Scale` and `Chord` contain common scale and chord harmonizers. * `Major`, `Minor`, and `Harmony` can be used to create functional harmony. ### Scale * `Scale` contains common scale harmonizers. ```swift let major = Scale.Major print(major(A4)) // [A4, B4, C♯5, D5, E5, F♯5, G♯5] ``` * The `Harmony` enum provides a way to create custom harmonizers from an array of semitone intervals. ```swift let equidistantPentatonic = Harmony.create([2.4, 2.4, 2.4, 2.4, 2.4]) ``` ### Chord * `Chord` contains common chord harmonizers. ```swift let minor = Chord.Minor print(minor(A4)) // [A4, C5, E5] ``` * `Chord` also provides a function to create a chord based on a `Harmonizer` (typically a scale). ```swift let chord = Chord.create(major, indices: [0, 2, 4, 6]) let ch = chord(Pitch(midi: 69)) print(ch) // [A4, C♯5, E5, G♯5] ``` * `Chord.name` can be used to derive a chord name from a pitch set ```swift let pitchSet: PitchSet = [Chroma.B*0, Chroma.Cs*2, Chroma.F*3, Chroma.G*4] print(Chord.name(pitchSet)!) // G7♭5/B let descriptor = Chord.descriptor(pitchSet) print(descriptor!) // root: G, quality: dominant seventh flat five, bass: B ``` ### Functional harmony * `Major` and `Minor` contain harmonizers for creating diatonic functional harmony. ```swift let neapolitan = Major.bII print(neapolitan(Chroma.C*5)) // [C♯5, E♯5, G♯5] let G4 = Chroma.G*4 let plagalCadence = [Major.IV, Major.I] * G4 print(plagalCadence) // [[C5, E5, G5], [G4, B4, D5]] ``` * `Harmony` provides a way to create custom functional harmonizers. ```swift let V7ofV = HarmonicFunction.create(Scale.Major, degree: 5, chord: Major.V7) print(V7ofV(C5)) // [D6, F♯6, A6, C7] ```