module Synthesizer.Dimensional.Causal.ControlledProcess (
C(process),
RateDep(RateDep, unRateDep),
runSynchronous1,
runSynchronous2,
runAsynchronous1,
runAsynchronousBuffered1,
processAsynchronous1,
runAsynchronous2,
processAsynchronous2,
processAsynchronousBuffered2,
) where
import qualified Synthesizer.Dimensional.Sample as Sample
import qualified Synthesizer.Dimensional.Process as Proc
import qualified Synthesizer.Dimensional.Rate as Rate
import qualified Synthesizer.Dimensional.Signal.Private as SigA
import qualified Synthesizer.Dimensional.Causal.Process as CausalD
import qualified Synthesizer.Dimensional.Arrow as ArrowD
import qualified Synthesizer.Dimensional.Map as MapD
import qualified Synthesizer.Dimensional.Amplitude as Amp
import qualified Synthesizer.Causal.Process as Causal
import qualified Synthesizer.Causal.Interpolation as Interpolation
import qualified Synthesizer.Interpolation.Class as Interpol
import qualified Synthesizer.State.Signal as Sig
import qualified Number.DimensionTerm as DN
import qualified Algebra.DimensionTerm as Dim
import qualified Algebra.RealField as RealField
import Control.Applicative (liftA2, )
import Foreign.Storable.Newtype as Store
import Foreign.Storable (Storable(..))
import NumericPrelude.Numeric
class
Amp.C global =>
C global parameter a b |
global parameter a -> b,
global parameter b -> a where
process ::
(Dim.C u) =>
Proc.T s u t
(CausalD.T s
(Sample.T global (RateDep s parameter), a) b)
newtype RateDep s ic = RateDep {unRateDep :: ic}
instance Interpol.C a ic => Interpol.C a (RateDep s ic) where
scaleAndAccumulate =
Interpol.makeMac RateDep unRateDep
instance Storable ic => Storable (RateDep s ic) where
sizeOf = Store.sizeOf unRateDep
alignment = Store.alignment unRateDep
peek = Store.peek RateDep
poke = Store.poke unRateDep
type Signal s ecAmp ec =
SigA.T (Rate.Phantom s) ecAmp (Sig.T ec)
runSynchronous1 ::
(C global parameter sampleIn sampleOut, Dim.C u,
Amp.C ecAmp) =>
Proc.T s u t
(MapD.T
(Sample.T ecAmp ec)
(Sample.T global (RateDep s parameter))) ->
Proc.T s u t
(Signal s ecAmp ec ->
CausalD.T s sampleIn sampleOut)
runSynchronous1 =
liftA2
(\proc causal ->
CausalD.applyFst proc .
ArrowD.apply causal)
process
runSynchronous2 ::
(C global parameter sampleIn sampleOut, Dim.C u,
Amp.C ecAmp0, Amp.C ecAmp1) =>
Proc.T s u t
(MapD.T
(Sample.T ecAmp0 ec0, Sample.T ecAmp1 ec1)
(Sample.T global (RateDep s parameter))) ->
Proc.T s u t
(Signal s ecAmp0 ec0 ->
Signal s ecAmp1 ec1 ->
CausalD.T s sampleIn sampleOut)
runSynchronous2 causalp =
liftA2
(\proc causal x y ->
CausalD.applyFst proc $
ArrowD.apply causal $
SigA.zip x y)
process causalp
resample ::
(Amp.C amp, Dim.C u, RealField.C t) =>
Interpolation.T t y ->
SigA.T (Rate.Dimensional u t) amp (Sig.T y) ->
Proc.T s u t
(SigA.T (Rate.Phantom s) amp (Sig.T y))
resample ip sig =
fmap
(\k ->
SigA.Cons
Rate.Phantom
(SigA.amplitude sig)
(Causal.applyConst
(Interpolation.relativeConstantPad ip zero (SigA.body sig)) k))
(Proc.toFrequencyScalar (SigA.actualSampleRate sig))
zipRate ::
(Amp.C amp0, Amp.C amp1, Eq t) =>
SigA.T (Rate.Dimensional u t) amp0 (Sig.T y0) ->
SigA.T (Rate.Dimensional u t) amp1 (Sig.T y1) ->
SigA.T (Rate.Dimensional u t) (amp0,amp1) (Sig.T (y0,y1))
zipRate x y =
SigA.Cons
(Rate.Actual $
Rate.common "ControlledProcess.zipRate"
(SigA.actualSampleRate x) (SigA.actualSampleRate y))
(SigA.amplitude x, SigA.amplitude y)
(Sig.zip (SigA.body x) (SigA.body y))
runAsynchronous ::
(C global ic sampleIn sampleOut,
Dim.C u, RealField.C t) =>
Interpolation.T t (RateDep s ic) ->
SigA.T (Rate.Dimensional u t) global (Sig.T (RateDep s ic)) ->
Proc.T s u t (CausalD.T s sampleIn sampleOut)
runAsynchronous ip sig =
liftA2 CausalD.applyFst process (resample ip sig)
runAsynchronousBuffered ::
(C global ic sampleIn sampleOut,
Dim.C u, RealField.C t) =>
Interpolation.T t (RateDep s ic) ->
SigA.T (Rate.Dimensional u t) global (Sig.T (RateDep s ic)) ->
Proc.T s u t (CausalD.T s sampleIn sampleOut)
runAsynchronousBuffered ip =
runAsynchronous ip .
SigA.processBody (Sig.fromList . Sig.toList)
runAsynchronous1 ::
(C global ic sampleIn sampleOut,
Dim.C u, RealField.C t) =>
Interpolation.T t (RateDep s ic) ->
Proc.T s u t
(MapD.T
(Sample.T ecAmp ec)
(Sample.T global (RateDep s ic))) ->
SigA.T (Rate.Dimensional u t) ecAmp (Sig.T ec) ->
Proc.T s u t (CausalD.T s sampleIn sampleOut)
runAsynchronous1 ip cp sig =
cp >>= \p -> runAsynchronous ip (ArrowD.apply p sig)
runAsynchronousBuffered1 ::
(C global ic sampleIn sampleOut,
Dim.C u, RealField.C t) =>
Interpolation.T t (RateDep s ic) ->
Proc.T s u t
(MapD.T
(Sample.T ecAmp ec)
(Sample.T global (RateDep s ic))) ->
SigA.T (Rate.Dimensional u t) ecAmp (Sig.T ec) ->
Proc.T s u t (CausalD.T s sampleIn sampleOut)
runAsynchronousBuffered1 ip cp sig =
cp >>= \p -> runAsynchronousBuffered ip (ArrowD.apply p sig)
processAsynchronous1 ::
(
C global ic sampleIn sampleOut,
Amp.C ecAmp, Dim.C u, RealField.C t) =>
Interpolation.T t (RateDep s ic) ->
Proc.T s u t
(MapD.T
(Sample.T ecAmp ec)
(Sample.T global (RateDep s ic))) ->
DN.T (Dim.Recip u) t ->
(forall r. Proc.T r u t (Signal r ecAmp ec)) ->
Proc.T s u t (CausalD.T s sampleIn sampleOut)
processAsynchronous1 ip cp rate sig =
cp >>= \p -> runAsynchronous ip (SigA.render rate (fmap (ArrowD.apply p) sig))
runAsynchronous2 ::
(C global ic sampleIn sampleOut,
Amp.C ecAmp0, Amp.C ecAmp1, Dim.C u, RealField.C t) =>
Interpolation.T t (RateDep s ic) ->
Proc.T s u t
(MapD.T
(Sample.T ecAmp0 ec0, Sample.T ecAmp1 ec1)
(Sample.T global (RateDep s ic))) ->
SigA.T (Rate.Dimensional u t) (ecAmp0) (Sig.T ec0) ->
SigA.T (Rate.Dimensional u t) (ecAmp1) (Sig.T ec1) ->
Proc.T s u t (CausalD.T s sampleIn sampleOut)
runAsynchronous2 ip cp x y =
cp >>= \p ->
runAsynchronous ip $ ArrowD.apply p $ zipRate x y
processAsynchronous2 ::
(C global ic sampleIn sampleOut,
Amp.C ecAmp0, Amp.C ecAmp1, Dim.C u, RealField.C t) =>
Interpolation.T t (RateDep s ic) ->
Proc.T s u t
(MapD.T
(Sample.T ecAmp0 ec0, Sample.T ecAmp1 ec1)
(Sample.T global (RateDep s ic))) ->
DN.T (Dim.Recip u) t ->
(forall r. Proc.T r u t (Signal r ecAmp0 ec0)) ->
(forall r. Proc.T r u t (Signal r ecAmp1 ec1)) ->
Proc.T s u t (CausalD.T s sampleIn sampleOut)
processAsynchronous2 ip cp rate x y =
cp >>= \p ->
runAsynchronous ip
(SigA.render rate (fmap (ArrowD.apply p) $ liftA2 SigA.zip x y))
_processAsynchronousNaive2 ::
(C global ic sampleIn sampleOut,
Amp.C ecAmp0, Amp.C ecAmp1, Dim.C u, RealField.C t) =>
Interpolation.T t (RateDep s ic) ->
Proc.T s u t
(MapD.T
(Sample.T ecAmp0 ec0, Sample.T ecAmp1 ec1)
(Sample.T global (RateDep s ic))) ->
DN.T (Dim.Recip u) t ->
(forall r. Proc.T r u t (Signal r ecAmp0 ec0)) ->
(forall r. Proc.T r u t (Signal r ecAmp1 ec1)) ->
Proc.T s u t (CausalD.T s sampleIn sampleOut)
_processAsynchronousNaive2 ip cp rate x y =
runAsynchronous2 ip cp
(SigA.render rate x) (SigA.render rate y)
processAsynchronousBuffered2 ::
(
C global ic sampleIn sampleOut,
Amp.C ecAmp0, Amp.C ecAmp1, Dim.C u, RealField.C t) =>
Interpolation.T t (RateDep s ic) ->
Proc.T s u t
(MapD.T
(Sample.T ecAmp0 ec0, Sample.T ecAmp1 ec1)
(Sample.T global (RateDep s ic))) ->
DN.T (Dim.Recip u) t ->
(forall r. Proc.T r u t (Signal r ecAmp0 ec0)) ->
(forall r. Proc.T r u t (Signal r ecAmp1 ec1)) ->
Proc.T s u t (CausalD.T s sampleIn sampleOut)
processAsynchronousBuffered2 ip cp rate x y =
cp >>= \p ->
runAsynchronousBuffered ip
(SigA.render rate (fmap (ArrowD.apply p) $ liftA2 SigA.zip x y))