-- | Basic harmony. module Music.Pitch.Common.Harmony ( isDissonance, isConsonance, isPerfectConsonance, isImperfectConsonance, isMelodicDissonance, isMelodicConsonance, ) where import Music.Pitch.Common.Interval import Music.Pitch.Common.Number import Music.Pitch.Common.Quality import Music.Pitch.Literal import Data.Semigroup import Data.Set (Set) import qualified Data.Set as Set {- TODO Generalize simple like this: > (number (asInterval (m9))-(fromIntegral $ signum (m9))) `mod` 7 -} -- | Whether the given interval is a (harmonic) dissonance. isDissonance :: Interval -> Bool isDissonance x = case number (simple x) of 2 -> True 7 -> True _ -> False -- | Whether the given interval is a (harmonic) consonance. isConsonance :: Interval -> Bool isConsonance x = isPerfectConsonance x || isImperfectConsonance x -- | Whether the given interval is a perfect (harmonic) consonance. isPerfectConsonance :: Interval -> Bool isPerfectConsonance x = case number (simple x) of 1 -> True 4 -> True 5 -> True _ -> False -- | Whether the given interval is an imperfect (harmonic) consonance. isImperfectConsonance :: Interval -> Bool isImperfectConsonance x = case number (simple x) of 3 -> True 6 -> True _ -> False -- | Whether the given interval is a melodic dissonance. isMelodicDissonance :: Interval -> Bool isMelodicDissonance x = not $ isMelodicConsonance x -- | Whether an interval is melodic consonance. isMelodicConsonance :: Interval -> Bool isMelodicConsonance x = quality x `elem` [Perfect, Major, Minor] {- type Chord = Set Interval majorTriad, minorTriad :: Chord majorTriad = Set.fromList [_P1, _M3, _P5] minorTriad = Set.fromList [_P1, m3, _P5] min7, maj7 :: Chord -> Chord min7 = (<> Set.fromList [m7]) maj7 = (<> Set.fromList [_M7]) -}