module Sound.SC3.Server.Synthdef where
import qualified Data.ByteString.Lazy as L
import Data.Default
import Data.List
import Data.Maybe
import System.FilePath
import qualified Sound.SC3.Server.Graphdef as G
import qualified Sound.SC3.Server.Graphdef.Graph as G
import Sound.SC3.UGen.Graph
import Sound.SC3.UGen.Help.Graph
import Sound.SC3.UGen.Type
import Sound.SC3.UGen.UGen
data Synthdef = Synthdef {synthdefName :: String
,synthdefUGen :: UGen}
deriving (Eq,Show)
instance Default Synthdef where def = defaultSynthdef
synthdef :: String -> UGen -> Synthdef
synthdef = Synthdef
defaultSynthdef :: Synthdef
defaultSynthdef = synthdef "default" default_ugen_graph
defaultSampler :: Bool -> Synthdef
defaultSampler use_gate =
let nm = "default-sampler-" ++ if use_gate then "gate" else "fixed"
in synthdef nm (default_sampler_ugen_graph use_gate)
synthdefGraph :: Synthdef -> Graph
synthdefGraph = ugen_to_graph . synthdefUGen
synthdefParam :: Synthdef -> [String]
synthdefParam = map node_k_name . controls . synthdefGraph
ugenIndices :: String -> Graph -> [Integer]
ugenIndices nm =
let f (k,nd) =
case nd of
NodeU _ _ nm' _ _ _ _ -> if nm == nm' then Just k else Nothing
_ -> Nothing
in mapMaybe f . zip [0..] . ugens
synthdef_to_graphdef :: Synthdef -> G.Graphdef
synthdef_to_graphdef (Synthdef nm u) = G.graph_to_graphdef nm (ugen_to_graph u)
synthdefData :: Synthdef -> L.ByteString
synthdefData = G.encode_graphdef . synthdef_to_graphdef
synthdefWrite :: Synthdef -> FilePath -> IO ()
synthdefWrite s dir =
let nm = dir </> synthdefName s <.> "scsyndef"
in L.writeFile nm (synthdefData s)
graph_stat :: Graph -> [String]
graph_stat s =
let cs = constants s
ks = controls s
us = ugens s
u_nm z = ugen_user_name (node_u_name z) (node_u_special z)
f g = let h (x:xs) = (x,length (x:xs))
h [] = error "graph_stat"
in show . map h . group . sort . map g
sq pp_f = intercalate "," (pp_f (map u_nm us))
in ["number of constants : " ++ show (length cs)
,"number of controls : " ++ show (length ks)
,"control rates : " ++ f node_k_rate ks
,"number of unit generators : " ++ show (length us)
,"unit generator rates : " ++ f node_u_rate us
,"unit generator set : " ++ sq (sort . nub)
,"unit generator sequence : " ++ sq id]
synthstat' :: UGen -> [String]
synthstat' = graph_stat . ugen_to_graph
synthstat :: UGen -> String
synthstat = unlines . synthstat'