hsc3-0.17: Sound/SC3/UGen/Protect.hs
-- | Functions to re-write assigned node identifiers at UGen graphs.
-- Used carefully it allows for composition of sub-graphs with psuedo-random nodes.
module Sound.SC3.UGen.Protect where
import Sound.SC3.Common.UId
import Sound.SC3.UGen.Type
import Sound.SC3.UGen.UGen
{-
-- | Collect Ids at UGen graph
ugenIds :: UGen -> [UGenId]
ugenIds =
let f u = case u of
Primitive_U p -> [ugenId p]
_ -> []
in ugenFoldr ((++) . f) []
-}
-- | Replace UId /i/ at /z/ with /(e,i)/.
edit_ugenid :: ID a => a -> UGenId -> UGenId
edit_ugenid e z =
case z of
NoId -> NoId
UId i -> UId (resolveID (e,i))
-- | 'edit_ugenid' of /e/ at all 'Primitive_U' of /u/.
uprotect :: ID a => a -> UGen -> UGen
uprotect e =
let f u = case u of
Primitive_U p -> Primitive_U (p {ugenId = edit_ugenid e (ugenId p)})
_ -> u
in ugenTraverse f
-- | Variant of 'uprotect' with subsequent identifiers derived by
-- incrementing initial identifier.
uprotect_seq :: ID a => a -> [UGen] -> [UGen]
uprotect_seq e =
let n = map (+ resolveID e) [1..]
in zipWith uprotect n
-- | Make /n/ instances of 'UGen' with protected identifiers.
uclone_seq :: ID a => a -> Int -> UGen -> [UGen]
uclone_seq e n = uprotect_seq e . replicate n
-- | 'mce' of 'uclone_seq'.
uclone :: ID a => a -> Int -> UGen -> UGen
uclone e n = mce . uclone_seq e n
-- | Left to right UGen function composition with 'UGenId' protection.
ucompose :: ID a => a -> [UGen -> UGen] -> UGen -> UGen
ucompose e xs =
let go [] u = u
go ((f,k):f') u = go f' (uprotect k (f u))
in go (zip xs [resolveID e ..])
-- | Make /n/ sequential instances of `f' with protected Ids.
useq :: ID a => a -> Int -> (UGen -> UGen) -> UGen -> UGen
useq e n f = ucompose e (replicate n f)