-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
116 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
|
||
# const Chord{T <: Union{PitchClass, Pitch}} = Set{T} | ||
|
||
struct Chord{T <: Union{PitchClass, Pitch}} | ||
notes::Set{T} | ||
end | ||
|
||
Chord(notes::T...) where {T <: Union{PitchClass, Pitch}} = Chord{T}(Set(notes)) | ||
|
||
|
||
Base.length(chord::Chord) = length(chord.notes) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
|
||
module NoteNames | ||
|
||
using MusicTheory: | ||
C, D, E, F, G, A, B, | ||
C♮, D♮, E♮, F♮, G♮, A♮, B♮, | ||
C♯, D♯, E♯, F♯, G♯, A♯, B♯, | ||
C♭, D♭, E♭, F♭, G♭, A♭, B♭, | ||
C𝄫, D𝄫, E𝄫, F𝄫, G𝄫, A𝄫, B𝄫, | ||
C𝄪, D𝄪, E𝄪, F𝄪, G𝄪, A𝄪, B𝄪 | ||
|
||
export | ||
C, D, E, F, G, A, B, | ||
C♮, D♮, E♮, F♮, G♮, A♮, B♮, | ||
C♯, D♯, E♯, F♯, G♯, A♯, B♯, | ||
C♭, D♭, E♭, F♭, G♭, A♭, B♭, | ||
C𝄫, D𝄫, E𝄫, F𝄫, G𝄫, A𝄫, B𝄫, | ||
C𝄪, D𝄪, E𝄪, F𝄪, G𝄪, A𝄪, B𝄪, | ||
middle_C | ||
|
||
const middle_C = C[4] | ||
|
||
end | ||
|
||
|
||
module AllNoteNames | ||
|
||
using MusicTheory: note_names, Pitch, PitchClass, Accidental | ||
|
||
using MusicTheory.NoteNames | ||
|
||
for note in note_names, octave in 0:9 | ||
name = Symbol(note, octave) | ||
@eval $(name) = Pitch(PitchClass($(Meta.quot(note))), $(octave)) | ||
@eval export $(name) | ||
|
||
for accidental in instances(Accidental) | ||
name = Symbol(note, accidental, octave) | ||
@eval $(name) = Pitch(PitchClass($(Meta.quot(note)), $(accidental)), $(octave)) | ||
@eval export $(name) | ||
end | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
function make_triad(scale::Scale, root::Pitch) | ||
|
||
!haskey(scale.steps, PitchClass(root)) && error("$root not in scale") | ||
|
||
triad_notes = [root] | ||
|
||
current, next = iterate(scale, root) | ||
current, next = iterate(scale, next) | ||
|
||
push!(triad_notes, next) | ||
|
||
current, next = iterate(scale, next) | ||
current, next = iterate(scale, next) | ||
|
||
push!(triad_notes, next) | ||
|
||
return Chord(triad_notes...) | ||
end | ||
|
||
|
||
function find_intervals(chord) | ||
notes = sort(collect(chord.notes)) | ||
# return [interval(n1, n2) for n1 in notes for n2 in notes if n1 < n2] | ||
return [Interval(notes[1], notes[2]), Interval(notes[1], notes[3])] | ||
end | ||
|
||
|
||
function is_triad(chord::Chord{PitchClass}) | ||
length(chord) != 3 && return false | ||
|
||
# put them in the same octave: | ||
pitches = [Pitch(n, 4) for n in chord.notes] | ||
|
||
intervals = find_intervals(Chord(pitches...)) |> collect | ||
numbers = (intervals[1].number, intervals[2].number) | ||
|
||
return numbers ∈ ( (3, 5), (3, 6), (4, 6) ) | ||
end | ||
|
||
is_triad(chord::Chord{Pitch}) = is_triad(Chord(PitchClass.(chord.notes)...)) | ||
|
||
is_triad(notes...) = is_triad(Chord(notes...)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ using Test | |
include("notes.jl") | ||
include("intervals.jl") | ||
include("scales.jl") | ||
include("triads.jl") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
@testset "Triads" begin | ||
@test is_triad(Chord(B, D, F)) | ||
@test is_triad(B[4], D[7], F[1]) | ||
|
||
@test !is_triad(Chord(A, B, C)) | ||
@test !is_triad(A, B, C) | ||
end | ||
|
||
@testset "Triads with names" begin | ||
using MusicTheory.AllNoteNames | ||
|
||
@test is_triad(C4, E5, A8) | ||
end |