{-# LANGUAGE NoImplicitPrelude #-}
module Synthesizer.Causal.Oscillator where
import qualified Synthesizer.Causal.Oscillator.Core as Osci
import qualified Synthesizer.Causal.Process as Causal
import qualified Synthesizer.Causal.Interpolation as InterpolationC
import qualified Synthesizer.Causal.ToneModulation as ToneMod
import qualified Synthesizer.Basic.WaveSmoothed as WaveSmooth
import qualified Synthesizer.Basic.Wave as Wave
import qualified Synthesizer.Basic.Phase as Phase
import qualified Synthesizer.Interpolation as Interpolation
import qualified Synthesizer.Generic.Signal as SigG
import qualified Synthesizer.State.Signal as Sig
import qualified Algebra.Transcendental as Trans
import qualified Algebra.RealField as RealField
import qualified Algebra.RealRing as RealRing
import Control.Arrow ((^<<), (<<^), (<<<), (***), )
import NumericPrelude.Numeric
import NumericPrelude.Base
{-# INLINE phaseMod #-}
phaseMod :: (RealRing.C a) =>
Wave.T a b -> a -> Causal.T a b
phaseMod wave freq =
Wave.apply wave ^<< Osci.phaseMod freq
{-# INLINE shapeMod #-}
shapeMod :: (RealRing.C a) =>
(c -> Wave.T a b) -> Phase.T a -> a -> Causal.T c b
shapeMod wave phase freq =
uncurry (Wave.apply . wave) ^<<
Osci.shapeMod phase freq
{-# INLINE freqMod #-}
freqMod :: (RealRing.C a) =>
Wave.T a b -> Phase.T a -> Causal.T a b
freqMod wave phase =
Wave.apply wave ^<< Osci.freqMod phase
{-# INLINE freqModAntiAlias #-}
freqModAntiAlias :: (RealRing.C a) =>
WaveSmooth.T a b -> Phase.T a -> Causal.T a b
freqModAntiAlias wave phase =
uncurry (WaveSmooth.apply wave) ^<<
Osci.freqModAntiAlias phase
{-# INLINE phaseFreqMod #-}
phaseFreqMod :: (RealRing.C a) =>
Wave.T a b -> Causal.T (a,a) b
phaseFreqMod wave =
Wave.apply wave ^<< Osci.phaseFreqMod
{-# INLINE shapeFreqMod #-}
shapeFreqMod :: (RealRing.C a) =>
(c -> Wave.T a b) -> Phase.T a -> Causal.T (c,a) b
shapeFreqMod wave phase =
uncurry (Wave.apply . wave) ^<<
Osci.shapeFreqMod phase
{-# INLINE freqModSample #-}
freqModSample :: RealRing.C a =>
Interpolation.T a b -> Sig.T b -> Phase.T a -> Causal.T a b
freqModSample ip wave phase =
let len = Sig.length wave
pr = fromIntegral len * Phase.toRepresentative phase
in InterpolationC.relativeCyclicPad ip pr wave
<<< Causal.map (fromIntegral len *)
{-# INLINE shapeFreqModSample #-}
shapeFreqModSample :: (RealRing.C c, RealRing.C b) =>
Interpolation.T c (Wave.T b a) -> Sig.T (Wave.T b a) ->
c -> Phase.T b ->
Causal.T (c, b) a
shapeFreqModSample ip waves shape0 phase =
uncurry Wave.apply ^<<
(InterpolationC.relativeConstantPad ip shape0 waves ***
Osci.freqMod phase)
{-# INLINE shapeFreqModFromSampledTone #-}
shapeFreqModFromSampledTone ::
(RealField.C t, SigG.Transform sig y) =>
Interpolation.T t y ->
Interpolation.T t y ->
t -> sig y ->
t -> Phase.T t ->
Causal.T (t,t) y
shapeFreqModFromSampledTone
ipLeap ipStep period sampledTone shape0 phase =
uncurry (ToneMod.interpolateCell ipLeap ipStep) ^<<
ToneMod.oscillatorCells
(Interpolation.margin ipLeap) (Interpolation.margin ipStep)
(round period) period sampledTone
(shape0, phase)
{-# INLINE shapePhaseFreqModFromSampledTone #-}
shapePhaseFreqModFromSampledTone ::
(RealField.C t, SigG.Transform sig y) =>
Interpolation.T t y ->
Interpolation.T t y ->
t -> sig y ->
t -> Phase.T t ->
Causal.T (t,t,t) y
shapePhaseFreqModFromSampledTone
ipLeap ipStep period sampledTone shape0 phase =
let periodInt = round period
marginLeap = Interpolation.margin ipLeap
marginStep = Interpolation.margin ipStep
in (\(dp, ((s,p), suffix)) ->
uncurry (ToneMod.interpolateCell ipLeap ipStep) $
ToneMod.seekCell periodInt period $
((s, Phase.increment dp p), suffix))
^<<
Causal.second
(ToneMod.oscillatorSuffixes
marginLeap marginStep
periodInt period sampledTone
(shape0, phase))
<<^
(\(s,p,f) -> (p,(s,f)))
{-# INLINE freqModSine #-}
freqModSine :: (Trans.C a, RealRing.C a) => Phase.T a -> Causal.T a a
freqModSine = freqMod Wave.sine
{-# INLINE phaseModSine #-}
phaseModSine :: (Trans.C a, RealRing.C a) => a -> Causal.T a a
phaseModSine = phaseMod Wave.sine
{-# INLINE freqModSaw #-}
freqModSaw :: RealRing.C a => Phase.T a -> Causal.T a a
freqModSaw = freqMod Wave.saw