{-# LANGUAGE NoImplicitPrelude #-}
{- |
Copyright   :  (c) Henning Thielemann 2008
License     :  GPL

Maintainer  :  synthesizer@henning-thielemann.de
Stability   :  provisional
Portability :  requires multi-parameter type classes
-}
module Synthesizer.Dimensional.Rate.Filter (
   {- * Non-recursive -}

   {- ** Amplification -}
   negate,
   envelope,
   envelopeVector,
   convolveVector,

   {- ** Smooth -}
   mean,
   meanStatic,

   {- ** Delay -}
   delay,
   phaseModulation,
   phaser,
   phaserStereo,
   frequencyModulation,
   frequencyModulationDecoupled,


   {- * Recursive -}

   {- ** Without resonance -}
   firstOrderLowpass,
   firstOrderHighpass,
   butterworthLowpass,
   butterworthHighpass,
   chebyshevALowpass,
   chebyshevAHighpass,
   chebyshevBLowpass,
   chebyshevBHighpass,
   {- ** With resonance -}
   universal,
   highpassFromUniversal,
   bandpassFromUniversal,
   lowpassFromUniversal,
   bandlimitFromUniversal,
   moogLowpass,

   {- ** Allpass -}
   allpassCascade,
   allpassFlangerPhase,

   {- ** Reverb -}
   comb,

   {- * Helper functions -}
   interpolateMultiRelativeZeroPad,
) where

import qualified Synthesizer.Dimensional.Amplitude.Flat as Flat

import qualified Synthesizer.Dimensional.Amplitude.Filter       as FiltV
import qualified Synthesizer.Dimensional.Process as Proc
import qualified Synthesizer.Dimensional.Amplitude as Amp
import qualified Synthesizer.Dimensional.Rate as Rate

import Synthesizer.Dimensional.Process
   (toTimeScalar, toFrequencyScalar, )

-- import Synthesizer.Dimensional.Process ((.:), (.^), )

import qualified Synthesizer.Dimensional.Signal.Private  as SigA
import qualified Synthesizer.State.Signal as Sig
import Synthesizer.Plain.Signal (Modifier, )

import qualified Synthesizer.Causal.Process       as Causal
import qualified Synthesizer.Causal.Interpolation as Interpolation
import qualified Synthesizer.State.Displacement as Disp
import qualified Synthesizer.State.Filter.Delay as Delay
import qualified Synthesizer.State.Filter.Recursive.MovingAverage as MA
import qualified Synthesizer.State.Filter.NonRecursive as FiltNR

import qualified Synthesizer.Plain.Filter.Recursive.FirstOrder  as Filt1
import qualified Synthesizer.Plain.Filter.Recursive.Allpass     as Allpass
import qualified Synthesizer.Plain.Filter.Recursive.Universal   as UniFilter
import qualified Synthesizer.Plain.Filter.Recursive.Moog        as Moog
import qualified Synthesizer.Plain.Filter.Recursive.Butterworth as Butter
import qualified Synthesizer.Plain.Filter.Recursive.Chebyshev   as Cheby
import qualified Synthesizer.Plain.Filter.Recursive             as FiltRec

import qualified Synthesizer.Storable.Signal as SigSt
import qualified Synthesizer.Generic.Filter.Recursive.Comb as Comb

-- import qualified Synthesizer.Generic.Interpolation as InterpolationG
import qualified Synthesizer.Generic.Filter.Recursive.MovingAverage as MAG
import qualified Synthesizer.Generic.Filter.NonRecursive as FiltG
import qualified Synthesizer.Generic.Filter.Delay as DelayG
import qualified Synthesizer.Generic.Signal  as SigG

import qualified Synthesizer.Frame.Stereo as Stereo

import qualified Number.DimensionTerm        as DN
import qualified Algebra.DimensionTerm       as Dim

import qualified Number.NonNegative     as NonNeg

import qualified Algebra.Transcendental as Trans
import qualified Algebra.RealField      as RealField
import qualified Algebra.Field          as Field
import qualified Algebra.RealRing       as RealRing
import qualified Algebra.Ring           as Ring
import qualified Algebra.Additive       as Additive
-- import qualified Algebra.VectorSpace    as VectorSpace
import qualified Algebra.Module         as Module

import Foreign.Storable (Storable, )

-- import qualified Data.List as List

-- import Control.Monad(liftM2)

import NumericPrelude.Numeric hiding (negate)
import NumericPrelude.Base as P
import Prelude ()


type Signal s amp yv =
   SigA.T (Rate.Phantom s) amp (Sig.T yv)

{-# INLINE negate #-}
negate :: (Additive.C yv, Dim.C u) =>
      Proc.T s u t (
        Signal s amp yv
     -> Signal s amp yv)
negate :: forall yv u s t amp.
(C yv, C u) =>
T s u t (Signal s amp yv -> Signal s amp yv)
negate = forall a s u t. a -> T s u t a
Proc.pure forall (sig :: * -> *) yv rate amp.
(Transform sig yv, C yv) =>
T rate amp (sig yv) -> T rate amp (sig yv)
FiltV.negate


{-# INLINE envelope #-}
envelope :: (Flat.C y0 flat, Ring.C y0, Dim.C u) =>
      Proc.T s u t (
        Signal s flat y0        {- v the envelope -}
     -> Signal s amp y0         {- v the signal to be enveloped -}
     -> Signal s amp y0)
envelope :: forall y0 flat u s t amp.
(C y0 flat, C y0, C u) =>
T s u t (Signal s flat y0 -> Signal s amp y0 -> Signal s amp y0)
envelope = forall a s u t. a -> T s u t a
Proc.pure forall y flat s amp.
(C y flat, C y) =>
T (Phantom s) flat (T y)
-> T (Phantom s) amp (T y) -> T (Phantom s) amp (T y)
FiltV.envelope

{-# INLINE envelopeVector #-}
envelopeVector ::
   (Flat.C y0 flat, Module.C y0 yv, Dim.C u) =>
      Proc.T s u t (
        Signal s flat y0        {- v the envelope -}
     -> Signal s amp yv         {- v the signal to be enveloped -}
     -> Signal s amp yv)
envelopeVector :: forall y0 flat yv u s t amp.
(C y0 flat, C y0 yv, C u) =>
T s u t (Signal s flat y0 -> Signal s amp yv -> Signal s amp yv)
envelopeVector = forall a s u t. a -> T s u t a
Proc.pure forall y0 flat yv s amp.
(C y0 flat, C y0 yv) =>
T (Phantom s) flat (T y0)
-> T (Phantom s) amp (T yv) -> T (Phantom s) amp (T yv)
FiltV.envelopeVector

{-# INLINE convolveVector #-}
convolveVector ::
   (Module.C q yv, Field.C q, Dim.C u) =>
      Proc.T s u q (
        SigA.R s (Dim.Recip u) q q
                              {- v the filter window -}
     -> Signal s amp yv         {- v the signal to be enveloped -}
     -> Signal s amp yv)
convolveVector :: forall q yv u s amp.
(C q yv, C q, C u) =>
T s u q (R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
convolveVector =
   do T (Recip u) q -> q
toFreq <- forall a s u t b. (a -> T s u t b) -> T s u t (a -> b)
Proc.withParam forall t u s. (C t, C u) => T (Recip u) t -> T s u t t
toFrequencyScalar
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \ R s (Recip u) q q
window ->
         forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody
            (forall a v. C a v => T a -> T v -> T v
FiltNR.generic (forall y (sig :: * -> *) amp rate.
(C y, Transform sig y) =>
(amp -> y) -> T rate (Numeric amp) (sig y) -> sig y
SigA.scalarSamples T (Recip u) q -> q
toFreq R s (Recip u) q q
window))


{- | needs a better handling of boundaries, yet -}
{-# INLINE meanStatic #-}
meanStatic :: (Additive.C yv, RealField.C q,
         Module.C q yv, Dim.C u) =>
      DN.T (Dim.Recip u) q    {- ^ cut-off frequency -}
   -> Proc.T s u q (
        Signal s amp yv
     -> Signal s amp yv)
meanStatic :: forall yv q u s amp.
(C yv, C q, C q yv, C u) =>
T (Recip u) q -> T s u q (Signal s amp yv -> Signal s amp yv)
meanStatic T (Recip u) q
freq =
   do q
f <- forall t u s. (C t, C u) => T (Recip u) t -> T s u t t
toFrequencyScalar T (Recip u) q
freq
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
         let tInt :: Int
tInt  = forall a b. (C a, C b) => a -> b
round ((forall a. C a => a -> a
recip q
f forall a. C a => a -> a -> a
- q
1)forall a. C a => a -> a -> a
/q
2)
             width :: Int
width = Int
tIntforall a. C a => a -> a -> a
*Int
2forall a. C a => a -> a -> a
+Int
1
         in  forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody
                ((forall a. a -> a -> a
asTypeOf (forall a. C a => a -> a
recip (forall a b. (C a, C b) => a -> b
fromIntegral Int
width)) q
f forall a v. C a v => a -> v -> v
*> ) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                 forall y. Int -> T y -> T y
Delay.staticNeg Int
tInt forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                 forall v. C v => Int -> T v -> T v
MA.sumsStaticInt Int
width)

{- | needs a better handling of boundaries, yet -}
{-# INLINE mean #-}
mean :: (Additive.C yv, RealField.C q,
         Module.C q yv, Dim.C u, Storable q, Storable yv) =>
      DN.T (Dim.Recip u) q    {- ^ minimum cut-off frequency -}
   -> Proc.T s u q (
        SigA.R s (Dim.Recip u) q q
                              {- v cut-off frequencies -}
     -> Signal s amp yv
     -> Signal s amp yv)
mean :: forall yv q u s amp.
(C yv, C q, C q yv, C u, Storable q, Storable yv) =>
T (Recip u) q
-> T s
     u
     q
     (R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
mean T (Recip u) q
minFreq =
   do q
mf <- forall t u s. (C t, C u) => T (Recip u) t -> T s u t t
toFrequencyScalar T (Recip u) q
minFreq
      forall u y t s.
(C u, C y) =>
(T y -> t) -> T s u y (R s (Recip u) y y -> t)
frequencyControl forall a b. (a -> b) -> a -> b
$ \ T q
freqs ->
         let tMax :: Int
tMax   = forall a b. (C a, C b) => a -> b
ceiling (forall a. C a => a -> a
recip (q
2forall a. C a => a -> a -> a
*q
mf))
             err :: a
err    = forall a. HasCallStack => [Char] -> a
error [Char]
"Filter.mean: frequencies must be positive"
             widths :: T q
widths = forall a b. (a -> b) -> T a -> T b
Sig.map (\q
f -> if q
fforall a. Ord a => a -> a -> Bool
>q
0 then forall a. C a => a -> a
recip (q
2forall a. C a => a -> a -> a
*q
f) else forall {a}. a
err) T q
freqs
         in  forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody
                (forall a. Storable a => T a -> T a
fromStorable forall b c a. (b -> c) -> (a -> b) -> a -> c
.
--                 MAG.sumsStaticInt tMax .
                 forall a v (sig :: * -> *).
(C a, C a v, Transform sig a, Write sig v) =>
Int -> sig a -> sig v -> sig v
MAG.modulatedFrac Int
tMax (forall a. Storable a => T a -> T a
toStorable T q
widths) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                 forall a. Storable a => T a -> T a
toStorable)

{-# INLINE delay #-}
delay :: (Additive.C yv, RealRing.C t, Dim.C u, SigG.Write sig yv) =>
      DN.T u t
   -> Proc.T s u t (
        SigA.T (Rate.Phantom s) amp (sig yv)
     -> SigA.T (Rate.Phantom s) amp (sig yv))
delay :: forall yv t u (sig :: * -> *) s amp.
(C yv, C t, C u, Write sig yv) =>
T u t
-> T s
     u
     t
     (T (Phantom s) amp (sig yv) -> T (Phantom s) amp (sig yv))
delay T u t
time =
   forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall t u s. (C t, C u) => T u t -> T s u t t
toTimeScalar T u t
time) forall a b. (a -> b) -> a -> b
$
   \t
t -> forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody (forall y (sig :: * -> *).
(C y, Write sig y) =>
Int -> sig y -> sig y
DelayG.static (forall a b. (C a, C b) => a -> b
round t
t))


{-# INLINE toStorable #-}
toStorable :: (Storable a) => Sig.T a -> SigSt.T a
toStorable :: forall a. Storable a => T a -> T a
toStorable = forall a. Storable a => ChunkSize -> T a -> T a
Sig.toStorableSignal ChunkSize
SigSt.defaultChunkSize

{-# INLINE fromStorable #-}
fromStorable :: (Storable a) => SigSt.T a -> Sig.T a
fromStorable :: forall a. Storable a => T a -> T a
fromStorable = forall a. Storable a => T a -> T a
Sig.fromStorableSignal

{-# INLINE phaseModulation #-}
phaseModulation ::
   (Additive.C yv, RealField.C q, Dim.C u,
    Storable q, Storable yv) =>
      Interpolation.T q yv
   -> DN.T u q
          {- ^ minimal deviation from current time, usually negative -}
   -> DN.T u q
          {- ^ maximal deviation, it must be @minDev <= maxDev@
               and the modulation must always be
               in the range [minDev,maxDev]. -}
   -> Proc.T s u q (
        SigA.R s u q q
          {- v deviation control,
               positive numbers meanStatic prefetch,
               negative numbers meanStatic delay -}
     -> Signal s amp yv
     -> Signal s amp yv)
phaseModulation :: forall yv q u s amp.
(C yv, C q, C u, Storable q, Storable yv) =>
T q yv
-> T u q
-> T u q
-> T s u q (R s u q q -> Signal s amp yv -> Signal s amp yv)
phaseModulation T q yv
ip T u q
minDev T u q
maxDev =
   forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
      (\T (Phantom s) (Dimensional u q) (T q) -> T yv -> T yv
f R s u q q
devs ->
         forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody
            (forall a. Storable a => T a -> T a
fromStorable forall b c a. (b -> c) -> (a -> b) -> a -> c
.
             T (Phantom s) (Dimensional u q) (T q) -> T yv -> T yv
f (forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody forall a. Storable a => T a -> T a
toStorable R s u q q
devs) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
             forall a. Storable a => T a -> T a
toStorable))
      (forall yv q u (sig :: * -> *) s.
(C yv, C q, C u, Transform sig q, Transform sig yv,
 Write sig yv) =>
T q yv
-> T u q
-> T u q
-> T s
     u
     q
     (T (Phantom s) (Dimensional u q) (sig q) -> sig yv -> sig yv)
phaseModulationGeneric T q yv
ip T u q
minDev T u q
maxDev)

{-# INLINE phaseModulationGeneric #-}
phaseModulationGeneric ::
   (Additive.C yv, RealField.C q, Dim.C u,
    SigG.Transform sig q, SigG.Transform sig yv, SigG.Write sig yv) =>
      Interpolation.T q yv
   -> DN.T u q
          {- ^ minimal deviation from current time, usually negative -}
   -> DN.T u q
          {- ^ maximal deviation, it must be @minDev <= maxDev@
               and the modulation must always be
               in the range [minDev,maxDev]. -}
   -> Proc.T s u q (
        SigA.T (Rate.Phantom s) (Amp.Dimensional u q) (sig q)
          {- v deviation control,
               positive numbers meanStatic prefetch,
               negative numbers meanStatic delay -}
     -> sig yv
     -> sig yv)
phaseModulationGeneric :: forall yv q u (sig :: * -> *) s.
(C yv, C q, C u, Transform sig q, Transform sig yv,
 Write sig yv) =>
T q yv
-> T u q
-> T u q
-> T s
     u
     q
     (T (Phantom s) (Dimensional u q) (sig q) -> sig yv -> sig yv)
phaseModulationGeneric T q yv
ip T u q
minDev T u q
_maxDev =
   forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
      (\T u q -> q
toTime T (Phantom s) (Dimensional u q) (sig q)
devs ->
          let t0 :: q
t0    = T u q -> q
toTime T u q
minDev
              tInt0 :: Int
tInt0 = forall a b. (C a, C b) => a -> b
floor q
t0
          in  forall t y (sig :: * -> *).
(C t, C y, Read sig t, Transform sig t, Transform sig y,
 Write sig y) =>
T t y -> Int -> sig t -> sig y -> sig y
DelayG.modulated T q yv
ip Int
tInt0
                 (forall (sig :: * -> *) y0 y1.
(Transform0 sig, Storage (sig y0), Storage (sig y1)) =>
(y0 -> y1) -> sig y0 -> sig y1
SigG.map (forall a. Ord a => a -> a -> a
max q
t0) (forall y (sig :: * -> *) amp rate.
(C y, Transform sig y) =>
(amp -> y) -> T rate (Numeric amp) (sig y) -> sig y
SigA.scalarSamples T u q -> q
toTime T (Phantom s) (Dimensional u q) (sig q)
devs)))
      (forall a s u t b. (a -> T s u t b) -> T s u t (a -> b)
Proc.withParam forall t u s. (C t, C u) => T u t -> T s u t t
toTimeScalar)


{-
FIXME: move to Dimensional.Straight
-}
{-# INLINE frequencyModulation #-}
frequencyModulation ::
   (Flat.C t flat,
    Additive.C yv, RealRing.C t, Dim.C u) =>
      Interpolation.T t yv
   -> Proc.T s u t (
        Signal s flat t    {- v frequency factors -}
     -> Signal s amp yv
     -> Signal s amp yv)
frequencyModulation :: forall t flat yv u s amp.
(C t flat, C yv, C t, C u) =>
T t yv
-> T s u t (Signal s flat t -> Signal s amp yv -> Signal s amp yv)
frequencyModulation T t yv
ip =
   forall a s u t. a -> T s u t a
Proc.pure forall a b. (a -> b) -> a -> b
$
      \ Signal s flat t
factors ->
          forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody
             (forall q yv. (C q, C yv) => T q yv -> T q -> T yv -> T yv
interpolateMultiRelativeZeroPad T t yv
ip (forall y flat (sig :: * -> *) rate.
(C y flat, Transform sig y) =>
T rate flat (sig y) -> sig y
Flat.toSamples Signal s flat t
factors))

{- |
Frequency modulation where the input signal can have a sample rate
different from the output.
(The sample rate values can differ, the unit must be the same.
We could lift that restriction,
but then the unit handling becomes more complicated,
and I didn't have a use for it so far.)

The function can be used for resampling.
-}
{-# INLINE frequencyModulationDecoupled #-}
frequencyModulationDecoupled ::
   (Flat.C t flat,
    Additive.C yv, RealField.C t, Dim.C u) =>
      Interpolation.T t yv
   -> SigA.T (Rate.Dimensional u t) amp (Sig.T yv)
                   {- ToDo: We could also allow any signal from Generic.Read class. -}
   -> Proc.T s u t (
        Signal s flat t {- v frequency factors -}
     -> Signal s amp yv)
frequencyModulationDecoupled :: forall t flat yv u amp s.
(C t flat, C yv, C t, C u) =>
T t yv
-> T (Dimensional u t) amp (T yv)
-> T s u t (Signal s flat t -> Signal s amp yv)
frequencyModulationDecoupled T t yv
ip T (Dimensional u t) amp (T yv)
y =
   forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
      (\T (Recip u) t -> t
toFreq Signal s flat t
factors ->
         forall rate amplitude body.
rate -> amplitude -> body -> T rate amplitude body
SigA.Cons forall s. Phantom s
Rate.Phantom (forall rate amplitude body. T rate amplitude body -> amplitude
SigA.amplitude T (Dimensional u t) amp (T yv)
y) forall a b. (a -> b) -> a -> b
$
         (forall a b. (a -> b) -> a -> b
$ forall rate amplitude body. T rate amplitude body -> body
SigA.body T (Dimensional u t) amp (T yv)
y) forall a b. (a -> b) -> a -> b
$
         forall q yv. (C q, C yv) => T q yv -> T q -> T yv -> T yv
interpolateMultiRelativeZeroPad T t yv
ip forall a b. (a -> b) -> a -> b
$
         forall y (sig :: * -> *) amp rate.
(C y, Transform sig y) =>
(amp -> y) -> T rate (Numeric amp) (sig y) -> sig y
SigA.scalarSamples T (Recip u) t -> t
toFreq forall a b. (a -> b) -> a -> b
$
         forall amp sig s. amp -> sig -> T (Phantom s) (Numeric amp) sig
SigA.fromBody (forall rate amp sig. T (Actual rate) amp sig -> rate
SigA.actualSampleRate T (Dimensional u t) amp (T yv)
y) forall a b. (a -> b) -> a -> b
$
         forall y flat (sig :: * -> *) rate.
(C y flat, Transform sig y) =>
T rate flat (sig y) -> sig y
Flat.toSamples Signal s flat t
factors)
      (forall a s u t b. (a -> T s u t b) -> T s u t (a -> b)
Proc.withParam forall t u s. (C t, C u) => T (Recip u) t -> T s u t t
Proc.toFrequencyScalar)



{-# INLINE interpolateMultiRelativeZeroPad #-}
interpolateMultiRelativeZeroPad ::
    (RealRing.C q, Additive.C yv) =>
    Interpolation.T q yv
    -> Sig.T q
    -> Sig.T yv
    -> Sig.T yv
interpolateMultiRelativeZeroPad :: forall q yv. (C q, C yv) => T q yv -> T q -> T yv -> T yv
interpolateMultiRelativeZeroPad T q yv
ip T q
k T yv
x =
    forall (sig :: * -> *) a b.
(Transform sig a, Transform sig b) =>
T a b -> sig a -> sig b
Causal.apply (forall t y. C t => y -> T t y -> t -> T y -> T t y
Interpolation.relativeZeroPad forall a. C a => a
zero T q yv
ip forall a. C a => a
zero T yv
x) T q
k

{- | symmetric phaser -}
{-# INLINE phaser #-}
phaser ::
   (Additive.C yv, RealField.C q,
    Module.C q yv, Dim.C u,
    Storable q, Storable yv) =>
      Interpolation.T q yv
   -> DN.T u q  {- ^ maxDev, must be positive -}
   -> Proc.T s u q (
        SigA.R s u q q
                {- v delay control -}
     -> Signal s amp yv
     -> Signal s amp yv)
phaser :: forall yv q u s amp.
(C yv, C q, C q yv, C u, Storable q, Storable yv) =>
T q yv
-> T u q
-> T s u q (R s u q q -> Signal s amp yv -> Signal s amp yv)
phaser T q yv
ip T u q
maxDev =
   forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
      (\R s u q q -> T yv -> (T yv, T yv)
p R s u q q
devs ->
         forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody
            (forall a v. C a v => a -> T v -> T v
FiltNR.amplifyVector (forall y rate v sig. y -> T rate (Dimensional v y) sig -> y
SigA.asTypeOfAmplitude q
0.5 R s u q q
devs) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
             forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall v. C v => T v -> T v -> T v
Disp.mix forall b c a. (b -> c) -> (a -> b) -> a -> c
. R s u q q -> T yv -> (T yv, T yv)
p R s u q q
devs))
      (forall yv q u s.
(C yv, C q, C q yv, C u, Storable q, Storable yv) =>
T q yv -> T u q -> T s u q (R s u q q -> T yv -> (T yv, T yv))
phaserCore T q yv
ip T u q
maxDev)

{-# INLINE phaserStereo #-}
phaserStereo ::
   (Additive.C yv, RealField.C q,
    Module.C q yv, Dim.C u,
    Storable q, Storable yv) =>
      Interpolation.T q yv
   -> DN.T u q   {- ^ maxDev, must be positive -}
   -> Proc.T s u q (
        SigA.R s u q q
                 {- v delay control -}
     -> Signal s amp yv
     -> Signal s amp (Stereo.T yv))
phaserStereo :: forall yv q u s amp.
(C yv, C q, C q yv, C u, Storable q, Storable yv) =>
T q yv
-> T u q
-> T s u q (R s u q q -> Signal s amp yv -> Signal s amp (T yv))
phaserStereo T q yv
ip T u q
maxDev =
   forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
      (\R s u q q -> T yv -> (T yv, T yv)
p R s u q q
devs ->
            forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (forall a b c. (a -> b -> c) -> T a -> T b -> T c
Sig.zipWith forall a. a -> a -> T a
Stereo.cons) forall b c a. (b -> c) -> (a -> b) -> a -> c
. R s u q q -> T yv -> (T yv, T yv)
p R s u q q
devs))
      (forall yv q u s.
(C yv, C q, C q yv, C u, Storable q, Storable yv) =>
T q yv -> T u q -> T s u q (R s u q q -> T yv -> (T yv, T yv))
phaserCore T q yv
ip T u q
maxDev)

{-# INLINE phaserCore #-}
phaserCore ::
   (Additive.C yv, RealField.C q,
    Module.C q yv, Dim.C u,
    Storable q, Storable yv) =>
      Interpolation.T q yv
   -> DN.T u q   {- ^ maxDev, must be positive -}
   -> Proc.T s u q (
        SigA.R s u q q
                 {- v delay control -}
     -> Sig.T yv
     -> (Sig.T yv, Sig.T yv))
phaserCore :: forall yv q u s.
(C yv, C q, C q yv, C u, Storable q, Storable yv) =>
T q yv -> T u q -> T s u q (R s u q q -> T yv -> (T yv, T yv))
phaserCore T q yv
ip T u q
maxDev =
   do let minDev :: T u q
minDev  = forall a. C a => a -> a
Additive.negate T u q
maxDev
      T (Phantom s) (Dimensional u q) (Vector q)
-> Vector yv -> Vector yv
pm <- forall yv q u (sig :: * -> *) s.
(C yv, C q, C u, Transform sig q, Transform sig yv,
 Write sig yv) =>
T q yv
-> T u q
-> T u q
-> T s
     u
     q
     (T (Phantom s) (Dimensional u q) (sig q) -> sig yv -> sig yv)
phaseModulationGeneric T q yv
ip T u q
minDev T u q
maxDev
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \ R s u q q
devs T yv
x ->
         let devsPos :: T (Phantom s) (Dimensional u q) (Vector q)
devsPos = forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody forall a. Storable a => T a -> T a
toStorable R s u q q
devs
             devsNeg :: T (Phantom s) (Dimensional u q) (Vector q)
devsNeg = forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody forall a (sig :: * -> *). (C a, Transform sig a) => sig a -> sig a
FiltG.negate T (Phantom s) (Dimensional u q) (Vector q)
devsPos
             xst :: Vector yv
xst     = forall a. Storable a => T a -> T a
toStorable T yv
x
         in  (forall a. Storable a => T a -> T a
fromStorable (T (Phantom s) (Dimensional u q) (Vector q)
-> Vector yv -> Vector yv
pm T (Phantom s) (Dimensional u q) (Vector q)
devsPos Vector yv
xst),
              forall a. Storable a => T a -> T a
fromStorable (T (Phantom s) (Dimensional u q) (Vector q)
-> Vector yv -> Vector yv
pm T (Phantom s) (Dimensional u q) (Vector q)
devsNeg Vector yv
xst))


{-# INLINE firstOrderLowpass #-}
{-# INLINE firstOrderHighpass #-}
firstOrderLowpass, firstOrderHighpass ::
   (Trans.C q, Module.C q yv, Dim.C u) =>
      Proc.T s u q (
        SigA.R s (Dim.Recip u) q q
                    {- v Control signal for the cut-off frequency. -}
     -> Signal s amp yv
                    {- v Input signal -}
     -> Signal s amp yv)
firstOrderLowpass :: forall q yv u s amp.
(C q, C q yv, C u) =>
T s u q (R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
firstOrderLowpass  = forall q yv u s amp.
(C q, C q yv, C u) =>
Modifier yv (Parameter q) yv yv
-> T s
     u
     q
     (R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
firstOrderGen forall a v. (C a, C a v) => Simple v (Parameter a) v v
Filt1.lowpassModifier
firstOrderHighpass :: forall q yv u s amp.
(C q, C q yv, C u) =>
T s u q (R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
firstOrderHighpass = forall q yv u s amp.
(C q, C q yv, C u) =>
Modifier yv (Parameter q) yv yv
-> T s
     u
     q
     (R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
firstOrderGen forall a v. (C a, C a v) => Simple v (Parameter a) v v
Filt1.highpassModifier

{-# INLINE firstOrderGen #-}
firstOrderGen ::
   (Trans.C q, Module.C q yv, Dim.C u) =>
      (Modifier yv (Filt1.Parameter q) yv yv)
   -> Proc.T s u q (
        SigA.R s (Dim.Recip u) q q
     -> Signal s amp yv
     -> Signal s amp yv)
firstOrderGen :: forall q yv u s amp.
(C q, C q yv, C u) =>
Modifier yv (Parameter q) yv yv
-> T s
     u
     q
     (R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
firstOrderGen Modifier yv (Parameter q) yv yv
modif =
   forall u y t s.
(C u, C y) =>
(T y -> t) -> T s u y (R s (Recip u) y y -> t)
frequencyControl forall a b. (a -> b) -> a -> b
$ \ T q
freqs ->
      forall param ctrl state y0 y1 s amp.
(param -> ctrl)
-> Modifier state ctrl y0 y1
-> T param
-> Signal s amp y0
-> Signal s amp y1
modifyModulated forall a. C a => a -> Parameter a
Filt1.parameter Modifier yv (Parameter q) yv yv
modif T q
freqs


{-# INLINE butterworthLowpass #-}
{-# INLINE butterworthHighpass #-}
{-# INLINE chebyshevALowpass #-}
{-# INLINE chebyshevAHighpass #-}
{-# INLINE chebyshevBLowpass #-}
{-# INLINE chebyshevBHighpass #-}

butterworthLowpass, butterworthHighpass,
   chebyshevALowpass, chebyshevAHighpass,
   chebyshevBLowpass, chebyshevBHighpass ::
      (Flat.C q flat, Trans.C q, Module.C q yv, Dim.C u) =>
      NonNeg.Int   {- ^ Order of the filter, must be even,
                        the higher the order, the sharper is the separation of frequencies. -}
   -> Proc.T s u q (
        Signal s flat q {- v The attenuation at the cut-off frequency.
                           Should be between 0 and 1. -}
     -> SigA.R s (Dim.Recip u) q q
                      {- v Control signal for the cut-off frequency. -}
     -> Signal s amp yv {- v Input signal -}
     -> Signal s amp yv)

butterworthLowpass :: forall q flat yv u s amp.
(C q flat, C q, C q yv, C u) =>
Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
butterworthLowpass  = forall q flat u yv s amp.
(C q flat, C q, C u) =>
(Int -> [q] -> [q] -> [yv] -> [yv])
-> Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
higherOrderNoResoGen forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Butter.lowpassPole
butterworthHighpass :: forall q flat yv u s amp.
(C q flat, C q, C q yv, C u) =>
Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
butterworthHighpass = forall q flat u yv s amp.
(C q flat, C q, C u) =>
(Int -> [q] -> [q] -> [yv] -> [yv])
-> Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
higherOrderNoResoGen forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Butter.highpassPole
chebyshevALowpass :: forall q flat yv u s amp.
(C q flat, C q, C q yv, C u) =>
Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
chebyshevALowpass   = forall q flat u yv s amp.
(C q flat, C q, C u) =>
(Int -> [q] -> [q] -> [yv] -> [yv])
-> Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
higherOrderNoResoGen forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Cheby.lowpassAPole
chebyshevAHighpass :: forall q flat yv u s amp.
(C q flat, C q, C q yv, C u) =>
Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
chebyshevAHighpass  = forall q flat u yv s amp.
(C q flat, C q, C u) =>
(Int -> [q] -> [q] -> [yv] -> [yv])
-> Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
higherOrderNoResoGen forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Cheby.highpassAPole
chebyshevBLowpass :: forall q flat yv u s amp.
(C q flat, C q, C q yv, C u) =>
Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
chebyshevBLowpass   = forall q flat u yv s amp.
(C q flat, C q, C u) =>
(Int -> [q] -> [q] -> [yv] -> [yv])
-> Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
higherOrderNoResoGen forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Cheby.lowpassBPole
chebyshevBHighpass :: forall q flat yv u s amp.
(C q flat, C q, C q yv, C u) =>
Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
chebyshevBHighpass  = forall q flat u yv s amp.
(C q flat, C q, C u) =>
(Int -> [q] -> [q] -> [yv] -> [yv])
-> Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
higherOrderNoResoGen forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Cheby.highpassBPole


-- ToDo: switch from list to more efficient data structure
{-# INLINE higherOrderNoResoGen #-}
higherOrderNoResoGen ::
   (Flat.C q flat, Field.C q, Dim.C u) =>
      (Int -> [q] -> [q] -> [yv] -> [yv])
   -> NonNeg.Int
   -> Proc.T s u q (
        Signal s flat q
     -> SigA.R s (Dim.Recip u) q q
     -> Signal s amp yv
     -> Signal s amp yv)
higherOrderNoResoGen :: forall q flat u yv s amp.
(C q flat, C q, C u) =>
(Int -> [q] -> [q] -> [yv] -> [yv])
-> Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
higherOrderNoResoGen Int -> [q] -> [q] -> [yv] -> [yv]
filt Int
order =
   forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. (a -> b) -> a -> b
$ forall u y t s.
(C u, C y) =>
(T y -> t) -> T s u y (R s (Recip u) y y -> t)
frequencyControl forall a b. (a -> b) -> a -> b
$ \ T q
freqs Signal s flat q
ratios ->
      forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody
         (forall y. [y] -> T y
Sig.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
.
          Int -> [q] -> [q] -> [yv] -> [yv]
filt (forall a. T a -> a
NonNeg.toNumber Int
order)
             (forall y. T y -> [y]
Sig.toList (forall y flat (sig :: * -> *) rate.
(C y flat, Transform sig y) =>
T rate flat (sig y) -> sig y
Flat.toSamples Signal s flat q
ratios)) (forall y. T y -> [y]
Sig.toList T q
freqs) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
          forall y. T y -> [y]
Sig.toList)



{-# INLINE highpassFromUniversal #-}
{-# INLINE bandpassFromUniversal #-}
{-# INLINE lowpassFromUniversal #-}
{-# INLINE bandlimitFromUniversal #-}
highpassFromUniversal, lowpassFromUniversal,
  bandpassFromUniversal, bandlimitFromUniversal ::
        Signal s amp (UniFilter.Result yv)
     -> Signal s amp yv
{-
   (Dim.C u) =>
      Proc.T s u q (
        Signal s amp (UniFilter.Result yv)
     -> Signal s amp yv)
-}
highpassFromUniversal :: forall s amp yv. Signal s amp (Result yv) -> Signal s amp yv
highpassFromUniversal  = forall y0 y1 rate amp.
(y0 -> y1) -> T rate amp (T y0) -> T rate amp (T y1)
homogeneousMap forall a. Result a -> a
UniFilter.highpass
bandpassFromUniversal :: forall s amp yv. Signal s amp (Result yv) -> Signal s amp yv
bandpassFromUniversal  = forall y0 y1 rate amp.
(y0 -> y1) -> T rate amp (T y0) -> T rate amp (T y1)
homogeneousMap forall a. Result a -> a
UniFilter.bandpass
lowpassFromUniversal :: forall s amp yv. Signal s amp (Result yv) -> Signal s amp yv
lowpassFromUniversal   = forall y0 y1 rate amp.
(y0 -> y1) -> T rate amp (T y0) -> T rate amp (T y1)
homogeneousMap forall a. Result a -> a
UniFilter.lowpass
bandlimitFromUniversal :: forall s amp yv. Signal s amp (Result yv) -> Signal s amp yv
bandlimitFromUniversal = forall y0 y1 rate amp.
(y0 -> y1) -> T rate amp (T y0) -> T rate amp (T y1)
homogeneousMap forall a. Result a -> a
UniFilter.bandlimit

homogeneousMap ::
   (y0 -> y1) ->
   SigA.T rate amp (Sig.T y0) -> SigA.T rate amp (Sig.T y1)
homogeneousMap :: forall y0 y1 rate amp.
(y0 -> y1) -> T rate amp (T y0) -> T rate amp (T y1)
homogeneousMap y0 -> y1
f =
   forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody (forall a b. (a -> b) -> T a -> T b
Sig.map y0 -> y1
f)

{-
homogeneousMap0 :: (Hom.C sig) =>
   (y0 -> y1) ->
   Signal s amp y0 -> Signal s amp y1
homogeneousMap0 f =
   SigA.processBody (Sig.map f)

homogeneousMap1 :: (Hom.C sig) =>
   (y0 -> y1) ->
   Proc.T s1 u t (Signal s amp y0 -> Signal s amp y1)
homogeneousMap1 f =
   Proc.pure (SigA.processBody (Sig.map f))
-}


{-# INLINE universal #-}
universal ::
   (Flat.C q flat, Trans.C q, Module.C q yv, Dim.C u) =>
      Proc.T s u q (
        Signal s flat q
                    {- v signal for resonance,
                         i.e. factor of amplification at the resonance frequency
                         relatively to the transition band. -}
     -> SigA.R s (Dim.Recip u) q q
                    {- v signal for cut off and band center frequency -}
     -> Signal s amp yv
                    {- v input signal -}
     -> Signal s amp (UniFilter.Result yv))
                    {- ^ highpass, bandpass, lowpass filter -}
universal :: forall q flat yv u s amp.
(C q flat, C q, C q yv, C u) =>
T s
  u
  q
  (Signal s flat q
   -> R s (Recip u) q q
   -> Signal s amp yv
   -> Signal s amp (Result yv))
universal =
   forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. (a -> b) -> a -> b
$ forall u y t s.
(C u, C y) =>
(T y -> t) -> T s u y (R s (Recip u) y y -> t)
frequencyControl forall a b. (a -> b) -> a -> b
$ \ T q
freqs Signal s flat q
reso ->
      let resos :: T q
resos = forall y flat (sig :: * -> *) rate.
(C y flat, Transform sig y) =>
T rate flat (sig y) -> sig y
Flat.toSamples Signal s flat q
reso
      in  forall param ctrl state y0 y1 s amp.
(param -> ctrl)
-> Modifier state ctrl y0 y1
-> T param
-> Signal s amp y0
-> Signal s amp y1
modifyModulated
             forall a. C a => Pole a -> Parameter a
UniFilter.parameter
             forall a v.
(C a, C a v) =>
Simple (State v) (Parameter a) v (Result v)
UniFilter.modifier
             (forall a b c. (a -> b -> c) -> T a -> T b -> T c
Sig.zipWith forall a. a -> a -> Pole a
FiltRec.Pole T q
resos T q
freqs)

{-# INLINE moogLowpass #-}
moogLowpass :: (Flat.C q flat, Trans.C q, Module.C q yv, Dim.C u) =>
      NonNeg.Int
   -> Proc.T s u q (
        Signal s flat q
                   {- v signal for resonance,
                        i.e. factor of amplification at the resonance frequency
                        relatively to the transition band. -}
     -> SigA.R s (Dim.Recip u) q q
                   {- v signal for cut off frequency -}
     -> Signal s amp yv
     -> Signal s amp yv)
moogLowpass :: forall q flat yv u s amp.
(C q flat, C q, C q yv, C u) =>
Int
-> T s
     u
     q
     (Signal s flat q
      -> R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
moogLowpass Int
order =
   forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. (a -> b) -> a -> b
$ forall u y t s.
(C u, C y) =>
(T y -> t) -> T s u y (R s (Recip u) y y -> t)
frequencyControl forall a b. (a -> b) -> a -> b
$ \ T q
freqs Signal s flat q
reso ->
      let resos :: T q
resos = forall y flat (sig :: * -> *) rate.
(C y flat, Transform sig y) =>
T rate flat (sig y) -> sig y
Flat.toSamples Signal s flat q
reso
          orderInt :: Int
orderInt = forall a. T a -> a
NonNeg.toNumber Int
order
      in  forall param ctrl state y0 y1 s amp.
(param -> ctrl)
-> Modifier state ctrl y0 y1
-> T param
-> Signal s amp y0
-> Signal s amp y1
modifyModulated
             (forall a. C a => Int -> Pole a -> Parameter a
Moog.parameter Int
orderInt)
             (forall a v.
(C a, C a v) =>
Int -> Simple (State v) (Parameter a) v v
Moog.lowpassModifier Int
orderInt)
             (forall a b c. (a -> b -> c) -> T a -> T b -> T c
Sig.zipWith forall a. a -> a -> Pole a
FiltRec.Pole T q
resos T q
freqs)


{-# INLINE allpassCascade #-}
allpassCascade :: (Trans.C q, Module.C q yv, Dim.C u) =>
      NonNeg.Int  {- ^ order, number of filters in the cascade -}
   -> q           {- ^ the phase shift to be achieved for the given frequency -}
   -> Proc.T s u q (
        SigA.R s (Dim.Recip u) q q {- v lowest comb frequency -}
     -> Signal s amp yv
     -> Signal s amp yv)
allpassCascade :: forall q yv u s amp.
(C q, C q yv, C u) =>
Int
-> q
-> T s
     u
     q
     (R s (Recip u) q q -> Signal s amp yv -> Signal s amp yv)
allpassCascade Int
order q
phase =
   forall u y t s.
(C u, C y) =>
(T y -> t) -> T s u y (R s (Recip u) y y -> t)
frequencyControl forall a b. (a -> b) -> a -> b
$ \ T q
freqs ->
      let orderInt :: Int
orderInt = forall a. T a -> a
NonNeg.toNumber Int
order
      in  forall param ctrl state y0 y1 s amp.
(param -> ctrl)
-> Modifier state ctrl y0 y1
-> T param
-> Signal s amp y0
-> Signal s amp y1
modifyModulated
             (forall a. C a => Int -> a -> a -> Parameter a
Allpass.cascadeParameter Int
orderInt q
phase)
             (forall a v. (C a, C a v) => Int -> Simple [v] (Parameter a) v v
Allpass.cascadeModifier Int
orderInt)
             T q
freqs

{-# INLINE allpassFlangerPhase #-}
allpassFlangerPhase :: Trans.C a => a
allpassFlangerPhase :: forall a. C a => a
allpassFlangerPhase = forall a. C a => a
Allpass.flangerPhase


{- | Infinitely many equi-delayed exponentially decaying echos. -}
{-# INLINE comb #-}
comb :: (RealRing.C t, Module.C y yv, Dim.C u, Storable yv) =>
   DN.T u t -> y -> Proc.T s u t (Signal s amp yv -> Signal s amp yv)
comb :: forall t y yv u s amp.
(C t, C y yv, C u, Storable yv) =>
T u t -> y -> T s u t (Signal s amp yv -> Signal s amp yv)
comb T u t
time y
gain =
   do t
t <- forall t u s. (C t, C u) => T u t -> T s u t t
toTimeScalar T u t
time
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody
         (forall a. Storable a => T a -> T a
fromStorable forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t y (sig :: * -> *).
(C t y, Write sig y) =>
Int -> t -> sig y -> sig y
Comb.run (forall a b. (C a, C b) => a -> b
round t
t) y
gain forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Storable a => T a -> T a
toStorable)


-- * auxiliary functions

{-# INLINE frequencyControl #-}
frequencyControl :: (Dim.C u, Field.C y) =>
      (Sig.T y -> t)
   -> Proc.T s u y (
        SigA.R s (Dim.Recip u) y y
     -> t)
frequencyControl :: forall u y t s.
(C u, C y) =>
(T y -> t) -> T s u y (R s (Recip u) y y -> t)
frequencyControl T y -> t
f =
   do T (Recip u) y -> y
toFreq <- forall a s u t b. (a -> T s u t b) -> T s u t (a -> b)
Proc.withParam forall t u s. (C t, C u) => T (Recip u) t -> T s u t t
toFrequencyScalar
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \ R s (Recip u) y y
freq -> T y -> t
f (forall y (sig :: * -> *) amp rate.
(C y, Transform sig y) =>
(amp -> y) -> T rate (Numeric amp) (sig y) -> sig y
SigA.scalarSamples T (Recip u) y -> y
toFreq R s (Recip u) y y
freq)


{-# INLINE modifyModulated #-}
modifyModulated ::
   (param -> ctrl) ->
   Modifier state ctrl y0 y1 ->
   Sig.T param ->
   Signal s amp y0 ->
   Signal s amp y1
modifyModulated :: forall param ctrl state y0 y1 s amp.
(param -> ctrl)
-> Modifier state ctrl y0 y1
-> T param
-> Signal s amp y0
-> Signal s amp y1
modifyModulated param -> ctrl
makeParam Modifier state ctrl y0 y1
modif T param
params =
   forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody (forall s ctrl a b. Simple s ctrl a b -> T ctrl -> T a -> T b
Sig.modifyModulated Modifier state ctrl y0 y1
modif (forall a b. (a -> b) -> T a -> T b
Sig.map param -> ctrl
makeParam T param
params))