-- | Functions to make your own opcodes. -- You can find a lot of examples in source code (see directory @Csound/Opcode@) module Csound.LowLevel( -- * Types Rate(..), Name, E, -- * Handy shortcuts i, k, a, x, s, f, is, ks, as, -- * Standard opcodes -- | Example: -- -- > oscil :: Sig -> Sig -> Tab -> Sig -- > oscil = opc3 "oscil" [ -- > (a, [x, x, i, i]), -- > (k, [k, k, i, i])] Spec1, opcs, opc0, opc1, opc2, opc3, opc4, opc5, opc6, opc7, opc8, opc9, opc10, opc11, -- * Multiple outputs -- | Examples: -- -- > pan2 :: Sig -> Sig -> (Sig, Sig) -- > pan2 = mopc2 "pan2" ([a, a], [a, x, i]) -- -- When you don't want to specify precise number of outputs: -- -- > soundin :: CsdTuple a => S -> a -- > soundin = mopc1 "soundin" (repeat a, s : is 4) Specs, mopcs, mopc0, mopc1, mopc2, mopc3, mopc4, mopc5, mopc6, mopc7, -- * Side effects -- | Examples: -- -- > delayr :: D -> SE Sig -- > delayr a1 = se $ opc1 "delayr" [(a, [i])] a1 -- > -- > delayw :: Sig -> SE () -- > delayw a1 = se_ $ opc1 "delayw" [(x, [a])] a1 -- -- Functions that produce no values (procedures) should return value of the type 'Xr'. -- * When standard functions are not enough -- | Sometimes Csound opcodes take too many parameters. If you want to -- use them, you can always use functions that are defined on lists ('opcs' or 'mopcs'). -- But in this case you have to convert all arguments to the same type 'E': -- -- For example: -- -- > oscil :: Sig -> Sig -> Tab -> Sig -- > oscil a1 a2 a3 = opcs "oscil" signature [toE a1, toE a2, toE a3] -- > where signature = [ -- > (a, [x, x, i, i]), -- > (k, [k, k, i, i])] toE, se, se_ ) where import Data.Fix import Csound.Exp import Csound.Exp.Wrapper import Csound.Exp.Cons import Csound.Render.Sco(Msg) i = Ir k = Kr a = Ar x = Xr s = Sr f = Fr is n = replicate n i ks n = replicate n k as n = replicate n a