-- | The unit-generator graph structure implemented by the SuperCollider synthesis server. module Sound.Sc3.Server.Synthdef where import qualified Data.ByteString.Lazy as L {- bytestring -} import qualified Sound.Sc3.Ugen.Graph as Graph {- hsc3 -} import qualified Sound.Sc3.Ugen.Help.Graph as Help.Graph {- hsc3 -} import qualified Sound.Sc3.Ugen.Ugen as Ugen {- hsc3 -} import qualified Sound.Sc3.Server.Graphdef as Graphdef {- hsc3 -} import qualified Sound.Sc3.Server.Graphdef.Binary as Graphdef.Binary {- hsc3 -} import qualified Sound.Sc3.Server.Graphdef.Graph as Graphdef.Graph {- hsc3 -} import qualified Sound.Sc3.Server.Param as Param {- hsc3 -} -- | A named unit generator graph. data Synthdef = Synthdef { synthdefName :: String , synthdefUgen :: Ugen.Ugen } deriving (Eq, Show) -- | Alias for 'Synthdef'. synthdef :: String -> Ugen.Ugen -> Synthdef synthdef = Synthdef {- | The Sc3 /default/ instrument 'Synthdef', see 'default_ugen_graph'. > import Sound.Osc {\- hosc -\} > import Sound.Sc3 {\- hsc3 -\} > withSc3 (sendMessage (d_recv defaultSynthdef)) > audition defaultSynthdef -} defaultSynthdef :: Synthdef defaultSynthdef = synthdef "default" Help.Graph.default_ugen_graph {- | The Sc3 /default/ sample (buffer) playback instrument 'Synthdef', see 'default_sampler_ugen_graph'. > withSc3 (sendMessage (d_recv (defaultSampler False))) > audition (defaultSampler False) -} defaultSampler :: Bool -> Synthdef defaultSampler use_gate = let nm = "default-sampler-" ++ if use_gate then "gate" else "fixed" in synthdef nm (Help.Graph.default_sampler_ugen_graph use_gate) -- | 'ugen_to_graph' of 'synthdefUgen'. synthdefGraph :: Synthdef -> Graph.U_Graph synthdefGraph = Graph.ugen_to_graph . synthdefUgen {- | Parameter names at 'Synthdef'. >>> synthdefParam defaultSynthdef [("amp",0.1),("pan",0.0),("gate",1.0),("freq",440.0),("out",0.0)] -} synthdefParam :: Synthdef -> Param.Param synthdefParam = map (\n -> (Graph.u_node_k_name n, Graph.u_node_k_default n)) . Graph.ug_controls . synthdefGraph -- | 'graph_to_graphdef' at 'Synthdef'. synthdef_to_graphdef :: Synthdef -> Graphdef.Graphdef synthdef_to_graphdef (Synthdef nm u) = Graphdef.Graph.graph_to_graphdef nm (Graph.ugen_to_graph u) -- | 'graph_to_graphdef' at 'Synthdef'. ugen_to_graphdef :: Ugen.Ugen -> Graphdef.Graphdef ugen_to_graphdef = synthdef_to_graphdef . Synthdef "anonymous" -- | Encode 'Synthdef' as a binary data stream. synthdefData :: Synthdef -> L.ByteString synthdefData = Graphdef.Binary.encode_graphdef . synthdef_to_graphdef -- | Write 'Synthdef' to indicated file. synthdefWrite :: FilePath -> Synthdef -> IO () synthdefWrite fn = Graphdef.Binary.graphdefWrite fn . synthdef_to_graphdef {- | Write 'Synthdef' to indicated directory. The filename is the 'synthdefName' with the appropriate extension (@scsyndef@). -} synthdefWrite_dir :: FilePath -> Synthdef -> IO () synthdefWrite_dir dir = Graphdef.Binary.graphdefWrite_dir dir . synthdef_to_graphdef -- | 'graph_stat_ln' of 'synth'. synthstat_ln :: Ugen.Ugen -> [String] synthstat_ln = Graph.ug_stat_ln . Graph.ugen_to_graph -- | 'unlines' of 'synthstat_ln'. synthstat :: Ugen.Ugen -> String synthstat = unlines . synthstat_ln {- | 'putStrLn' of 'synthstat'. > synthstat_wr Sound.Sc3.Ugen.Help.Graph.default_ugen_graph -} synthstat_wr :: Ugen.Ugen -> IO () synthstat_wr = putStrLn . synthstat {- | Variant without Ugen sequence. > putStrLn $ synthstat_concise (default_sampler_ugen_graph True) -} synthstat_concise :: Ugen.Ugen -> String synthstat_concise = unlines . reverse . drop 1 . reverse . synthstat_ln -- | 'graphdef_dump_ugens' of 'ugen_to_graphdef' ugen_dump_ugens :: Ugen.Ugen -> IO () ugen_dump_ugens = Graphdef.graphdef_dump_ugens . ugen_to_graphdef