packages feed

synthesizer-dimensional-0.3: src/Synthesizer/Dimensional/Wave.hs

module Synthesizer.Dimensional.Wave where

import qualified Synthesizer.Basic.Wave as Wave
import qualified Synthesizer.Generic.Wave as WaveG
import qualified Synthesizer.Generic.Signal as SigG

import qualified Synthesizer.Interpolation as Interpolation

import qualified Synthesizer.Dimensional.Signal.Private as SigA
import qualified Synthesizer.Dimensional.Amplitude as Amp

import qualified Algebra.Transcendental as Trans
import qualified Algebra.RealField      as RealField
import qualified Algebra.Ring           as Ring

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

import NumericPrelude
import PreludeBase
import Prelude ()


data T amp t y =
   Cons {
      amplitude :: amp,
      body :: Wave.T t y
   }

{-
data T amp body =
   Cons {
      amplitude :: amp,
      body :: body
   }
-}

infix 7 &*~

{-# INLINE (&*~) #-}
(&*~) ::
   amp ->
   Wave.T t y ->
   T (Amp.Numeric amp) t y
(&*~) = amplified


{-# INLINE sample #-}
sample ::
   (RealField.C t, SigG.Transform sig y) =>
   Interpolation.T t y ->
   SigA.T rate amp (sig y) -> T amp t y
sample ip wave =
   Cons (SigA.amplitude wave) $
   WaveG.sample ip (SigA.body wave)


{-# INLINE flat #-}
flat :: (Ring.C y) =>
   Wave.T t y ->
   T (Amp.Flat y) t y
flat = Cons Amp.Flat


{-# INLINE abstract #-}
abstract ::
   Wave.T t y ->
   T Amp.Abstract t y
abstract = Cons Amp.Abstract


{-# INLINE amplified #-}
amplified ::
   amp ->
   Wave.T t y ->
   T (Amp.Numeric amp) t y
{-
 (Ring.C y, Dim.C u) =>
   DN.T u y ->
   Wave.T t y ->
   T (Amp.Dimensional u y) t y
-}
{-
   amp ->
   Wave.T t y ->
   T amp t y
-}
amplified = Cons . Amp.Numeric


{-# INLINE mapLinear #-}
mapLinear :: (Ring.C y, Dim.C u) =>
   y ->
   DN.T u y ->
   Wave.T t y ->
   T (Amp.Dimensional u y) t y
mapLinear depth center =
   amplified center . Wave.distort (\x -> one+x*depth)

{-# INLINE mapExponential #-}
mapExponential :: (Trans.C y, Dim.C u) =>
   y ->
   DN.T u y ->
   Wave.T t y ->
   T (Amp.Dimensional u y) t y
mapExponential depth center =
   -- amplified center . Wave.distort (depth**)
   -- should be faster
   amplified center .
      let logDepth = log depth
      in  Wave.distort (exp . (logDepth*))