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)
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)
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
($-) :: 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)
constant :: Ring.C yv => y' -> T y y' yv
constant x = Cons x (repeat 1)