{-# LANGUAGE FlexibleContexts #-}
module Synthesizer.Dimensional.Cyclic.Analysis (
toFrequencySpectrum, fromFrequencySpectrum,
) where
import qualified Synthesizer.Generic.Fourier as FourierG
import qualified Synthesizer.Generic.Signal as SigG
import qualified Synthesizer.Generic.Cut as CutG
import qualified Synthesizer.Dimensional.Rate as Rate
import qualified Synthesizer.Dimensional.Amplitude as Amp
import qualified Synthesizer.Dimensional.Signal.Private as SigA
import qualified Synthesizer.Dimensional.Cyclic.Signal as SigC
import qualified Number.DimensionTerm as DN
import qualified Algebra.DimensionTerm as Dim
import Number.DimensionTerm ((&*&), (*&), )
import qualified Number.Complex as Complex
import qualified Algebra.Transcendental as Trans
import qualified Algebra.Field as Field
import NumericPrelude.Base ((.), ($), )
import NumericPrelude.Numeric (fromIntegral, )
import Prelude ()
{-# INLINE period #-}
period :: (Field.C t, Dim.C u, CutG.Read body) =>
SigA.T (Rate.Dimensional u t) amp (SigC.T body) ->
DN.T u t
period :: forall t u body amp.
(C t, C u, Read body) =>
T (Dimensional u t) amp (T body) -> T u t
period = forall t u body amp.
(C t, C u) =>
(body -> t) -> T (Dimensional u t) amp (T body) -> T u t
makePhysicalPeriod (forall a b. (C a, C b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall sig. Read sig => sig -> Int
CutG.length)
{-# INLINE makePhysicalPeriod #-}
makePhysicalPeriod :: (Field.C t, Dim.C u) =>
(body -> t) ->
SigA.T (Rate.Dimensional u t) amp (SigC.T body) ->
DN.T u t
makePhysicalPeriod :: forall t u body amp.
(C t, C u) =>
(body -> t) -> T (Dimensional u t) amp (T body) -> T u t
makePhysicalPeriod body -> t
f T (Dimensional u t) amp (T body)
x =
body -> t
f (forall period. T period -> period
SigC.toPeriod (forall rate amplitude body. T rate amplitude body -> body
SigA.body T (Dimensional u t) amp (T body)
x))
forall u a. (C u, C a) => a -> T u a -> T u a
*& forall u a. (C u, C a) => T (Recip u) a -> T u a
DN.unrecip (forall rate amp sig. T (Actual rate) amp sig -> rate
SigA.actualSampleRate T (Dimensional u t) amp (T body)
x)
{-# INLINE toFrequencySpectrum #-}
toFrequencySpectrum ::
(Trans.C q, Dim.C u, Dim.C v,
SigG.Transform sig (Complex.T q)) =>
SigA.T (Rate.Dimensional u q) (Amp.Dimensional v q) (SigC.T (sig (Complex.T q))) ->
SigA.T (Rate.Dimensional (Dim.Recip u) q) (Amp.Dimensional (Dim.Mul u v) q) (SigC.T (sig (Complex.T q)))
toFrequencySpectrum :: forall q u v (sig :: * -> *).
(C q, C u, C v, Transform sig (T q)) =>
T (Dimensional u q) (Dimensional v q) (T (sig (T q)))
-> T (Dimensional (Recip u) q)
(Dimensional (Mul u v) q)
(T (sig (T q)))
toFrequencySpectrum T (Dimensional u q) (Dimensional v q) (T (sig (T q)))
x =
let len :: T (Recip (Recip u)) q
len = forall u v a. (C u, C v) => (u -> v) -> T u a -> T v a
DN.rewriteDimension forall u. C u => u -> Recip (Recip u)
Dim.doubleRecip (forall t u body amp.
(C t, C u, Read body) =>
T (Dimensional u t) amp (T body) -> T u t
period T (Dimensional u q) (Dimensional v q) (T (sig (T q)))
x)
amp :: T v q
amp = forall rate amp sig. T rate (Numeric amp) sig -> amp
SigA.actualAmplitude T (Dimensional u q) (Dimensional v q) (T (sig (T q)))
x
newAmp :: T (Mul u v) q
newAmp = forall u a. (C u, C a) => T (Recip u) a -> T u a
DN.unrecip (forall rate amp sig. T (Actual rate) amp sig -> rate
SigA.actualSampleRate T (Dimensional u q) (Dimensional v q) (T (sig (T q)))
x) forall u v a. (C u, C v, C a) => T u a -> T v a -> T (Mul u v) a
&*& T v q
amp
in forall rate amplitude body.
rate -> amplitude -> body -> T rate amplitude body
SigA.Cons
(forall rate. rate -> Actual rate
Rate.Actual T (Recip (Recip u)) q
len)
(forall amp. amp -> Numeric amp
Amp.Numeric T (Mul u v) q
newAmp)
(forall period. period -> T period
SigC.Cons forall a b. (a -> b) -> a -> b
$ forall y (sig :: * -> *).
(Element y, Transform sig y) =>
sig y -> sig y
FourierG.transformBackward forall a b. (a -> b) -> a -> b
$ forall period. T period -> period
SigC.toPeriod forall a b. (a -> b) -> a -> b
$ forall rate amplitude body. T rate amplitude body -> body
SigA.body T (Dimensional u q) (Dimensional v q) (T (sig (T q)))
x)
{-# INLINE fromFrequencySpectrum #-}
fromFrequencySpectrum ::
(Trans.C q, Dim.C u, Dim.C v,
SigG.Transform sig (Complex.T q)) =>
SigA.T (Rate.Dimensional (Dim.Recip u) q) (Amp.Dimensional (Dim.Mul u v) q) (SigC.T (sig (Complex.T q))) ->
SigA.T (Rate.Dimensional u q) (Amp.Dimensional v q) (SigC.T (sig (Complex.T q)))
fromFrequencySpectrum :: forall q u v (sig :: * -> *).
(C q, C u, C v, Transform sig (T q)) =>
T (Dimensional (Recip u) q)
(Dimensional (Mul u v) q)
(T (sig (T q)))
-> T (Dimensional u q) (Dimensional v q) (T (sig (T q)))
fromFrequencySpectrum T (Dimensional (Recip u) q)
(Dimensional (Mul u v) q)
(T (sig (T q)))
x =
let len :: T (Recip u) q
len = forall t u body amp.
(C t, C u, Read body) =>
T (Dimensional u t) amp (T body) -> T u t
period T (Dimensional (Recip u) q)
(Dimensional (Mul u v) q)
(T (sig (T q)))
x
amp :: T (Mul u v) q
amp = forall rate amp sig. T rate (Numeric amp) sig -> amp
SigA.actualAmplitude T (Dimensional (Recip u) q)
(Dimensional (Mul u v) q)
(T (sig (T q)))
x
newAmp :: T v q
newAmp =
forall u v a. (C u, C v) => (u -> v) -> T u a -> T v a
DN.rewriteDimension
(forall u. C u => Mul Scalar u -> u
Dim.identityLeft forall b c a. (b -> c) -> (a -> b) -> a -> c
.
forall u0 u1 v.
(C u0, C u1, C v) =>
(u0 -> u1) -> Mul u0 v -> Mul u1 v
Dim.applyLeftMul forall u. C u => Mul (Recip u) u -> Scalar
Dim.cancelLeft forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall u0 u1 u2.
(C u0, C u1, C u2) =>
Mul u0 (Mul u1 u2) -> Mul (Mul u0 u1) u2
Dim.associateLeft)
(forall u a. (C u, C a) => T (Recip u) a -> T u a
DN.unrecip (forall rate amp sig. T (Actual rate) amp sig -> rate
SigA.actualSampleRate T (Dimensional (Recip u) q)
(Dimensional (Mul u v) q)
(T (sig (T q)))
x) forall u v a. (C u, C v, C a) => T u a -> T v a -> T (Mul u v) a
&*& T (Mul u v) q
amp)
in forall rate amplitude body.
rate -> amplitude -> body -> T rate amplitude body
SigA.Cons
(forall rate. rate -> Actual rate
Rate.Actual T (Recip u) q
len)
(forall amp. amp -> Numeric amp
Amp.Numeric T v q
newAmp)
(forall period. period -> T period
SigC.Cons forall a b. (a -> b) -> a -> b
$ forall y (sig :: * -> *).
(Element y, Transform sig y) =>
sig y -> sig y
FourierG.transformForward forall a b. (a -> b) -> a -> b
$ forall period. T period -> period
SigC.toPeriod forall a b. (a -> b) -> a -> b
$ forall rate amplitude body. T rate amplitude body -> body
SigA.body T (Dimensional (Recip u) q)
(Dimensional (Mul u v) q)
(T (sig (T q)))
x)