music-pitch-1.6.1: src/Music/Pitch/Common/Harmony.hs
module Music.Pitch.Common.Harmony (
isDissonance,
isConsonance,
isPerfectConsonance,
isImperfectConsonance,
isMelodicDissonance,
isMelodicConsonance,
) where
import Music.Pitch.Common.Interval
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])