module Music.Theory.Prime ( cmp_prime
, forte_prime
, rahn_prime
, encode_prime ) where
import Data.Bits
import Data.List
import Music.Theory.Pitch
cmp_prime :: (Integral a) => ([a] -> [a] -> Ordering) -> [a] -> [a]
cmp_prime _ [] = []
cmp_prime f p =
let q = invert 0 p
r = rotations (pcset p) ++ rotations (pcset q)
in minimumBy f (map (transposeTo 0) r)
forte_cmp :: (Ord t) => [t] -> [t] -> Ordering
forte_cmp [] [] = EQ
forte_cmp p q =
let r = compare (last p) (last q)
in if r == EQ then compare p q else r
forte_prime :: (Integral a) => [a] -> [a]
forte_prime = cmp_prime forte_cmp
rahn_prime :: (Integral a) => [a] -> [a]
rahn_prime = cmp_prime (\p q -> compare (reverse p) (reverse q))
encode_prime :: (Integral a, Bits a) => [a] -> [a]
encode_prime s =
let t = map (`tn` s) [0..11]
c = t ++ map (invert 0) t
in decode (minimum (map encode c))
encode :: (Integral a) => [a] -> a
encode = sum . map (2 ^)
decode :: (Bits a, Integral a) => a -> [a]
decode n =
let f i = (i, testBit n i)
in map (fromIntegral . fst) (filter snd (map f [0..11]))