module Synthesizer.Plain.Filter.Recursive.MovingAverage
(sumsStaticInt,
modulatedFrac,
) where
import qualified Synthesizer.Plain.Signal as Sig
import qualified Synthesizer.Plain.Filter.Recursive.Integration as Integration
import Synthesizer.Plain.Filter.NonRecursive (delay, )
import qualified Algebra.Module as Module
import qualified Algebra.RealField as RealField
import qualified Algebra.Additive as Additive
import Control.Monad.Fix (fix)
import Data.List (tails)
import PreludeBase
import NumericPrelude
sumsStaticInt :: (Additive.C v) => Int -> Sig.T v -> Sig.T v
sumsStaticInt n xs =
fix (\ys -> let (xs0,xs1) = splitAt n xs
in (xs0 ++ (xs1xs)) + (zero:ys))
sumFromTo :: (Additive.C v) => Int -> Int -> Sig.T v -> v
sumFromTo from to =
if from <= to
then sum . take (tofrom) . drop from
else negate . sum . take (fromto) . drop to
sumFromToFrac :: (RealField.C a, Module.C a v) => a -> a -> Sig.T v -> v
sumFromToFrac from to xs =
let (fromInt, fromFrac) = splitFraction from
(toInt, toFrac) = splitFraction to
in case compare fromInt toInt of
EQ -> (tofrom) *> (xs !! fromInt)
LT ->
sum $
zipWith id
(((1fromFrac) *>) :
replicate (toIntfromInt1) id ++
(toFrac *>) :
[]) $
drop fromInt xs
GT ->
negate $ sum $
zipWith id
(((1toFrac) *>) :
replicate (fromInttoInt1) id ++
(fromFrac *>) :
[]) $
drop toInt xs
sumDiffsModulated :: (RealField.C a, Module.C a v) =>
a -> Sig.T a -> Sig.T v -> Sig.T v
sumDiffsModulated d ds =
zipWith3 sumFromToFrac ((d+1) : ds) (map (1+) ds) .
init . init . tails . (zero:)
sumsModulated :: (RealField.C a, Module.C a v) =>
Int -> Sig.T a -> Sig.T v -> Sig.T v
sumsModulated maxDInt ds xs =
let maxD = fromIntegral maxDInt
posXs = sumDiffsModulated 0 ds xs
negXs = sumDiffsModulated maxD (map (maxD) ds) (delay maxDInt xs)
in Integration.run (posXs negXs)
sumsModulatedHalf :: (RealField.C a, Module.C a v) =>
Int -> Sig.T a -> Sig.T v -> Sig.T v
sumsModulatedHalf maxDInt ds xs =
let maxD = fromIntegral maxDInt
d0 = maxD+0.5
delXs = delay maxDInt xs
posXs = sumDiffsModulated d0 (map (d0+) ds) delXs
negXs = sumDiffsModulated d0 (map (d0) ds) delXs
in Integration.run (posXs negXs)
modulatedFrac :: (RealField.C a, Module.C a v) =>
Int -> Sig.T a -> Sig.T v -> Sig.T v
modulatedFrac maxDInt ds xs =
zipWith (\d y -> recip (2*d) *> y) ds $
sumsModulatedHalf maxDInt ds xs