packages feed

synthesizer-inference-0.2: src/Synthesizer/Inference/Monad/SignalSeq.hs

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{- |

Copyright   :  (c) Henning Thielemann 2006
License     :  GPL

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



Similar to "Synthesizer.Inference.Monad.Signal"
but the functions have monadic input and sequentialize it.
This allows for a more functional looking style of programming
because the type signature of signal modifiers is essentially
   @SigI.Process a q v -> SigI.Process a q v@
and thus they are perfectly composable with (.)
and normal function application.

The processor sequentializes its inputs
and the order is quite arbitrary,
but actually the order within monad sequences
influences only the order of inference of signal parameters.
The core signal processing does not depend on the monad order.

The interfaces used here allow for function calls like
   @superProc (proc1 x) (proc2 y)@ .
However, we have to be careful with sharing of the results of signal processors.
E.g.
   @superProc x x@
does not mean, that the signal generated by @x@ is used twice.
Instead it means that @x@ is computed twice.
This can be avoided by explicitly sharing
the result signal with 'Inference.Process.share'.
This is absolutely the same situation as in "UniqueLogicNP.Explicit.Expression".

@
   do
      y <- Process.share x
      superProc y y
@

A rule of thumb:
Whenever you use the @let@ syntax,
you are probably planing to use the variable more than once.
Thus you should better use @do@ notation together with 'Inference.Process.share'.

-}
module Synthesizer.Inference.Monad.SignalSeq 
(
   T,
   Process,

   run,

   returnCons,

   sampleRateExpr,
   amplitudeExpr,

   toTimeScalar,
   toFrequencyScalar,
   toAmplitudeScalar,

   fixSampleRate,
   loop
)
where

import qualified Synthesizer.Inference.Monad.Signal  as SigI

import Synthesizer.Inference.Monad.Signal (T, Process, run, returnCons,
   sampleRateExpr, amplitudeExpr,
   toTimeScalar, toFrequencyScalar, toAmplitudeScalar)

import UniqueLogicNP.Monad(liftP)
-- import NumericPrelude
import PreludeBase as P



fixSampleRate :: (Eq q) =>
      q             {-^ sample rate -}
   -> Process a q v {-^ passed through signal -}
   -> Process a q v
fixSampleRate sampleRate =
   liftP (SigI.fixSampleRate sampleRate)

{- | Create a loop from one node to another one.
     That is, compute the fix point of a process iteration. -}
loop :: (Eq q) =>
      (Process a q v -> Process a q v)
                    {-^ process chain that shall be looped -}
   -> Process a q v
loop f = SigI.loop (f . return)