synthesizer-0.0.3: src/Synthesizer/Storable/Cut.hs
module Synthesizer.Storable.Cut where
import qualified Synthesizer.Storable.Signal as Sig
import qualified Data.EventList.Relative.TimeBody as EventList
import Control.Monad.State (runState, modify, gets, put, )
import Synthesizer.Utility (mapSnd, )
-- import qualified Algebra.Real as Real
import qualified Algebra.Additive as Additive
import qualified Number.NonNegative as NonNeg
import Foreign.Storable (Storable)
import PreludeBase
import NumericPrelude
{-# INLINE arrange #-}
arrange :: (Storable v, Additive.C v) =>
Sig.ChunkSize
-> EventList.T NonNeg.Int (Sig.T v)
{-^ A list of pairs: (relative start time, signal part),
The start time is relative to the start time
of the previous event. -}
-> Sig.T v
{-^ The mixed signal. -}
arrange size =
uncurry Sig.append .
flip runState Sig.empty .
fmap (Sig.concat . EventList.getTimes) .
EventList.mapM
(\timeNN ->
let time = NonNeg.toNumber timeNN
in do (prefix,suffix) <- gets (Sig.splitAtPad size time)
put suffix
return prefix)
(\body ->
modify (Sig.mix body))
arrangeList :: (Storable v, Additive.C v) =>
Sig.ChunkSize
-> EventList.T NonNeg.Int (Sig.T v)
{-^ A list of pairs: (relative start time, signal part),
The start time is relative to the start time
of the previous event. -}
-> Sig.T v
{-^ The mixed signal. -}
arrangeList size evs =
let xs = EventList.getBodies evs
in case EventList.getTimes evs of
t:ts -> Sig.replicate size (NonNeg.toNumber t) zero `Sig.append`
addShiftedMany size ts xs
[] -> Sig.empty
addShiftedMany :: (Storable a, Additive.C a) =>
Sig.ChunkSize -> [NonNeg.Int] -> [Sig.T a] -> Sig.T a
addShiftedMany size ds xss =
foldr (uncurry (addShifted size)) Sig.empty (zip (ds++[0]) xss)
{-
It is crucial that 'mix' uses the chunk size structure of the second operand.
This way we avoid unnecessary and even infinite look-ahead.
-}
addShifted :: (Storable a, Additive.C a) =>
Sig.ChunkSize -> NonNeg.Int -> Sig.T a -> Sig.T a -> Sig.T a
addShifted size delNN px py =
let del = NonNeg.toNumber delNN
in uncurry Sig.append $
mapSnd (flip Sig.mix py) $
Sig.splitAtPad size del px