module Synthesizer.Generic.Interpolation (
T, func, offset, number,
zeroPad, constantPad, cyclicPad, extrapolationPad,
single,
multiRelative,
multiRelativeZeroPad, multiRelativeConstantPad,
multiRelativeCyclicPad, multiRelativeExtrapolationPad,
multiRelativeZeroPadConstant, multiRelativeZeroPadLinear,
multiRelativeZeroPadCubic,
) where
import qualified Synthesizer.Interpolation as Interpolation
import Synthesizer.Interpolation (T, offset, number, )
import Synthesizer.Interpolation.Module (constant, linear, cubic, )
import qualified Synthesizer.Generic.Signal as SigG
import qualified Synthesizer.Generic.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.Additive as Additive
import Data.Maybe (fromMaybe, )
import NumericPrelude.Numeric
import NumericPrelude.Base
zeroPad :: (RealRing.C t, SigG.Write sig y) =>
(T t y -> t -> sig y -> a) ->
y -> T t y -> t -> sig y -> a
zeroPad interpolate z ip phase x =
let (phInt, phFrac) = splitFraction phase
in interpolate ip phFrac
(FiltNR.delayPad z (offset ip phInt)
(SigG.append x (SigG.repeat SigG.defaultLazySize z)))
constantPad :: (RealRing.C t, SigG.Write sig y) =>
(T t y -> t -> sig y -> a) ->
T t y -> t -> sig y -> a
constantPad interpolate ip phase x =
let (phInt, phFrac) = splitFraction phase
xPad =
do (xFirst,_) <- SigG.viewL x
return (FiltNR.delayPad xFirst
(offset ip phInt) (SigG.extendConstant SigG.defaultLazySize x))
in interpolate ip phFrac
(fromMaybe SigG.empty xPad)
cyclicPad :: (RealRing.C t, SigG.Transform sig y) =>
(T t y -> t -> sig y -> a) ->
T t y -> t -> sig y -> a
cyclicPad interpolate ip phase x =
let (phInt, phFrac) = splitFraction phase
in interpolate ip phFrac
(SigG.drop (mod (phInt offset ip) (SigG.length x)) (SigG.cycle x))
extrapolationPad :: (RealRing.C t, SigG.Transform sig y) =>
(T t y -> t -> sig y -> a) ->
T t y -> t -> sig y -> a
extrapolationPad interpolate ip phase =
interpolate ip (phase fromIntegral (offset ip))
func :: (SigG.Read sig y) =>
T t y -> t -> sig y -> y
func ip phase =
Interpolation.func ip phase . SigG.toState
skip :: (RealRing.C t, SigG.Transform sig y) =>
T t y -> (t, sig y) -> (t, sig y)
skip ip (phase0, x0) =
let (n, frac) = splitFraction phase0
(m, x1) = SigG.dropMarginRem (number ip) n x0
in (fromIntegral m + frac, x1)
single :: (RealRing.C t, SigG.Transform sig y) =>
T t y -> t -> sig y -> y
single ip phase0 x0 =
uncurry (func ip) $ skip ip (phase0, x0)
multiRelative ::
(RealRing.C t, SigG.Transform sig t, SigG.Transform sig y) =>
T t y -> t -> sig y -> sig t -> sig y
multiRelative ip phase0 x0 =
SigG.crochetL
(\freq pos ->
let (phase,x) = skip ip pos
in Just (func ip phase x, (phase+freq,x)))
(phase0,x0)
multiRelativeZeroPad ::
(RealRing.C t, SigG.Transform sig t, SigG.Transform sig y, SigG.Write sig y) =>
y -> T t y -> t -> sig t -> sig y -> sig y
multiRelativeZeroPad z ip phase fs x =
zeroPad multiRelative z ip phase x fs
multiRelativeConstantPad ::
(RealRing.C t, SigG.Transform sig t, SigG.Transform sig y, SigG.Write sig y) =>
T t y -> t -> sig t -> sig y -> sig y
multiRelativeConstantPad ip phase fs x =
constantPad multiRelative ip phase x fs
multiRelativeCyclicPad ::
(RealRing.C t, SigG.Transform sig t, SigG.Transform sig y) =>
T t y -> t -> sig t -> sig y -> sig y
multiRelativeCyclicPad ip phase fs x =
cyclicPad multiRelative ip phase x fs
multiRelativeExtrapolationPad ::
(RealRing.C t, SigG.Transform sig t, SigG.Transform sig y) =>
T t y -> t -> sig t -> sig y -> sig y
multiRelativeExtrapolationPad ip phase fs x =
extrapolationPad multiRelative ip phase x fs
multiRelativeZeroPadConstant ::
(RealRing.C t, Additive.C y, SigG.Transform sig t, SigG.Transform sig y, SigG.Write sig y) =>
t -> sig t -> sig y -> sig y
multiRelativeZeroPadConstant =
multiRelativeZeroPad zero constant
multiRelativeZeroPadLinear ::
(RealRing.C t, Module.C t y, SigG.Transform sig t, SigG.Transform sig y, SigG.Write sig y) =>
t -> sig t -> sig y -> sig y
multiRelativeZeroPadLinear =
multiRelativeZeroPad zero linear
multiRelativeZeroPadCubic ::
(RealField.C t, Module.C t y, SigG.Transform sig t, SigG.Transform sig y, SigG.Write sig y) =>
t -> sig t -> sig y -> sig y
multiRelativeZeroPadCubic =
multiRelativeZeroPad zero cubic