{-# LANGUAGE NoImplicitPrelude #-}
module Synthesizer.Plain.Cut (
takeUntilPause,
takeUntilInterval,
selectBool,
select,
arrange,
) where
import qualified Synthesizer.Plain.Signal as Sig
import qualified Data.EventList.Relative.TimeBody as EventList
import Data.Array (Array, Ix, (!))
import qualified MathObj.LaurentPolynomial as Laurent
import qualified Algebra.RealRing as RealRing
import qualified Algebra.Additive as Additive
import qualified Number.NonNegative as NonNeg
import NumericPrelude.Numeric
import NumericPrelude.Base
takeUntilPause :: (RealRing.C a) => a -> Int -> Sig.T a -> Sig.T a
takeUntilPause y =
takeUntilInterval ((<=y) . abs)
takeUntilInterval :: (a -> Bool) -> Int -> Sig.T a -> Sig.T a
takeUntilInterval p n xs =
map fst $
takeWhile ((<n) . snd) $
zip xs $
drop n $
scanl (\acc x -> if p x then succ acc else 0) 0 xs
++ repeat 0
selectBool :: (Sig.T a, Sig.T a) -> Sig.T Bool -> Sig.T a
selectBool =
uncurry (zipWith3 (\xf xt c -> if c then xt else xf))
select :: Ix i => Array i (Sig.T a) -> Sig.T i -> Sig.T a
select arr =
zipWith (!)
(map (fmap head) $ iterate (fmap tail) arr)
arrange :: (Additive.C v) =>
EventList.T NonNeg.Int (Sig.T v)
-> Sig.T v
arrange evs =
let xs = EventList.getBodies evs
in case map NonNeg.toNumber (EventList.getTimes evs) of
t:ts -> replicate t zero ++ Laurent.addShiftedMany ts xs
[] -> []