{-# LANGUAGE MultiParamTypeClasses #-}{-# LANGUAGE FunctionalDependencies #-}{-# LANGUAGE FlexibleInstances #-}{- |
Copyright : (c) Henning Thielemann 2008-2009
License : GPL
Maintainer : synthesizer@henning-thielemann.de
Stability : provisional
Portability : requires multi-parameter type classes
A class that allows unified handling of
@Amplitude.Flat@ and @Amplitude.Dimensional Dim.Scalar@
which is often used for control curves.
However, I'm thinking about whether this is more abuse than use.
So this class may disappear in future.
Amplitude.Flat might become a synonym for @DN.scalar one@.
Sometimes, using Flat instead of DN.Scalar has the advantage
of internally saving a multiplication with one,
but I think the compiler should optimize that away.
The optimization however is more complicated
if a whole StorableVector is multiplied element-wise by one.
E.g. the concatenation of flat (storable) signals
can be done without copying the entire data.
-}moduleSynthesizer.Dimensional.Amplitude.Flat(C,amplifySample,canonicalize,toSamples,)whereimportqualifiedSynthesizer.Dimensional.AmplitudeasAmpimportqualifiedSynthesizer.Dimensional.Signal.PrivateasSigAimportqualifiedSynthesizer.Generic.Filter.NonRecursiveasFiltGimportqualifiedSynthesizer.Generic.SignalasSigG-- import qualified Synthesizer.State.Signal as SigimportqualifiedNumber.DimensionTermasDNimportqualifiedAlgebra.DimensionTermasDim{-
import qualified Algebra.Module as Module
import qualified Algebra.Field as Field
-}importqualifiedAlgebra.RingasRing-- import Number.DimensionTerm ((&/&))importNumericPrelude.NumericimportNumericPrelude.BaseimportPrelude(){-
we could use OccasionallyScalar class,
but this would flood user code with OccScalar.C y y constraints
-}classAmp.Camp=>Cyamp|amp->ywheretoScalar::amp->yamplifySample::amp->y->yamplify::(SigG.Transformsigy)=>amp->sigy->sigyinstanceRing.Cy=>Cy(Amp.Flaty)wheretoScalar=constRing.oneamplifySample_=idamplify_=idinstance(Dim.IsScalarv,Ring.Cy)=>Cy(Amp.Numeric(DN.Tvy))wheretoScalar(Amp.Numericamp)=DN.toNumber.DN.rewriteDimensionDim.toScalar$ampamplifySampleampy=toScalaramp*yamplifyamp=FiltG.amplify(toScalaramp){- DEPRECATED toSamples "this function drops the sample rate, better use canonicalize" -}{-# INLINE toSamples #-}toSamples::(Cyflat,SigG.Transformsigy)=>SigA.Trateflat(sigy)->sigytoSamplessig=amplify(SigA.amplitudesig)(SigA.bodysig){-# INLINE canonicalize #-}canonicalize::(Cyflat,SigG.Transformsigy)=>SigA.Trateflat(sigy)->SigA.Trate(Amp.Flaty)(sigy)canonicalizesig=SigA.Cons(SigA.sampleRatesig)Amp.Flat(toSamplessig)