vivid-0.2.0.0: Vivid/UGens/Algebraic.hs
-- | The fixities of the operators ("~+", "~*", "~<", etc) are the same as those of
-- their non-'~' equivalents (+, *, < etc)
--
-- (So you can e.g. multiply then add without parens!)
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE NoIncoherentInstances #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE NoUndecidableInstances #-}
module Vivid.UGens.Algebraic (
(~+)
, (~-)
, (~*)
, (~**)
, (~/)
, (~>)
, (~>=)
, (~<)
, (~<=)
, binaryOp
, biOp
, unaryOp
, uOp
, midiCPS
, cpsMIDI
, abs'
, neg
, tanh'
, clip2
, xor
) where
import Vivid.SynthDef
-- import Vivid.UGens.Args
import Prelude
infixl 7 ~*
-- | Multiply signals
(~*) :: (ToSig i0 a, ToSig i1 a) => i0 -> i1 -> SDBody' a Signal
(~*) = binaryOp Mul
infixr 8 ~**
-- | Exponentiation of signals
(~**) :: (ToSig i0 a, ToSig i1 a) => i0 -> i1 -> SDBody' a Signal
(~**) = binaryOp Pow
infixl 6 ~+
-- | Add signals
(~+) :: (ToSig i0 a, ToSig i1 a) => i0 -> i1 -> SDBody' a Signal
(~+) = binaryOp Add
infixl 7 ~/
-- | Divide signals
(~/) :: (ToSig i0 a, ToSig i1 a) => i0 -> i1 -> SDBody' a Signal
(~/) = binaryOp FDiv
infix 4 ~>
-- | Test signals for left greater than right
(~>) :: (ToSig i0 a, ToSig i1 a) => i0 -> i1 -> SDBody' a Signal
(~>) = binaryOp Gt
infix 4 ~>=
-- | Test signals for left greater than or equal to right
(~>=) :: (ToSig i0 a, ToSig i1 a) => i0 -> i1 -> SDBody' a Signal
(~>=) = binaryOp Ge
infix 4 ~<
-- | Test signals for left less than right
(~<) :: (ToSig i0 a, ToSig i1 a) => i0 -> i1 -> SDBody' a Signal
(~<) = binaryOp Lt
infix 4 ~<=
-- | Test signals for left less than or equal to right
(~<=) :: (ToSig i0 a, ToSig i1 a) => i0 -> i1 -> SDBody' a Signal
(~<=) = binaryOp Le
infixl 6 ~-
-- | Subtract signals
(~-) :: (ToSig i0 a, ToSig i1 a) => i0 -> i1 -> SDBody' a Signal
(~-) = binaryOp Sub
-- | Build your own!
--
-- The calculation rate of the result is the larger (more frequent) of the 2 input
-- signals
-- (So you shouldn't need to use "?" very much!)
binaryOp :: (ToSig s0 a, ToSig s1 a) => BinaryOp -> s0 -> s1 -> SDBody' a Signal
binaryOp theBiOp s0 s1 = do
s0' <- toSig s0
s1' <- toSig s1
calcRate <- max <$> getCalcRate s0' <*> getCalcRate s1'
let sigs = [s0', s1']
addUGen $ UGen (UGName_B theBiOp) calcRate sigs 1
-- | Alias of 'binaryOp'. Shorter, fer livecodin
biOp :: (ToSig s0 a, ToSig s1 a) => BinaryOp -> s0 -> s1 -> SDBody' a Signal
biOp = binaryOp
-- | Build your own, from 'UnaryOp's
unaryOp :: (ToSig sig a) => UnaryOp -> sig -> SDBody' a Signal
unaryOp theUOp sig = do
sig' <- toSig sig
calcRate <- getCalcRate sig'
addUGen $ UGen (UGName_U theUOp) calcRate [sig'] 1
-- | Alias of 'unaryOp'
uOp :: (ToSig sig a) => UnaryOp -> sig -> SDBody' a Signal
uOp = unaryOp
-- | Convert from a midi note number (0-127, each representing a musical half step) to a
-- frequency in hz (cycles per second)
midiCPS :: (ToSig i a) => i -> SDBody' a Signal
midiCPS = unaryOp MIDICPS
-- | Inverse of 'midiCPS'
cpsMIDI :: (ToSig i a) => i -> SDBody' a Signal
cpsMIDI = unaryOp CPSMIDI
-- | The prime is to not conflict with \"abs\" in the prelude. May just use
-- \"uOp Abs\" in the future
abs' :: (ToSig i a) => i -> SDBody' a Signal
abs' = unaryOp Abs
neg :: (ToSig i a) => i -> SDBody' a Signal
neg = unaryOp Neg
-- | The prime, like 'abs'', is to not conflict with a prelude definition.
--
-- Remember you can always just use:
--
-- > uOp TanH
tanh' :: ToSig i a => i -> SDBody' a Signal
tanh' i = uOp TanH i
-- | Like 'Vivid.UGens.Maths.clip' but the lo value is always negative the hi value
clip2 :: (ToSig s0 a, ToSig s1 a) => s0 -> s1 -> SDBody' a Signal
clip2 = biOp Clip2
-- | Bitwise xor. Short for @biOp BitXor@
xor :: (ToSig s0 a, ToSig s1 a) => s0 -> s1 -> SDBody' a Signal
xor = biOp BitXor