module Sound.SC3.UGen.UGen where
import qualified Data.Char as C
import Data.List
import Sound.SC3.UGen.Identifier
import Sound.SC3.UGen.Operator
import Sound.SC3.UGen.Rate
import Sound.SC3.UGen.Type
ugen_user_name :: String -> Special -> String
ugen_user_name nm (Special n) =
case nm of
"UnaryOpUGen" -> unaryName n
"BinaryOpUGen" -> binaryName n
_ -> nm
ugenTraverse :: (UGen -> UGen) -> UGen -> UGen
ugenTraverse f u =
let rec = ugenTraverse f
in case u of
Primitive_U p ->
let i = ugenInputs p
in f (Primitive_U (p {ugenInputs = map rec i}))
Proxy_U p ->
let s = Primitive_U (proxySource p)
in case rec s of
Primitive_U p' -> f (Proxy_U (p {proxySource = p'}))
_ -> error "ugenTraverse"
MCE_U m -> f (mce (map rec (mceProxies m)))
MRG_U (MRG l r) -> f (MRG_U (MRG (rec l) (rec r)))
_ -> f u
ugenFoldr :: (UGen -> a -> a) -> a -> UGen -> a
ugenFoldr f st u =
let rec = flip (ugenFoldr f)
in case u of
Primitive_U p ->
let i = ugenInputs p
in f u (foldr rec st i)
Proxy_U p ->
let s = proxySource p
in f u (f (Primitive_U s) st)
MCE_U m -> f u (foldr rec st (mceProxies m))
MRG_U (MRG l r) -> f u (f l (f r st))
_ -> f u st
control :: Rate -> String -> Double -> UGen
control r n d = Control_U (Control r n d False)
tr_control :: String -> Double -> UGen
tr_control n d = Control_U (Control KR n d True)
mrg2 :: UGen -> UGen -> UGen
mrg2 u = MRG_U . MRG u
mce2 :: UGen -> UGen -> UGen
mce2 x y = mce [x,y]
mce2c :: UGen -> (UGen,UGen)
mce2c u =
case u of
MCE_U m -> case mceProxies m of
[] -> error "mce2c: nil mce"
p:[] -> (p,p)
p:q:_ -> (p,q)
_ -> (u,u)
mce3 :: UGen -> UGen -> UGen -> UGen
mce3 x y z = mce [x,y,z]
mceMap :: (UGen -> UGen) -> UGen -> UGen
mceMap f u = mce (map f (mceChannels u))
mceEdit :: ([UGen] -> [UGen]) -> UGen -> UGen
mceEdit f u =
case u of
MCE_U m -> mce (f (mceProxies m))
_ -> error "mceEdit: non MCE value"
mceReverse :: UGen -> UGen
mceReverse = mceEdit reverse
mceChannel :: Int -> UGen -> UGen
mceChannel n u =
case u of
MCE_U m -> mceProxies m !! n
_ -> error "mceChannel: non MCE value"
mceTranspose :: UGen -> UGen
mceTranspose = mce . map mce . transpose . map mceChannels . mceChannels
mceSum :: UGen -> UGen
mceSum = sum . mceChannels
label :: String -> UGen
label = Label_U . Label
equal_length_p :: [[a]] -> Bool
equal_length_p = (== 1) . length . nub . map length
unpackLabel :: UGen -> [UGen]
unpackLabel u =
case u of
Label_U (Label s) ->
let q = fromEnum '?'
f c = if C.isAscii c then fromEnum c else q
s' = map (fromIntegral . f) s
n = fromIntegral (length s)
in n : s'
MCE_U m ->
let x = map unpackLabel (mceProxies m)
in if equal_length_p x
then map mce (transpose x)
else error (show ("unpackLabel: mce length /=",x))
_ -> error (show ("unpackLabel: non-label",u))
mk_osc :: [Rate] -> UGenId -> Rate -> String -> [UGen] -> Int -> UGen
mk_osc rs z r c i o =
if r `elem` rs
then mkUGen Nothing rs (Just r) c i o (Special 0) z
else error ("mk_osc: rate restricted: " ++ show (r, rs, c))
no_id :: UGenId
no_id = NoId
mkOsc :: Rate -> String -> [UGen] -> Int -> UGen
mkOsc = mk_osc all_rates no_id
mkOscR :: [Rate] -> Rate -> String -> [UGen] -> Int -> UGen
mkOscR rs = mk_osc rs no_id
toUId :: (ID a) => a -> UGenId
toUId = UId . resolveID
mkOscIdR :: (ID a) => [Rate] -> a -> Rate -> String -> [UGen] -> Int -> UGen
mkOscIdR rr z = mk_osc rr (toUId z)
mkOscId :: (ID a) => a -> Rate -> String -> [UGen] -> Int -> UGen
mkOscId z = mk_osc all_rates (toUId z)
mk_osc_mce :: UGenId -> Rate -> String -> [UGen] -> UGen -> Int -> UGen
mk_osc_mce z r c i j =
let i' = i ++ mceChannels j
in mk_osc all_rates z r c i'
mkOscMCE :: Rate -> String -> [UGen] -> UGen -> Int -> UGen
mkOscMCE = mk_osc_mce no_id
mkOscMCEId :: ID a => a -> Rate -> String -> [UGen] -> UGen -> Int -> UGen
mkOscMCEId z = mk_osc_mce (toUId z)
mk_filter :: [Rate] -> UGenId -> String -> [UGen] -> Int -> UGen
mk_filter rs z c i o = mkUGen Nothing rs Nothing c i o (Special 0) z
mkFilter :: String -> [UGen] -> Int -> UGen
mkFilter = mk_filter all_rates no_id
mkFilterR :: [Rate] -> String -> [UGen] -> Int -> UGen
mkFilterR rs = mk_filter rs no_id
mkFilterId :: (ID a) => a -> String -> [UGen] -> Int -> UGen
mkFilterId z = mk_filter all_rates (toUId z)
mkFilterKeyed :: String -> Int -> [UGen] -> Int -> UGen
mkFilterKeyed c k i o =
let r = rateOf (i !! k)
in mkUGen Nothing all_rates (Just r) c i o (Special 0) no_id
mk_filter_mce :: [Rate] -> UGenId -> String -> [UGen] -> UGen -> Int -> UGen
mk_filter_mce rs z c i j = mk_filter rs z c (i ++ mceChannels j)
mkFilterMCER :: [Rate] -> String -> [UGen] -> UGen -> Int -> UGen
mkFilterMCER rs = mk_filter_mce rs no_id
mkFilterMCE :: String -> [UGen] -> UGen -> Int -> UGen
mkFilterMCE = mk_filter_mce all_rates no_id
mkFilterMCEId :: ID a => a -> String -> [UGen] -> UGen -> Int -> UGen
mkFilterMCEId z = mk_filter_mce all_rates (toUId z)
mkInfo :: String -> UGen
mkInfo name = mkOsc IR name [] 1
bitAnd :: UGen -> UGen -> UGen
bitAnd = mkBinaryOperator BitAnd undefined
bitOr :: UGen -> UGen -> UGen
bitOr = mkBinaryOperator BitOr undefined
bitXOr :: UGen -> UGen -> UGen
bitXOr = mkBinaryOperator BitXor undefined
bitNot :: UGen -> UGen
bitNot = mkUnaryOperator BitNot undefined
shiftLeft :: UGen -> UGen -> UGen
shiftLeft = mkBinaryOperator ShiftLeft undefined
shiftRight :: UGen -> UGen -> UGen
shiftRight = mkBinaryOperator ShiftRight undefined
unsignedShift :: UGen -> UGen -> UGen
unsignedShift = mkBinaryOperator UnsignedShift undefined
(.<<.) :: UGen -> UGen -> UGen
(.<<.) = shiftLeft
(.>>.) :: UGen -> UGen -> UGen
(.>>.) = shiftRight