module Synthesizer.Plain.Interpolation (
T, func, offset, number,
zeroPad, constantPad, cyclicPad, extrapolationPad,
single,
multiRelative,
multiRelativeZeroPad, multiRelativeConstantPad,
multiRelativeCyclicPad, multiRelativeExtrapolationPad,
multiRelativeZeroPadConstant, multiRelativeZeroPadLinear,
multiRelativeZeroPadCubic,
constant, linear, cubic,
piecewise, function,
Interpolation.Margin, Interpolation.margin,
singleRec,
) where
import qualified Synthesizer.Interpolation as Interpolation
import Synthesizer.Interpolation (T, offset, number, )
import Synthesizer.Interpolation.Module
(constant, linear, cubic, piecewise, function, )
import qualified Synthesizer.State.Signal as SigS
import qualified Synthesizer.Plain.Signal as Sig
import qualified Synthesizer.Plain.Filter.NonRecursive as FiltNR
import qualified Algebra.Module as Module
import qualified Algebra.RealField as RealField
import qualified Algebra.RealRing as RealRing
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import Algebra.Additive(zero)
import Data.Maybe (fromMaybe)
import qualified Data.List.HT as ListHT
import Control.Monad (guard, )
import NumericPrelude.Base
import NumericPrelude.Numeric
zeroPad :: (RealRing.C t) =>
(T t y -> t -> Sig.T y -> a) ->
y -> T t y -> t -> Sig.T y -> a
zeroPad interpolate z ip phase x =
let (phInt, phFrac) = splitFraction phase
in interpolate ip phFrac
(FiltNR.delayPad z (offset ip phInt) (x ++ repeat z))
constantPad :: (RealRing.C t) =>
(T t y -> t -> Sig.T y -> a) ->
T t y -> t -> Sig.T y -> a
constantPad interpolate ip phase x =
let (phInt, phFrac) = splitFraction phase
xPad =
do (xFirst,_) <- ListHT.viewL x
(xBody,xLast) <- ListHT.viewR x
return (FiltNR.delayPad xFirst (offset ip phInt) (xBody ++ repeat xLast))
in interpolate ip phFrac
(fromMaybe [] xPad)
cyclicPad :: (RealRing.C t) =>
(T t y -> t -> Sig.T y -> a) ->
T t y -> t -> Sig.T y -> a
cyclicPad interpolate ip phase x =
let (phInt, phFrac) = splitFraction phase
in interpolate ip phFrac
(drop (mod (phInt offset ip) (length x)) (cycle x))
extrapolationPad :: (RealRing.C t) =>
(T t y -> t -> Sig.T y -> a) ->
T t y -> t -> Sig.T y -> a
extrapolationPad interpolate ip phase =
interpolate ip (phase fromIntegral (offset ip))
func ::
T t y -> t -> Sig.T y -> y
func ip phase =
Interpolation.func ip phase . SigS.fromList
skip :: (RealRing.C t) =>
T t y -> (t, Sig.T y) -> (t, Sig.T y)
skip ip (phase0, x0) =
let (n, frac) = splitFraction phase0
(m, x1) = Sig.dropMarginRem (number ip) n x0
in (fromIntegral m + frac, x1)
single :: (RealRing.C t) =>
T t y -> t -> Sig.T y -> y
single ip phase0 x0 =
uncurry (func ip) $ skip ip (phase0, x0)
singleRec :: (Ord t, Ring.C t) =>
T t y -> t -> Sig.T y -> y
singleRec ip phase x =
maybe
(func ip phase x)
(singleRec ip (phase 1))
(do (_,xs) <- ListHT.viewL x
guard (phase >= 1 && Sig.lengthAtLeast (number ip) xs)
return xs)
multiRelative :: (RealRing.C t) =>
T t y -> t -> Sig.T y -> Sig.T t -> Sig.T y
multiRelative ip phase0 x0 =
map (uncurry (func ip)) .
scanl
(\(phase,x) freq -> skip ip (phase + freq, x))
(skip ip (phase0,x0))
multiRelativeZeroPad :: (RealRing.C t) =>
y -> T t y -> t -> Sig.T t -> Sig.T y -> Sig.T y
multiRelativeZeroPad z ip phase fs x =
zeroPad multiRelative z ip phase x fs
multiRelativeConstantPad :: (RealRing.C t) =>
T t y -> t -> Sig.T t -> Sig.T y -> Sig.T y
multiRelativeConstantPad ip phase fs x =
constantPad multiRelative ip phase x fs
multiRelativeCyclicPad :: (RealRing.C t) =>
T t y -> t -> Sig.T t -> Sig.T y -> Sig.T y
multiRelativeCyclicPad ip phase fs x =
cyclicPad multiRelative ip phase x fs
multiRelativeExtrapolationPad :: (RealRing.C t) =>
T t y -> t -> Sig.T t -> Sig.T y -> Sig.T y
multiRelativeExtrapolationPad ip phase fs x =
extrapolationPad multiRelative ip phase x fs
multiRelativeZeroPadConstant ::
(RealRing.C t, Additive.C y) => t -> Sig.T t -> Sig.T y -> Sig.T y
multiRelativeZeroPadConstant = multiRelativeZeroPad zero constant
multiRelativeZeroPadLinear ::
(RealRing.C t, Module.C t y) => t -> Sig.T t -> Sig.T y -> Sig.T y
multiRelativeZeroPadLinear = multiRelativeZeroPad zero linear
multiRelativeZeroPadCubic ::
(RealField.C t, Module.C t y) => t -> Sig.T t -> Sig.T y -> Sig.T y
multiRelativeZeroPadCubic = multiRelativeZeroPad zero cubic