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

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

Treat a signal as period of a cyclic signal.

ToDo:
In principle this module does no longer belong to dimensional package
but could be moved to synthesizer-core.
-}
module Synthesizer.Dimensional.Cyclic.Signal where

-- import qualified Synthesizer.Format as Format

import qualified Synthesizer.Generic.Cyclic as Cyclic
import qualified Synthesizer.Generic.Signal as SigG
-- import qualified Synthesizer.State.Signal as Sig

{-
import qualified Algebra.Module         as Module
import qualified Algebra.Field          as Field
import qualified Algebra.Ring           as Ring
-}
import qualified Algebra.Additive       as Additive

import Data.Monoid (Monoid, )


import NumericPrelude.Numeric
import NumericPrelude.Base
import Prelude ()


newtype T period =
   Cons {
      forall period. T period -> period
toPeriod :: period   {-^ the sampled values -}
   }
   deriving (T period -> T period -> Bool
forall period. Eq period => T period -> T period -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: T period -> T period -> Bool
$c/= :: forall period. Eq period => T period -> T period -> Bool
== :: T period -> T period -> Bool
$c== :: forall period. Eq period => T period -> T period -> Bool
Eq, Int -> T period -> ShowS
forall period. Show period => Int -> T period -> ShowS
forall period. Show period => [T period] -> ShowS
forall period. Show period => T period -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [T period] -> ShowS
$cshowList :: forall period. Show period => [T period] -> ShowS
show :: T period -> String
$cshow :: forall period. Show period => T period -> String
showsPrec :: Int -> T period -> ShowS
$cshowsPrec :: forall period. Show period => Int -> T period -> ShowS
Show)

{-
instance Functor seq => Functor (T seq) where
   fmap f = Cons . fmap f . samples

instance Format.C seq => Format.C (T seq) where
   format p = Format.format p . samples

instance (Format.C seq, Show y) => Show (T seq y) where
   showsPrec = Format.format


type R s yv = RP.T s (T Sig.T) yv
-}


{-
replacePeriod :: Sig.T yv1 -> R s yv0 -> R s yv1
replacePeriod ss _  =  fromPeriod ss
-}

processPeriod ::
   (body0 -> body1) -> T body0 -> T body1
processPeriod :: forall body0 body1. (body0 -> body1) -> T body0 -> T body1
processPeriod body0 -> body1
f =
   forall body. body -> T body
fromPeriod forall b c a. (b -> c) -> (a -> b) -> a -> c
. body0 -> body1
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall period. T period -> period
toPeriod


{-# INLINE fromPeriod #-}
fromPeriod :: body -> T body
fromPeriod :: forall body. body -> T body
fromPeriod  =  forall body. body -> T body
Cons


{- |
Periodization of a straight signal.
-}
{-# INLINE fromSignal #-}
fromSignal ::
   (Additive.C yv, SigG.Write sig yv) =>
   Int -> sig yv -> T (sig yv)
fromSignal :: forall yv (sig :: * -> *).
(C yv, Write sig yv) =>
Int -> sig yv -> T (sig yv)
fromSignal Int
n  =
   forall body. body -> T body
fromPeriod forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (sig :: * -> *) yv.
(Write sig yv, C yv) =>
LazySize -> Int -> sig yv -> sig yv
Cyclic.fromSignal LazySize
SigG.defaultLazySize Int
n

{- |
Convert a cyclic signal to a straight signal containing a loop.
-}
{-# INLINE toSignal #-}
toSignal :: (Monoid sig) => T sig -> sig
toSignal :: forall sig. Monoid sig => T sig -> sig
toSignal  =
   forall sig. Monoid sig => sig -> sig
SigG.cycle forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall period. T period -> period
toPeriod