diff --git a/src/intervals.jl b/src/intervals.jl index 1b7edf5..dbae702 100644 --- a/src/intervals.jl +++ b/src/intervals.jl @@ -112,6 +112,15 @@ function Base.:+(p::Pitch, interval::Interval) end +function Base.:+(i1::Interval, i2::Interval) + bottom = C[4] + top = bottom + i1 + i2 + + return Interval(bottom, top) +end + + + const Minor_2nd = Interval(2, Minor) const Major_2nd = Interval(2, Major) diff --git a/src/scales.jl b/src/scales.jl index 3463f5f..7e73112 100644 --- a/src/scales.jl +++ b/src/scales.jl @@ -1,10 +1,18 @@ -# Represents a musical scale -# I.e. an object that repeats each octave +""" + struct Scale{T<:Union{PitchClass, Pitch}} + +A musical scale divides up an octave. +A scale is represented as an iterator. +""" struct Scale{T<:Union{PitchClass, Pitch}} tonic::T steps::Dict{PitchClass, Interval} function Scale(tonic::T, steps::Vector{Interval}) where {T} + + # steps must add up to an octave: + @assert sum(steps) == Interval(8, Perfect) + steps_dict = Dict{PitchClass, Interval}() current = tonic diff --git a/test/intervals.jl b/test/intervals.jl index 0c8eefe..072c407 100644 --- a/test/intervals.jl +++ b/test/intervals.jl @@ -17,4 +17,17 @@ end @test C[4] + Interval(2, Major) == D[4] @test B[4] + Interval(2, Major) == C♯[5] +end + +@testset "Sum of intervals" begin + @test Interval(3, Major) + Interval(3, Minor) == Interval(5, Perfect) + @test Interval(3, Major) + Interval(3, Major) == Interval(5, Augmented) + @test Interval(3, Major) + Interval(4, Diminished) == Interval(6, Minor) + @test Interval(4, Perfect) + Interval(5, Perfect) == Interval(8, Perfect) + + major_scale = let M = Major_2nd, m = Minor_2nd + [M, M, m, M, M, M, m] + end + + @test sum(major_scale) == Interval(8, Perfect) end \ No newline at end of file