{- | Copyright : (c) Henning Thielemann 2008 License : GPL Maintainer : synthesizer@henning-thielemann.de Stability : provisional Portability : requires multi-parameter type classes -} module Synthesizer.Amplitude.Displacement ( mix, mixVolume, mixMulti, mixMultiVolume, raise, ) where import qualified Synthesizer.Amplitude.Signal as SigV import Synthesizer.Amplitude.Signal (toAmplitudeScalar) import qualified Synthesizer.Plain.Displacement as Synthesizer import qualified Algebra.OccasionallyScalar as OccScalar import qualified Algebra.Module as Module -- import qualified Algebra.Transcendental as Trans 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. -} mix :: (Real.C y', Field.C y', Module.C y yv, OccScalar.C y y') => SigV.T y y' yv -> SigV.T y y' yv -> SigV.T y y' yv mix x y = mixVolume (abs (SigV.amplitude x) + abs (SigV.amplitude y)) x y mixVolume :: (Real.C y', Field.C y', Module.C y yv, OccScalar.C y y') => y' -> SigV.T y y' yv -> SigV.T y y' yv -> SigV.T y y' yv mixVolume v x y = let z = SigV.Cons v (toAmplitudeScalar z (SigV.amplitude x) *> SigV.samples x + toAmplitudeScalar z (SigV.amplitude y) *> SigV.samples y) in z {-| Mix one or more signals. -} mixMulti :: (Real.C y', Field.C y', Module.C y yv, OccScalar.C y y') => [SigV.T y y' yv] -> SigV.T y y' yv mixMulti x = mixMultiVolume (sum (map (abs . SigV.amplitude) x)) x mixMultiVolume :: (Real.C y', Field.C y', Module.C y yv, OccScalar.C y y') => y' -> [SigV.T y y' yv] -> SigV.T y y' yv mixMultiVolume v x = let z = SigV.Cons v (foldr (\y -> (toAmplitudeScalar z (SigV.amplitude y) *> SigV.samples y +)) [] x) in z {-| Add a number to all of the signal values. This is useful for adjusting the center of a modulation. -} raise :: (Field.C y', Module.C y yv, OccScalar.C y y') => y' -> yv -> SigV.T y y' yv -> SigV.T y y' yv raise y' yv x = SigV.Cons (SigV.amplitude x) (Synthesizer.raise (toAmplitudeScalar x y' *> yv) (SigV.samples x))