module Music.Diatonic.Interval (
Interval(
Unison,Min2nd,Maj2nd,Min3rd,Maj3rd,Perf4th,
Perf5th,Min6th,Maj6th,Min7th,Maj7th
), augment, diminish,
steps, semitones
) where
import Music.Diatonic.Quality
data Interval = Unison | Min2nd | Maj2nd | Min3rd | Maj3rd | Perf4th
| Perf5th | Min6th | Maj6th | Min7th | Maj7th
| Aug Interval | Dim Interval
deriving (Eq)
instance Show Interval where
show Unison = "P1" ; show Min2nd = "m2" ; show Maj2nd = "M2" ; show Min3rd = "m3"
show Maj3rd = "M3" ; show Perf4th = "P4" ; show Perf5th = "P5" ; show Min6th = "m6"
show Maj6th = "M6" ; show Min7th = "m7" ; show Maj7th = "M7"
show (Aug i@(Aug _)) = "A" ++ show i
show (Aug i) = "A" ++ (tail . show $ i)
show (Dim i@(Dim _)) = "d" ++ show i
show (Dim i) = "d" ++ (tail . show $ i)
instance Qual Interval where
quality i | i `elem` [Maj2nd, Maj3rd, Maj6th, Maj7th] = Major
quality i | i `elem` [Min2nd, Min3rd, Min6th, Min7th] = Minor
quality i | i `elem` [Perf4th, Perf5th] = Perfect
quality (Aug i) = Augmented
quality (Dim i) = Diminished
augment :: Interval -> Interval
augment (Dim i) = i
augment Min2nd = Maj2nd ; augment Min3rd = Maj3rd
augment Min6th = Maj6th ; augment Min7th = Maj7th
augment i = Aug i
diminish :: Interval -> Interval
diminish (Aug i) = i
diminish Maj2nd = Min2nd ; diminish Maj3rd = Min3rd
diminish Maj6th = Min6th ; diminish Maj7th = Min7th
diminish i = Dim i
steps :: Interval -> Int
steps Unison = 0 ; steps Min2nd = 1 ; steps Maj2nd = 1 ; steps Min3rd = 2
steps Maj3rd = 2 ; steps Perf4th = 3 ; steps Perf5th = 4 ; steps Min6th = 5
steps Maj6th = 5 ; steps Min7th = 6 ; steps Maj7th = 6
steps (Aug i) = steps i
steps (Dim i) = steps i
semitones :: Interval -> Int
semitones Unison = 0 ; semitones Min2nd = 1 ; semitones Maj2nd = 2 ; semitones Min3rd = 3
semitones Maj3rd = 4 ; semitones Perf4th = 5 ; semitones Perf5th = 7 ; semitones Min6th = 8
semitones Maj6th = 9 ; semitones Min7th = 10 ; semitones Maj7th = 11
semitones (Aug i) = semitones i + 1
semitones (Dim i) = semitones i 1