{-# LANGUAGE NoImplicitPrelude #-} {- | -} module Synthesizer.Generic.Displacement where import qualified Synthesizer.Generic.Signal as SigG import qualified Algebra.Transcendental as Trans import qualified Algebra.Ring as Ring import qualified Algebra.Additive as Additive import NumericPrelude.Numeric import NumericPrelude.Base -- * Mixing {-| Mix two signals. In opposition to 'zipWith' the result has the length of the longer signal. -} mix :: (Additive.C v, SigG.Transform sig v) => sig v -> sig v -> sig v mix = SigG.mix {- relict from Prelude98's Num mixMono :: Ring.C a => [a] -> [a] -> [a] mixMono [] x = x mixMono x [] = x mixMono (x:xs) (y:ys) = x+y : mixMono xs ys -} {-| Mix one or more signals. -} mixMulti :: (Additive.C v, SigG.Transform sig v) => [sig v] -> sig v mixMulti = foldl mix SigG.empty {-| Add a number to all of the signal values. This is useful for adjusting the center of a modulation. -} raise :: (Additive.C v, SigG.Transform sig v) => v -> sig v -> sig v raise x = SigG.map ((+) x) -- * Distortion {- | In "Synthesizer.Basic.Distortion" you find a collection of appropriate distortion functions. -} distort :: (SigG.Read sig c, SigG.Transform sig v) => (c -> v -> v) -> sig c -> sig v -> sig v distort = SigG.zipWith -- * Preprocessing of control curves {-# INLINE mapLinear #-} mapLinear :: (Ring.C a, SigG.Transform sig a) => a -> a -> sig a -> sig a mapLinear depth center = SigG.map (\x -> center*(one+x*depth)) {-# INLINE mapExponential #-} mapExponential :: (Trans.C a, SigG.Transform sig a) => a -> a -> sig a -> sig a mapExponential depth center = -- SigG.map ((center*) . (depth**)) -- should be faster let logDepth = log depth in SigG.map ((center*) . exp . (logDepth*))