synthesizer-0.0.3: src/Synthesizer/Dimensional/Amplitude/Displacement.hs
{- |
Copyright : (c) Henning Thielemann 2008
License : GPL
Maintainer : synthesizer@henning-thielemann.de
Stability : provisional
Portability : requires multi-parameter type classes
-}
module Synthesizer.Dimensional.Amplitude.Displacement (
mix, mixVolume,
mixMulti, mixMultiVolume,
raise, distort,
) where
import qualified Synthesizer.Dimensional.Abstraction.RateIndependent as Ind
import qualified Synthesizer.Dimensional.Amplitude.Signal as SigA
import Synthesizer.Dimensional.Amplitude.Signal (toAmplitudeScalar)
import qualified Number.DimensionTerm as DN
import qualified Algebra.DimensionTerm as Dim
-- import Number.DimensionTerm ((&*&))
import qualified Synthesizer.State.Displacement as Disp
import qualified Synthesizer.State.Signal as Sig
import qualified Algebra.Module as Module
import qualified Algebra.Field as Field
import qualified Algebra.Real as Real
-- import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import Algebra.Module ((*>))
import PreludeBase
import NumericPrelude
import Prelude ()
{- * Mixing -}
{-| Mix two signals.
In opposition to 'zipWith' the result has the length of the longer signal. -}
{-# INLINE mix #-}
mix ::
(Real.C y, Field.C y, Module.C y yv, Dim.C u) =>
SigA.R s u y yv
-> SigA.R s u y yv
-> SigA.R s u y yv
mix x y =
mixVolume (DN.abs (SigA.amplitude x) + DN.abs (SigA.amplitude y)) x y
{-# INLINE mixVolume #-}
mixVolume ::
(Real.C y, Field.C y, Module.C y yv, Dim.C u) =>
DN.T u y
-> SigA.R s u y yv
-> SigA.R s u y yv
-> SigA.R s u y yv
mixVolume v x y =
let z = SigA.fromSamples v
(toAmplitudeScalar z (SigA.amplitude x) *> SigA.samples x +
toAmplitudeScalar z (SigA.amplitude y) *> SigA.samples y)
in z
{-| Mix one or more signals. -}
{-# INLINE mixMulti #-}
mixMulti ::
(Real.C y, Field.C y, Module.C y yv, Dim.C u) =>
[SigA.R s u y yv]
-> SigA.R s u y yv
mixMulti x =
mixMultiVolume (sum (map (DN.abs . SigA.amplitude) x)) x
{-# INLINE mixMultiVolume #-}
mixMultiVolume ::
(Real.C y, Field.C y, Module.C y yv, Dim.C u) =>
DN.T u y
-> [SigA.R s u y yv]
-> SigA.R s u y yv
mixMultiVolume v x =
let z = SigA.fromSamples v
(foldr (\y -> (toAmplitudeScalar z (SigA.amplitude y) *>
SigA.samples y +)) Sig.empty x)
in z
{-| Add a number to all of the signal values.
This is useful for adjusting the center of a modulation. -}
{-# INLINE raise #-}
raise :: (Ind.C w, Field.C y, Module.C y yv, Dim.C u) =>
DN.T u y
-> yv
-> w (SigA.S u y) yv
-> w (SigA.S u y) yv
raise y' yv x =
SigA.processSamples
(Disp.raise (toAmplitudeScalar x y' *> yv)) x
{-# INLINE distort #-}
distort :: (Field.C y, Module.C y yv, Dim.C u) =>
(yv -> yv)
-> SigA.R s u y y
-> SigA.R s u y yv
-> SigA.R s u y yv
distort f cs xs =
SigA.processSamples
(Sig.zipWith
(\c y -> c *> f (recip c *> y))
(SigA.scalarSamples (toAmplitudeScalar xs) cs)) xs