module Csound.SigSpace(
SigSpace(..), BindSig(..), mul, mul', on, uon, At(..), MixAt(..), bat, bmixAt,
cfd, cfd4, cfds, cfdSpec, cfdSpec4, cfdsSpec,
wsum
) where
import Control.Monad
import Control.Applicative
import Csound.Typed
import Csound.Types
import Csound.Typed.Opcode(pvscross, pvscale, pvsmix, balance)
class SigSpace a where
mapSig :: (Sig -> Sig) -> a -> a
class SigSpace a => BindSig a where
bindSig :: (Sig -> SE Sig) -> a -> SE a
mul :: SigSpace a => Sig -> a -> a
mul k = mapSig (k * )
mul' :: BindSig a => SE Sig -> a -> SE a
mul' k = bindSig (\x -> fmap (* x) k)
on :: SigSpace a => Sig -> Sig -> a -> a
on a b x = uon a b $ mapSig unipolar x
where unipolar a = 0.5 + 0.5 * a
uon :: SigSpace a => Sig -> Sig -> a -> a
uon a b = mapSig (\x -> a + (b a) * x)
cfd :: (Num a, SigSpace a) => Sig -> a -> a -> a
cfd coeff a b = (1 coeff) `mul` a + coeff `mul` b
genCfds :: a -> (Sig -> a -> a -> a) -> [Sig] -> [a] -> a
genCfds zero mixFun cs xs = case xs of
[] -> zero
a:as -> foldl (\x f -> f x) a $ zipWith mix' cs as
where mix' c a b = mixFun c b a
cfd4 :: (Num a, SigSpace a) => Sig -> Sig -> a -> a -> a -> a -> a
cfd4 x y a b c d = sum $ zipWith mul [(1 x) * (1 y), x * (1 y) , x * y, (1 x) * y] [a, b, c, d]
cfds :: (Num a, SigSpace a) => [Sig] -> [a] -> a
cfds = genCfds 0 cfd
cfdSpec :: Sig -> Spec -> Spec -> Spec
cfdSpec coeff a b = pvscross a b (1 coeff) coeff
cfdSpec4 :: Sig -> Sig -> Spec -> Spec -> Spec -> Spec -> Spec
cfdSpec4 x y a b c d = foldl1 pvsmix
[ pvscale a ((1 x) * (1 y))
, pvscale b (x * (1 y))
, pvscale c (x * y)
, pvscale d ((1 x) * y)
]
cfdsSpec :: [Sig] -> [Spec] -> Spec
cfdsSpec = genCfds undefined cfdSpec
wsum :: (Num a, SigSpace a) => [(Sig, a)] -> a
wsum = sum . fmap (uncurry mul)
instance SigSpace Sig where mapSig = id
instance BindSig Sig where bindSig = id
instance SigSpace (Sig, Sig) where mapSig f (a1, a2) = (f a1, f a2)
instance BindSig (Sig, Sig) where bindSig f (a1, a2) = (,) <$> f a1 <*> f a2
instance SigSpace (Sig, Sig, Sig) where mapSig f (a1, a2, a3) = (f a1, f a2, f a3)
instance BindSig (Sig, Sig, Sig) where bindSig f (a1, a2, a3) = (,,) <$> f a1 <*> f a2 <*> f a3
instance SigSpace (Sig, Sig, Sig, Sig) where mapSig f (a1, a2, a3, a4) = (f a1, f a2, f a3, f a4)
instance BindSig (Sig, Sig, Sig, Sig) where bindSig f (a1, a2, a3, a4) = (,,,) <$> f a1 <*> f a2 <*> f a3 <*> f a4
instance SigSpace (SE Sig) where mapSig f = fmap (mapSig f)
instance BindSig (SE Sig) where bindSig f = fmap (bindSig f)
instance SigSpace (SE (Sig, Sig)) where mapSig f = fmap (mapSig f)
instance BindSig (SE (Sig, Sig)) where bindSig f = fmap (bindSig f)
instance SigSpace (SE (Sig, Sig, Sig)) where mapSig f = fmap (mapSig f)
instance BindSig (SE (Sig, Sig, Sig)) where bindSig f = fmap (bindSig f)
instance SigSpace (SE (Sig, Sig, Sig, Sig)) where mapSig f = fmap (mapSig f)
instance BindSig (SE (Sig, Sig, Sig, Sig)) where bindSig f = fmap (bindSig f)
instance Num (SE Sig) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (SE (Sig, Sig)) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (SE (Sig, Sig, Sig)) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (SE (Sig, Sig, Sig, Sig)) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (a -> Sig) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (a -> (Sig, Sig)) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (a -> (Sig, Sig, Sig)) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (a -> (Sig, Sig, Sig, Sig)) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (a -> SE Sig) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (a -> SE (Sig, Sig)) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (a -> SE (Sig, Sig, Sig)) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Num (a -> SE (Sig, Sig, Sig, Sig)) where
(+) = liftA2 (+)
(*) = liftA2 (*)
negate = fmap negate
fromInteger = return . fromInteger
signum = fmap signum
abs = fmap abs
instance Fractional (Sig, Sig) where
(a1, a2) / (b1, b2) = (a1 / b1, a2 / b2)
fromRational a = (fromRational a, fromRational a)
instance Fractional (Sig, Sig, Sig) where
(a1, a2, a3) / (b1, b2, b3) = (a1 / b1, a2 / b2, a3 / b3)
fromRational a = (fromRational a, fromRational a, fromRational a)
instance Fractional (Sig, Sig, Sig, Sig) where
(a1, a2, a3, a4) / (b1, b2, b3, b4) = (a1 / b1, a2 / b2, a3 / b3, a4 / b4)
fromRational a = (fromRational a, fromRational a, fromRational a, fromRational a)
instance Fractional (SE Sig) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (SE (Sig, Sig)) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (SE (Sig, Sig, Sig)) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (SE (Sig, Sig, Sig, Sig)) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (a -> SE Sig) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (a -> SE (Sig, Sig)) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (a -> SE (Sig, Sig, Sig)) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (a -> SE (Sig, Sig, Sig, Sig)) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (a -> Sig) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (a -> (Sig, Sig)) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (a -> (Sig, Sig, Sig)) where
(/) = liftA2 (/)
fromRational = return . fromRational
instance Fractional (a -> (Sig, Sig, Sig, Sig)) where
(/) = liftA2 (/)
fromRational = return . fromRational
class SigSpace b => At a b c where
type AtOut a b c :: *
at :: (a -> b) -> c -> AtOut a b c
bat :: At Sig a b => (Sig -> a) -> b -> AtOut Sig a b
bat f = at (\x -> mapSig ( `balance` x) $ f x)
instance SigSpace a => At Sig Sig a where
type AtOut Sig Sig a = a
at f a = mapSig f a
instance At Sig (SE Sig) Sig where
type AtOut Sig (SE Sig) Sig = SE Sig
at f a = f a
instance At Sig (SE Sig) Sig2 where
type AtOut Sig (SE Sig) Sig2 = SE Sig2
at f a = bindSig f a
instance At Sig (SE Sig) Sig3 where
type AtOut Sig (SE Sig) Sig3 = SE Sig3
at f a = bindSig f a
instance At Sig (SE Sig) Sig4 where
type AtOut Sig (SE Sig) Sig4 = SE Sig4
at f a = bindSig f a
instance At Sig (SE Sig) (SE Sig) where
type AtOut Sig (SE Sig) (SE Sig) = SE Sig
at f a = join $ bindSig f a
instance At Sig (SE Sig) (SE Sig2) where
type AtOut Sig (SE Sig) (SE Sig2) = SE Sig2
at f a = join $ bindSig f a
instance At Sig (SE Sig) (SE Sig3) where
type AtOut Sig (SE Sig) (SE Sig3) = SE Sig3
at f a = join $ bindSig f a
instance At Sig (SE Sig) (SE Sig4) where
type AtOut Sig (SE Sig) (SE Sig4) = SE Sig4
at f a = join $ bindSig f a
instance At Sig Sig2 Sig where
type AtOut Sig Sig2 Sig = Sig2
at f a = f a
instance At Sig Sig2 (SE Sig) where
type AtOut Sig Sig2 (SE Sig) = SE Sig2
at f a = fmap f a
instance At Sig Sig2 Sig2 where
type AtOut Sig Sig2 Sig2 = Sig2
at f a = 0.5 * (f (fst a) + f (snd a))
instance At Sig Sig2 (SE Sig2) where
type AtOut Sig Sig2 (SE Sig2) = SE Sig2
at f a = fmap (at f) a
fromMono a = (a, a)
instance At Sig2 Sig2 Sig where
type AtOut Sig2 Sig2 Sig = Sig2
at f a = f $ fromMono a
instance At Sig2 Sig2 Sig2 where
type AtOut Sig2 Sig2 Sig2 = Sig2
at f a = f a
instance At Sig2 Sig2 (SE Sig) where
type AtOut Sig2 Sig2 (SE Sig) = SE Sig2
at f a = fmap (f . fromMono) a
instance At Sig2 Sig2 (SE Sig2) where
type AtOut Sig2 Sig2 (SE Sig2) = SE Sig2
at f a = fmap f a
instance At Sig2 (SE Sig2) Sig where
type AtOut Sig2 (SE Sig2) Sig = SE Sig2
at f a = f $ fromMono a
instance At Sig2 (SE Sig2) Sig2 where
type AtOut Sig2 (SE Sig2) Sig2 = SE Sig2
at f a = f a
instance At Sig2 (SE Sig2) (SE Sig) where
type AtOut Sig2 (SE Sig2) (SE Sig) = SE Sig2
at f a = (f . fromMono) =<< a
instance At Sig2 (SE Sig2) (SE Sig2) where
type AtOut Sig2 (SE Sig2) (SE Sig2) = SE Sig2
at f a = f =<< a
class (SigSpace b, At a b c) => MixAt a b c where
mixAt :: Sig -> (a -> b) -> c -> AtOut a b c
bmixAt :: MixAt Sig a b => Sig -> (Sig -> a) -> b -> AtOut Sig a b
bmixAt k f = mixAt k (\x -> mapSig ( `balance` x) $ f x)
instance SigSpace a => MixAt Sig Sig a where
mixAt k f a = mapSig (\x -> cfd k x (f x)) a
instance MixAt Sig (SE Sig) Sig where
mixAt k f dry = do
wet <- f dry
return $ cfd k dry wet
instance MixAt Sig (SE Sig) Sig2 where
mixAt k f (dry1, dry2) = do
wet1 <- f dry1
wet2 <- f dry2
return $ cfd k (dry1, dry2) (wet1, wet2)
instance MixAt Sig (SE Sig) Sig3 where
mixAt k f (dry1, dry2, dry3) = do
wet1 <- f dry1
wet2 <- f dry2
wet3 <- f dry3
return $ cfd k (dry1, dry2, dry3) (wet1, wet2, wet3)
instance MixAt Sig (SE Sig) Sig4 where
mixAt k f (dry1, dry2, dry3, dry4) = do
wet1 <- f dry1
wet2 <- f dry2
wet3 <- f dry3
wet4 <- f dry4
return $ cfd k (dry1, dry2, dry3, dry4) (wet1, wet2, wet3, wet4)
instance MixAt Sig (SE Sig) (SE Sig) where
mixAt k f dry = do
dry1 <- dry
wet1 <- f dry1
return $ cfd k dry1 wet1
instance MixAt Sig (SE Sig) (SE Sig2) where
mixAt k f dry = do
(dry1, dry2) <- dry
wet1 <- f dry1
wet2 <- f dry2
return $ cfd k (dry1, dry2) (wet1, wet2)
instance MixAt Sig (SE Sig) (SE Sig3) where
mixAt k f dry = do
(dry1, dry2, dry3) <- dry
wet1 <- f dry1
wet2 <- f dry2
wet3 <- f dry3
return $ cfd k (dry1, dry2, dry3) (wet1, wet2, wet3)
instance MixAt Sig (SE Sig) (SE Sig4) where
mixAt k f dry = do
(dry1, dry2, dry3, dry4) <- dry
wet1 <- f dry1
wet2 <- f dry2
wet3 <- f dry3
wet4 <- f dry4
return $ cfd k (dry1, dry2, dry3, dry4) (wet1, wet2, wet3, wet4)
instance MixAt Sig Sig2 Sig where
mixAt k f dry = cfd k (dry, dry) wet
where wet = f dry
instance MixAt Sig Sig2 (SE Sig) where
mixAt k f dry = fmap (\x -> cfd k (x, x) (f x)) dry
instance MixAt Sig Sig2 Sig2 where
mixAt k f dry = cfd k dry wet
where wet = 0.5 * (f (fst dry) + f (snd dry))
instance MixAt Sig Sig2 (SE Sig2) where
mixAt k f dry = do
(dry1, dry2) <- dry
let wet = 0.5 * (f dry1 + f dry2)
return $ cfd k (dry1, dry2) wet
instance MixAt Sig2 Sig2 Sig where
mixAt k f dry1 = cfd k dry wet
where
dry = fromMono dry1
wet = f dry
instance MixAt Sig2 Sig2 Sig2 where
mixAt k f dry = cfd k dry wet
where
wet = f dry
instance MixAt Sig2 Sig2 (SE Sig) where
mixAt k f dry1 = do
dry <- fmap fromMono dry1
let wet = f dry
return $ cfd k dry wet
instance MixAt Sig2 Sig2 (SE Sig2) where
mixAt k f drySe = do
dry <- drySe
let wet = f dry
return $ cfd k dry wet
instance MixAt Sig2 (SE Sig2) Sig where
mixAt k f dry1 = do
wet <- f dry
return $ cfd k dry wet
where
dry = fromMono dry1
instance MixAt Sig2 (SE Sig2) Sig2 where
mixAt k f dry = do
wet <- f dry
return $ cfd k dry wet
instance MixAt Sig2 (SE Sig2) (SE Sig) where
mixAt k f dry1 = do
dry <- fmap fromMono dry1
wet <- f dry
return $ cfd k dry wet
instance MixAt Sig2 (SE Sig2) (SE Sig2) where
mixAt k f drySe = do
dry <- drySe
wet <- f dry
return $ cfd k dry wet