module Music.Pitch.Equal
(
Equal,
toEqual,
fromEqual,
equalToRatio,
size,
cast,
Equal6,
Equal12,
Equal17,
Equal24,
Equal36,
N20,
N30,
N17,
N24,
N36,
)
where
import Data.Maybe
import Data.Either
import Data.Semigroup
import Data.VectorSpace
import Data.AffineSpace
import Control.Monad
import Control.Applicative
import Music.Pitch.Absolute
import TypeUnary.Nat
newtype Equal a = Equal {getEqual :: Int }
deriving instance Eq (Equal a)
deriving instance Ord (Equal a)
instance Show (Equal a) where
show (Equal a) = show a
instance IsNat a => Num (Equal a) where
Equal a + Equal b = Equal (a + b)
Equal a * Equal b = Equal (a * b)
negate (Equal a) = Equal (negate a)
abs (Equal a) = Equal (abs a)
signum (Equal a) = Equal (signum a)
fromInteger = toEqual . fromIntegral
instance IsNat a => Semigroup (Equal a) where
(<>) = (+)
instance IsNat a => Monoid (Equal a) where
mempty = 0
mappend = (+)
instance IsNat a => AdditiveGroup (Equal a) where
zeroV = 0
(^+^) = (+)
negateV = negate
instance IsNat a => VectorSpace (Equal a) where
type Scalar (Equal a) = Equal a
(*^) = (*)
getSize :: IsNat a => Equal a -> Nat a
getSize _ = nat
size :: IsNat a => Equal a -> Int
size = natToZ . getSize
toEqual :: IsNat a => Int -> Equal a
toEqual = Equal
fromEqual :: IsNat a => Equal a -> Int
fromEqual = getEqual
equalToRatio :: IsNat a => Equal a -> Double
equalToRatio x = 2**(realToFrac (fromEqual x) / realToFrac (size x))
cast :: (IsNat a, IsNat b) => Equal a -> Equal b
cast = cast' undefined
cast' :: (IsNat a, IsNat b) => Equal b -> Equal a -> Equal b
cast' bDummy aDummy@(Equal a) = Equal $ (a * size bDummy) `div` size aDummy
type Equal6 = Equal N6
type Equal12 = Equal N12
type Equal17 = Equal N17
type Equal24 = Equal N24
type Equal36 = Equal N36
type N20 = N10 :*: N2
type N30 = N10 :*: N3
type N17 = N10 :+: N7
type N24 = N20 :+: N4
type N36 = N30 :+: N6