csound-expression-0.0: src/CsoundExpr/Base/UserDefined.hs
{-# LANGUAGE
TypeFamilies,
MultiParamTypeClasses,
TypeSynonymInstances,
FlexibleContexts #-}
-- | Functions to add your own opcodes or operations
--
-- Constructor takes in 'String' and list of CsTree's. 'String' represnts
-- name of opcode\/operation for rendering to csd file. 'CsTree' is an inner
-- type of csound expression. Any type @a@ that belongs to 'IM' 'CsTree' @a@
-- can be converted to 'CsTree' with 'to' method.
module CsoundExpr.Base.UserDefined
(IM(..), Opr2(..),
opcode, outOpcode,
infixOperation, prefixOperation)
where
import CsoundExpr.Translator.Cs.IM
import CsoundExpr.Translator.Cs.CsTree
import CsoundExpr.Translator.ExprTree.ExprTree
import CsoundExpr.Translator.Types
-- | Opcode constructor
--
-- Example :
--
-- > ares oscil xamp, xcps, ift, [iphs]
-- > kres oscil kamp, kcps, ift, [iphs]
--
-- > oscilA :: (X a0, X a1) => [Irate] -> a0 -> a1 -> Irate -> Arate
-- > oscilA inits xamp xcps ift = opcode "oscil" args
-- > where args = [to xamp, to xcps, to ift] ++ map to inits
--
-- > oscilK :: (K a0, K a1) => [Irate] -> a0 -> a1 -> Irate -> Krate
-- > oscilK inits kamp kcps ift = opcode "oscil" args
-- > where args = [to kamp, to kcps, to ift] ++ map to inits
--
--
-- > ares noise xamp, kbeta
--
-- > noise :: (X a, K b) => a -> b -> SideEffect Ares
-- > noise xamp kbeta = opcode "noise" args
-- > where args = [to xamp, to kbeta]
--
opcode :: IM CsTree a => String -> [CsTree] -> a
opcode name = from . pure (opc name)
-- | Constructor for opcode that doesn't produce any value
--
-- Example :
--
-- > outs asig1, asig2
--
-- > outs :: Arate -> Arate -> SignalOut
-- > outs asig1 asig2 = outOpcode "outs" args
-- > where args = [to asig1, to asig2]
--
outOpcode :: String -> [CsTree] -> SignalOut
outOpcode name = SignalOut . return . opcode name
-- | Infix operation constructor
--
-- Example :
--
-- > xres = xsig1 + xsig2
--
-- > add :: (X a, X b, X (Opr2 a b)) => a -> b -> Opr2 a b
-- > add a b = infixOperation "+" [to a, to b]
--
infixOperation :: IM CsTree a => String -> [CsTree] -> a
infixOperation name = from . pure (oprInfix name)
-- | Prefix operation constructor
--
-- Example :
--
-- > xres = sin(xsig)
--
-- > csSin :: X a => a -> a
-- > csSin a = prefixOperation "sin" [to a]
--
prefixOperation :: IM CsTree a => String -> [CsTree] -> a
prefixOperation name = from . pure (oprPrefix name)
-- | 'Opr2' @a@ @b@ - defines output type of binary arithmetic operator
--
-- > type instance Opr2 Irate Irate = Irate
-- > type instance Opr2 Irate Krate = Krate
-- > type instance Opr2 Irate Arate = Arate
--
-- > type instance Opr2 Krate Irate = Krate
-- > type instance Opr2 Krate Krate = Krate
-- > type instance Opr2 Krate Arate = Arate
--
-- > type instance Opr2 Arate Irate = Arate
-- > type instance Opr2 Arate Krate = Arate
-- > type instance Opr2 Arate Arate = Arate
type family Opr2 a b
-- Is
type instance Opr2 Irate Irate = Irate
type instance Opr2 Irate Krate = Krate
type instance Opr2 Irate Arate = Arate
-- Ks
type instance Opr2 Krate Irate = Krate
type instance Opr2 Krate Krate = Krate
type instance Opr2 Krate Arate = Arate
-- As
type instance Opr2 Arate Irate = Arate
type instance Opr2 Arate Krate = Arate
type instance Opr2 Arate Arate = Arate