{-# LANGUAGE NoImplicitPrelude #-}
module Synthesizer.Basic.DistortionControlled (
   clip, logit,
   zigZag, sine,
   quantize,
   ) where

import qualified Synthesizer.Basic.Distortion  as Dist

import qualified Algebra.Transcendental        as Trans
import qualified Algebra.RealField             as RealField
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 Data.Ord.HT (limit, )

-- import qualified Prelude as P
-- import PreludeBase
import NumericPrelude

{- * Clipping -}

{- |
limit, fuzz booster
-}
clip :: (Real.C a) => a -> a -> a
clip c = limit (negate c, c)

{- |
logit, tanh
-}
logit :: (Trans.C a) => a -> a -> a
logit k = rescale k Dist.logit

{-
probit, error function
-}



{- * Wrapping -}

{- |
zig-zag
-}
zigZag :: (RealField.C a) => a -> a -> a
zigZag k = rescale k Dist.zigZag

{- |
sine
-}
sine :: (Trans.C a) => a -> a -> a
sine k = rescale k Dist.sine




{- * Quantization -}

quantize :: (RealField.C a) => a -> a -> a
quantize k = rescale k Dist.quantize



{- Auxilary function -}

rescale :: (Field.C a) => a -> (a -> a) -> a -> a
rescale k f x = k * f (x/k)

{-
*Synthesizer.Basic.Distortion> GNUPlot.plotFuncs [] (GNUPlot.linearScale 1000 (-3,3::Double)) (map logit [0,0.1..1])
-}