module Synthesizer.Generic.Wave where
import qualified Synthesizer.State.ToneModulation as ToneMod
import qualified Synthesizer.Basic.Wave as Wave
import qualified Synthesizer.Generic.Signal as SigG
import qualified Synthesizer.Interpolation as Interpolation
import qualified Algebra.RealField            as RealField
import qualified Algebra.RealRing             as RealRing
import NumericPrelude.Numeric
import NumericPrelude.Base
import Prelude ()
sample ::
   (RealRing.C a, SigG.Transform sig v) =>
   Interpolation.T a v -> sig v -> Wave.T a v
sample ip wave =
   let len = SigG.length wave
       cycleWave = SigG.cycle wave
   in  Wave.fromFunction $ \ phase ->
           let (n,q) = RealRing.splitFraction (phase * fromIntegral len)
           in  Interpolation.func ip q $
               SigG.toState $
               SigG.drop n cycleWave
sampledTone ::
   (RealField.C a, SigG.Transform sig v) =>
   Interpolation.T a v ->
   Interpolation.T a v ->
   a -> sig v -> a -> Wave.T a v
sampledTone ipLeap ipStep period tone shape = Wave.Cons $ \phase ->
   uncurry (ToneMod.interpolateCell ipLeap ipStep) $
   ToneMod.sampledToneCell
      (ToneMod.makePrototype
          (Interpolation.margin ipLeap) (Interpolation.margin ipStep)
          period tone)
      shape phase