{- |
Copyright   :  (c) Henning Thielemann 2008
License     :  GPL

Maintainer  :  synthesizer@henning-thielemann.de
Stability   :  provisional
Portability :  requires multi-parameter type classes (OccasionallyScalar)

Signals equipped with a volume information that may carry a unit.
-}
module Synthesizer.Amplitude.Signal where

import qualified Algebra.OccasionallyScalar as OccScalar
import qualified Algebra.Module         as Module
import qualified Algebra.Field          as Field
import qualified Algebra.Ring           as Ring

import Algebra.OccasionallyScalar (toScalar)

import NumericPrelude
import PreludeBase as P
import Prelude ()


data T y y' yv =
   Cons {
        amplitude  :: y'   {-^ scaling of the values -}
      , samples    :: [yv] {-^ the sampled values -}
     }
   deriving (Eq, Show)


instance Functor (T y y') where
   fmap f (Cons amp ss) = Cons amp (map f ss)


toAmplitudeScalar :: (Field.C y', OccScalar.C y y') =>
   T y y' yv -> y' -> y
toAmplitudeScalar sig y =
   toScalar (y / amplitude sig)


scalarSamples :: (Ring.C y) =>
   (y' -> y) -> T y y' y -> [y]
scalarSamples toAmpScalar sig =
   let y = toAmpScalar (amplitude sig)
   in  map (y*) (samples sig)

vectorSamples :: (Module.C y yv) =>
   (y' -> y) -> T y y' yv -> [yv]
vectorSamples toAmpScalar sig =
   let y = toAmpScalar (amplitude sig)
   in  y *> samples sig



replaceAmplitude :: y1' -> T y y0' yv -> T y y1' yv
replaceAmplitude amp (Cons _ ss)  =  Cons amp ss

replaceSamples :: [yv1] -> T y y' yv0 -> T y y' yv1
replaceSamples ss (Cons amp _)  =  Cons amp ss