{-# OPTIONS -fno-implicit-prelude -fglasgow-exts #-} {- | Copyright : (c) Henning Thielemann 2007 License : GPL Maintainer : synthesizer@henning-thielemann.de Stability : provisional Portability : requires multi-parameter type classes (OccasionallyScalar) -} module Synthesizer.Inference.Reader.Signal ( T(..), run, addSampleRate, apply, lift, returnCons, toTimeScalar, toFrequencyScalar, toAmplitudeScalar, toGradientScalar, scalarSamples, vectorSamples, ($-), constant, ) where import Synthesizer.Inference.Reader.Process (($:)) import qualified Synthesizer.Inference.Reader.Process as Proc import qualified Synthesizer.SampleRateContext.Rate as Rate import qualified Synthesizer.SampleRateContext.Signal as SigC import qualified Synthesizer.Physical.Signal as SigP import Synthesizer.SampleRateContext.Signal (T(Cons, samples, amplitude)) 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 run :: t' -> Proc.T t t' (T y y' yv) -> SigP.T t t' y y' yv run sr proc = uncurry addSampleRate (Proc.run sr proc) {- run :: Rate.T t t' -> Proc.T t t' (T y y' yv) -> SigP.T t t' y y' yv run sr proc = uncurry addSampleRate (Proc.run (Rate.toNumber sr) proc) -} addSampleRate :: t' -> T y y' yv -> SigP.T t t' y y' yv addSampleRate = SigP.addPlainSampleRate apply :: (Proc.T t t' (T y0 y0' y0v -> T y1 y1' y1v)) -> SigP.T t t' y0 y0' y0v -> SigP.T t t' y1 y1' y1v apply proc (SigP.Cons sr sig) = let (sr', f) = Proc.run (Rate.toNumber sr) proc in addSampleRate sr' (f sig) lift :: (Rate.T t t' -> a) -> Proc.T t t' a lift f = Proc.Cons $ f . Rate.fromNumber returnCons :: y' -> [yv] -> Proc.T t t' (T y y' yv) returnCons amp sig = Proc.pure (Cons amp sig) {- sampleRateExpr :: SigP.T t (Value t') y (Value y') yv -> Expr t' sampleRateExpr x = Expr.fromValue (SigP.sampleRate x) amplitudeExpr :: SigP.T t (Value t') y (Value y') yv -> Expr y' amplitudeExpr x = Expr.fromValue (SigP.amplitude x) -} toTimeScalar :: (Ring.C t', OccScalar.C t t') => t' -> t' -> t toTimeScalar sampleRate t = toScalar (t * sampleRate) toFrequencyScalar :: (Field.C t', OccScalar.C t t') => t' -> t' -> t toFrequencyScalar sampleRate f = toScalar (f / sampleRate) toAmplitudeScalar :: (Field.C y', OccScalar.C y y') => T y y' yv -> y' -> y toAmplitudeScalar sig y = toScalar (y / amplitude sig) toGradientScalar :: (Field.C q', OccScalar.C q q') => q' -> q' -> q' -> q toGradientScalar amp sampleRate steepness = toFrequencyScalar sampleRate (steepness / amp) 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 {- | Take a scalar argument where a process expects a signal. -} ($-) :: Ring.C yv => Proc.T t t' (T y y' yv -> a) -> y' -> Proc.T t t' a ($-) f x = f $: Proc.pure (constant x) {- Should be in Control module. -} constant :: Ring.C yv => y' -> T y y' yv constant x = Cons x (repeat 1)