vocoder-dunai-0.1.0.0: example/ProcessingTree.hs
{-# LANGUAGE ScopedTypeVariables #-}
module ProcessingTree where
import Control.Monad.Writer
import Control.Monad.Except
import FRP.Rhine
import Vocoder
import Vocoder.Filter
type STFTMSF m = MSF m [[STFTFrame]] [STFTFrame]
data ProcessingTree m = PTSource Int
| PTNamed String
| PTBind String (ProcessingTree m)
| PTMSF (MSF m [STFTFrame] [STFTFrame]) (ProcessingTree m)
| PTFilter (Filter m) (ProcessingTree m)
| PTBinary (STFTFrame -> STFTFrame -> STFTFrame) (ProcessingTree m) (ProcessingTree m)
elaboratePT :: forall m. Monad m
=> m FreqStep
-> ProcessingTree m
-> Maybe (STFTMSF m)
elaboratePT mfs t0 = either (const Nothing) Just r where
(r, e0) = runWriter $ runExceptT $ g e0 t0
g :: [(String, STFTMSF m)]
-> ProcessingTree m
-> ExceptT () (Writer [(String, STFTMSF m)]) (STFTMSF m)
g _ (PTSource k) = return $ arr (!! k)
g e (PTNamed n) | Just v <- lookup n e = return v
| otherwise = throwError ()
g e (PTBind n t) = g e t >>= (\v -> tell [(n, v)] >> return v)
g e (PTMSF f t) = (>>> f) <$> g e t
g e (PTFilter f t) = (>>> arrM (\x -> mfs >>= forM x . f)) <$> g e t
g e (PTBinary f t1 t2) = (\m1 m2 -> zipWith f <$> m1 <*> m2) <$> g e t1 <*> g e t2
numSourcesPT :: (ProcessingTree m) -> Int
numSourcesPT (PTSource k) = k+1
numSourcesPT (PTNamed _) = 0
numSourcesPT (PTBind _ t) = numSourcesPT t
numSourcesPT (PTMSF _ t) = numSourcesPT t
numSourcesPT (PTFilter _ t) = numSourcesPT t
numSourcesPT (PTBinary _ t1 t2) = numSourcesPT t1 `max` numSourcesPT t2