{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{- |
This module provides a type class that automatically selects a filter
for a given parameter type.
We choose the dependency this way
because there may be different ways to specify the filter parameters
but there is only one implementation of the filter itself.
-}
module Synthesizer.LLVM.CausalParameterized.Controlled (
   Ctrl.process,
   processCtrlRate,
   ) where

import qualified Synthesizer.LLVM.CausalParameterized.Process as CausalP
import qualified Synthesizer.LLVM.Causal.Controlled as Ctrl
import qualified Synthesizer.LLVM.Parameterized.Signal as SigP

import qualified LLVM.DSL.Parameter as Param

import qualified LLVM.Extra.Tuple as Tuple
import qualified LLVM.Extra.Marshal as Marshal
import qualified LLVM.Extra.Memory as Memory
import qualified LLVM.Extra.ScalarOrVector as SoV

import qualified LLVM.Core as LLVM
import LLVM.Core (Value, IsFloating)


processCtrlRate ::
   (Ctrl.C parameter a b,
    Memory.C parameter,
    Marshal.C r, Tuple.ValueOf r ~ Value r,
    IsFloating r, SoV.IntegerConstant r,
    LLVM.CmpRet r, LLVM.IsPrimitive r) =>
   Param.T p r ->
   (Param.T p r -> SigP.T p parameter) ->
   CausalP.T p a b
processCtrlRate reduct ctrlGen =
   CausalP.applyFst Ctrl.process
      (SigP.interpolateConstant reduct (ctrlGen reduct))