packages feed

synthesizer-llvm-0.9: src/Synthesizer/LLVM/Simple/Vanilla.hs

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TypeFamilies #-}
module Synthesizer.LLVM.Simple.Vanilla where

import qualified Synthesizer.LLVM.Simple.Signal as Sig
import qualified Synthesizer.LLVM.Simple.Value as Value

import qualified Synthesizer.Basic.Phase as Phase
import qualified Synthesizer.Basic.Wave  as Wave

import qualified LLVM.Extra.MaybeContinuation as Maybe
import qualified LLVM.Extra.ScalarOrVector as SoV
import qualified LLVM.Extra.Memory as Memory
import LLVM.Core (IsArithmetic, IsConst, IsFirstClass, IsSized, Value)

import qualified Algebra.RealRing as RealRing

import NumericPrelude.Base hiding (and, iterate, map, zipWith)


iterateVal ::
   (Memory.C a) =>
   (Value.T a -> Value.T a) ->
   Value.T a -> Sig.T (Value.T a)
iterateVal f initial =
   Sig.simple
      (\y ->
         Maybe.lift $
         fmap (\y1 -> (Value.constantValue y, y1))
              (Value.unlift1 f y))
      (Value.decons initial)

iterate ::
   (Value.Flatten a, Value.Registers a ~ reg, Memory.C reg) =>
   (a -> a) ->
   (a -> Sig.T a)
iterate f initial =
   Sig.simple
      (\y ->
         Maybe.lift $
         fmap (\y1 -> (Value.unfold y, y1))
              (Value.flattenFunction f y))
      (Value.flatten initial)



map ::
   (a -> b) ->
   Sig.T a -> Sig.T b
map f = Sig.map (return . f)


osciReg ::
   (RealRing.C tv, tv ~ Value.T (Value t),
    SoV.Fraction t, IsConst t, IsSized t,
    IsFirstClass y) =>
   Wave.T (Value.T (Value t)) (Value.T (Value y)) ->
   Value t -> Value t -> Sig.T (Value y)
osciReg wave phase freq =
   Sig.map
      (Value.unlift1 $ Wave.apply wave . Phase.fromRepresentative) $
   Sig.iterate (SoV.incPhase freq) phase

osciVal ::
   (RealRing.C tv, tv ~ Value.T (Value t),
    SoV.Fraction t, IsConst t, IsSized t) =>
   Wave.T (Value.T (Value t)) y ->
   Value.T (Value t) -> Value.T (Value t) -> Sig.T y
osciVal wave phase freq =
   map (Wave.apply wave . Phase.fromRepresentative) $
   iterateVal (incPhaseVal freq) phase

incPhaseVal ::
   (SoV.Fraction a, IsArithmetic a) =>
   Value.T (Value a) -> Value.T (Value a) -> Value.T (Value a)
incPhaseVal = Value.lift2 SoV.incPhase

osci ::
   (RealRing.C t,
    Value.Flatten t, Value.Registers t ~ reg, Memory.C reg,
    SoV.Fraction t, IsConst t) =>
   Wave.T t y ->
   Phase.T t -> t -> Sig.T y
osci wave phase freq =
   map (Wave.apply wave) $
   iterate (Phase.increment freq) phase