module Sound.SC3.UGen.Graph.Transform where
import Data.Either
import Data.List
import Sound.SC3.UGen.Graph
import Sound.SC3.UGen.Rate
import Sound.SC3.UGen.Type
constant_to_control :: UID_t -> U_Node -> (UID_t,U_Node)
constant_to_control z n =
case n of
U_Node_C _ k -> (z + 1,U_Node_K z KR Nothing ("k_" ++ show z) k K_KR Nothing)
_ -> (z,n)
c_lift_from_port :: U_Graph -> UID_t -> From_Port -> (UID_t,Either From_Port U_Node)
c_lift_from_port g z fp =
case fp of
From_Port_C _ ->
let n = ug_from_port_node_err g fp
(z',n') = constant_to_control z n
in (z',Right n')
_ -> (z,Left fp)
c_lift_inputs :: U_Graph -> UID_t -> [From_Port] -> (UID_t,[From_Port],[U_Node])
c_lift_inputs g z i =
let (z',r) = mapAccumL (c_lift_from_port g) z i
f e = case e of
Left fp -> fp
Right n -> u_node_from_port n
r' = map f r
in (z',r',rights r)
c_lift_ugen :: U_Graph -> UID_t -> U_Node -> (UID_t,U_Node,[U_Node])
c_lift_ugen g z n =
let i = u_node_u_inputs n
(z',i',k) = c_lift_inputs g z i
in (z',n {u_node_u_inputs = i'},k)
c_lift_ugens :: U_Graph -> UID_t -> [U_Node] -> (UID_t,[U_Node],[U_Node])
c_lift_ugens g =
let recur (k,r) z u =
case u of
[] -> (z,k,reverse r)
n:u' -> let (z',n',k') = c_lift_ugen g z n
in recur (k++k',n':r) z' u'
in recur ([],[])
lift_constants :: U_Graph -> U_Graph
lift_constants g =
let (U_Graph z _ k u) = ug_remove_implicit g
(z',k',u') = c_lift_ugens g z u
g' = U_Graph z' [] (nubBy u_node_k_eq (k ++ k')) u'
in ug_add_implicit g'