module Sound.SC3.UGen.Graph.Transform where
import Data.Either
import Data.List
import Data.Maybe
import Sound.SC3.UGen.Graph
import Sound.SC3.UGen.Rate
constant_to_control :: NodeId -> Node -> (NodeId,Node)
constant_to_control z n =
case n of
NodeC _ k -> (z+1,NodeK z KR Nothing ("k_" ++ show z) k K_KR Nothing)
_ -> (z,n)
from_port_node_err :: Graph -> FromPort -> Node
from_port_node_err g fp =
let e = error "from_port_node_err"
in fromMaybe e (from_port_node g fp)
c_lift_from_port :: Graph -> NodeId -> FromPort -> (NodeId,Either FromPort Node)
c_lift_from_port g z fp =
case fp of
FromPort_C _ -> let n = from_port_node_err g fp
(z',n') = constant_to_control z n
in (z',Right n')
_ -> (z,Left fp)
c_lift_inputs :: Graph -> NodeId -> [FromPort] -> (NodeId,[FromPort],[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 -> as_from_port n
r' = map f r
in (z',r',rights r)
c_lift_ugen :: Graph -> NodeId -> Node -> (NodeId,Node,[Node])
c_lift_ugen g z n =
let i = node_u_inputs n
(z',i',k) = c_lift_inputs g z i
in (z',n {node_u_inputs = i'},k)
c_lift_ugens :: Graph -> NodeId -> [Node] -> (NodeId,[Node],[Node])
c_lift_ugens g =
let rec (k,r) z u =
case u of
[] -> (z,k,reverse r)
n:u' -> let (z',n',k') = c_lift_ugen g z n
in rec (k++k',n':r) z' u'
in rec ([],[])
lift_constants :: Graph -> Graph
lift_constants g =
let (Graph z _ k u) = remove_implicit g
(z',k',u') = c_lift_ugens g z u
g' = Graph z' [] (nubBy node_k_eq (k ++ k')) u'
in add_implicit g'