{- | Binary 'Graph Definition' as understood by @scsynth@.
     There are both binary and text encoders and decoders.
-}
module Sound.Sc3.Server.Graphdef where

import Control.Monad {- base -}
import Data.List {- base -}
import Data.Maybe {- base -}
import Text.Printf {- base -}

import qualified Safe {- safe -}

import qualified Sound.Osc.Datum as Datum {- hosc -}

import qualified Sound.Sc3.Common.Math.Operator as Operator {- hsc3 -}
import qualified Sound.Sc3.Common.Rate as Rate {- hsc3 -}

-- * Type

-- | Names are Ascii strings (ie. ByteString.Char8)
type Name = Datum.Ascii

-- | Controls are a name and a ugen-index.
type Control = (Name,Int)

-- | Constants are floating point.
type Sample = Double

-- | Ugen indices are Int.
type Ugen_Index = Int

-- | Port indices are Int.
type Port_Index = Int

-- | Index used to indicate constants at Ugen inputs.
--   Ie. if the ugen-index is this value (-1) it indicates a constant.
constant_index :: Ugen_Index
constant_index :: Int
constant_index = -Int
1

-- | Inputs are a ugen-index and a port-index.
data Input = Input Ugen_Index Port_Index deriving (Input -> Input -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Input -> Input -> Bool
$c/= :: Input -> Input -> Bool
== :: Input -> Input -> Bool
$c== :: Input -> Input -> Bool
Eq,Int -> Input -> [Char] -> [Char]
[Input] -> [Char] -> [Char]
Input -> [Char]
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
showList :: [Input] -> [Char] -> [Char]
$cshowList :: [Input] -> [Char] -> [Char]
show :: Input -> [Char]
$cshow :: Input -> [Char]
showsPrec :: Int -> Input -> [Char] -> [Char]
$cshowsPrec :: Int -> Input -> [Char] -> [Char]
Show)

-- | Rates are encoded as integers (IR = 0, KR = 1, AR = 2, DR = 3).
type Rate = Int

-- | Outputs each indicate a Rate.
type Output = Rate

-- | Secondary (special) index, used by operator Ugens to select operation.
type Special = Int

-- | Unit generator type.
type Ugen = (Name,Rate,[Input],[Output],Special)

-- | 'Ugen' name.
ugen_name_str :: Ugen -> String
ugen_name_str :: Ugen -> [Char]
ugen_name_str (Name
nm,Int
_,[Input]
_,[Int]
_,Int
_) = Name -> [Char]
Datum.ascii_to_string Name
nm

-- | 'Ugen' name, using operator name if appropriate.
ugen_name_op :: Ugen -> String
ugen_name_op :: Ugen -> [Char]
ugen_name_op (Name
nm,Int
_,[Input]
_,[Int]
_,Int
k) =
  let s :: [Char]
s = Name -> [Char]
Datum.ascii_to_string Name
nm
  in forall a. a -> Maybe a -> a
fromMaybe [Char]
s ([Char] -> Int -> Maybe [Char]
Operator.ugen_operator_name [Char]
s Int
k)

-- | 'Ugen' 'Rate'.
ugen_rate :: Ugen -> Rate
ugen_rate :: Ugen -> Int
ugen_rate (Name
_,Int
r,[Input]
_,[Int]
_,Int
_) = Int
r

ugen_rate_enum :: Ugen -> Rate.Rate
ugen_rate_enum :: Ugen -> Rate
ugen_rate_enum = forall a. Enum a => Int -> a
toEnum forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ugen -> Int
ugen_rate

-- | 'Ugen' 'Input's.
ugen_inputs :: Ugen -> [Input]
ugen_inputs :: Ugen -> [Input]
ugen_inputs (Name
_,Int
_,[Input]
i,[Int]
_,Int
_) = [Input]
i

-- | 'Ugen' 'Output's.
ugen_outputs :: Ugen -> [Output]
ugen_outputs :: Ugen -> [Int]
ugen_outputs (Name
_,Int
_,[Input]
_,[Int]
o,Int
_) = [Int]
o

-- | Predicate to examine Ugen name and decide if it is a control.
ugen_is_control :: Ugen -> Bool
ugen_is_control :: Ugen -> Bool
ugen_is_control =
  (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Char]
"Control",[Char]
"LagControl",[Char]
"TrigControl"]) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Ugen -> [Char]
ugen_name_str

-- | Input is a Ugen (ie. not a constant, indicated by a ugen-index of -1) and the Ugen is a control.
input_is_control :: Graphdef -> Input -> Bool
input_is_control :: Graphdef -> Input -> Bool
input_is_control Graphdef
g (Input Int
u Int
_) = (Int
u forall a. Eq a => a -> a -> Bool
/= Int
constant_index) Bool -> Bool -> Bool
&& Ugen -> Bool
ugen_is_control (Graphdef -> Int -> Ugen
graphdef_ugen Graphdef
g Int
u)

-- | Graph definition type.
data Graphdef = Graphdef {Graphdef -> Name
graphdef_name :: Name
                         ,Graphdef -> [Sample]
graphdef_constants :: [Sample]
                         ,Graphdef -> [(Control, Sample)]
graphdef_controls :: [(Control,Sample)]
                         ,Graphdef -> [Ugen]
graphdef_ugens :: [Ugen]}
                deriving (Graphdef -> Graphdef -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Graphdef -> Graphdef -> Bool
$c/= :: Graphdef -> Graphdef -> Bool
== :: Graphdef -> Graphdef -> Bool
$c== :: Graphdef -> Graphdef -> Bool
Eq,Int -> Graphdef -> [Char] -> [Char]
[Graphdef] -> [Char] -> [Char]
Graphdef -> [Char]
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
showList :: [Graphdef] -> [Char] -> [Char]
$cshowList :: [Graphdef] -> [Char] -> [Char]
show :: Graphdef -> [Char]
$cshow :: Graphdef -> [Char]
showsPrec :: Int -> Graphdef -> [Char] -> [Char]
$cshowsPrec :: Int -> Graphdef -> [Char] -> [Char]
Show)

-- | Lookup Ugen by index.
graphdef_ugen :: Graphdef -> Ugen_Index -> Ugen
graphdef_ugen :: Graphdef -> Int -> Ugen
graphdef_ugen Graphdef
g = forall a. Partial => [Char] -> [a] -> Int -> a
Safe.atNote [Char]
"graphdef_ugen" (Graphdef -> [Ugen]
graphdef_ugens Graphdef
g)

-- | Lookup Control and default value by index.
graphdef_control :: Graphdef -> Int -> (Control,Sample)
graphdef_control :: Graphdef -> Int -> (Control, Sample)
graphdef_control Graphdef
g = forall a. Partial => [Char] -> [a] -> Int -> a
Safe.atNote [Char]
"graphdef_controls" (Graphdef -> [(Control, Sample)]
graphdef_controls Graphdef
g)

-- | nid of constant.
graphdef_constant_nid :: Graphdef -> Int -> Int
graphdef_constant_nid :: Graphdef -> Int -> Int
graphdef_constant_nid Graphdef
_ = forall a. a -> a
id

-- | nid of control.
graphdef_control_nid :: Graphdef -> Int -> Int
graphdef_control_nid :: Graphdef -> Int -> Int
graphdef_control_nid Graphdef
g = forall a. Num a => a -> a -> a
(+) (forall (t :: * -> *) a. Foldable t => t a -> Int
length (Graphdef -> [Sample]
graphdef_constants Graphdef
g))

-- | nid of Ugen.
graphdef_ugen_nid :: Graphdef -> Int -> Int
graphdef_ugen_nid :: Graphdef -> Int -> Int
graphdef_ugen_nid Graphdef
g Int
n = Graphdef -> Int -> Int
graphdef_control_nid Graphdef
g Int
0 forall a. Num a => a -> a -> a
+ forall (t :: * -> *) a. Foldable t => t a -> Int
length (Graphdef -> [(Control, Sample)]
graphdef_controls Graphdef
g) forall a. Num a => a -> a -> a
+ Int
n

{- | "SCgf" encoded as 32-bit unsigned integer.

> map fromEnum "SCgf" == [83, 67, 103, 102]
> Byte.decode_i32 (Byte.encode_ascii (Datum.ascii "SCgf"))
-}
scgf_i32 :: Num n => n
scgf_i32 :: forall n. Num n => n
scgf_i32 = n
1396926310

-- * Get

-- | Get functions for Graphdef types, (str_f,i8_f,i16_f,i32_f,f32_f)
type Get_Functions m = (m Name,m Int,m Int,m Int,m Double)

-- | Get a 'Control'.
get_control :: Monad m => (Get_Functions m,m Int) -> m Control
get_control :: forall (m :: * -> *).
Monad m =>
(Get_Functions m, m Int) -> m Control
get_control ((m Name
get_str,m Int
_,m Int
_,m Int
_,m Sample
_),m Int
get_i) = do
  Name
nm <- m Name
get_str
  Int
ix <- m Int
get_i
  forall (m :: * -> *) a. Monad m => a -> m a
return (Name
nm,Int
ix)

-- | Get an 'Input'.
get_input :: Monad m => m Int -> m Input
get_input :: forall (m :: * -> *). Monad m => m Int -> m Input
get_input m Int
get_i = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 Int -> Int -> Input
Input m Int
get_i m Int
get_i

-- | Get a 'Ugen'
get_ugen :: Monad m => (Get_Functions m,m Int) -> m Ugen
get_ugen :: forall (m :: * -> *). Monad m => (Get_Functions m, m Int) -> m Ugen
get_ugen ((m Name
get_str,m Int
get_i8,m Int
get_i16,m Int
_,m Sample
_),m Int
get_i) = do
  Name
name <- m Name
get_str
  Int
rate <- m Int
get_i8
  Int
number_of_inputs <- m Int
get_i
  Int
number_of_outputs <- m Int
get_i
  Int
special <- m Int
get_i16
  [Input]
inputs <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
number_of_inputs (forall (m :: * -> *). Monad m => m Int -> m Input
get_input m Int
get_i)
  [Int]
outputs <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
number_of_outputs m Int
get_i8
  forall (m :: * -> *) a. Monad m => a -> m a
return (Name
name
         ,Int
rate
         ,[Input]
inputs
         ,[Int]
outputs
         ,Int
special)

-- | Get a 'Graphdef'. Supports version 0|1 and version 2 files.  Ignores variants.
get_graphdef :: Monad m => Get_Functions m -> m Graphdef
get_graphdef :: forall (m :: * -> *). Monad m => Get_Functions m -> m Graphdef
get_graphdef c :: Get_Functions m
c@(m Name
get_str,m Int
_,m Int
get_i16,m Int
get_i32,m Sample
get_f32) = do
  Int
magic <- m Int
get_i32
  Int
version <- m Int
get_i32
  let get_i :: m Int
get_i =
          case Int
version of
            Int
0 -> m Int
get_i16
            Int
1 -> m Int
get_i16 -- version one allows variants, which are not allowed by hsc3
            Int
2 -> m Int
get_i32
            Int
_ -> forall a. Partial => [Char] -> a
error ([Char]
"get_graphdef: version not at {zero | one | two}: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
version)
  Int
number_of_definitions <- m Int
get_i16
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
magic forall a. Eq a => a -> a -> Bool
/= forall n. Num n => n
scgf_i32)
       (forall a. Partial => [Char] -> a
error [Char]
"get_graphdef: illegal magic string")
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
number_of_definitions forall a. Eq a => a -> a -> Bool
/= Int
1)
       (forall a. Partial => [Char] -> a
error [Char]
"get_graphdef: non unary graphdef file")
  Name
name <- m Name
get_str
  Int
number_of_constants <- m Int
get_i
  [Sample]
constants <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
number_of_constants m Sample
get_f32
  Int
number_of_control_defaults <- m Int
get_i
  [Sample]
control_defaults <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
number_of_control_defaults m Sample
get_f32
  Int
number_of_controls <- m Int
get_i
  [Control]
controls <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
number_of_controls (forall (m :: * -> *).
Monad m =>
(Get_Functions m, m Int) -> m Control
get_control (Get_Functions m
c,m Int
get_i))
  Int
number_of_ugens <- m Int
get_i
  [Ugen]
ugens <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
number_of_ugens (forall (m :: * -> *). Monad m => (Get_Functions m, m Int) -> m Ugen
get_ugen (Get_Functions m
c,m Int
get_i))
  forall (m :: * -> *) a. Monad m => a -> m a
return (Name -> [Sample] -> [(Control, Sample)] -> [Ugen] -> Graphdef
Graphdef Name
name
                   [Sample]
constants
                   (forall a b. [a] -> [b] -> [(a, b)]
zip [Control]
controls [Sample]
control_defaults)
                   [Ugen]
ugens)

-- * Encode (version zero)

-- | Encode functions for Graphdef types (join_f,str_f,i8_f,i16_f,i32_f,f32_f,com_f)
type Encode_Functions t = ([t] -> t,Name -> t,Int -> t,Int -> t,Int -> t,Double -> t,String -> t)

encode_input_f :: Encode_Functions t -> Input -> t
encode_input_f :: forall t. Encode_Functions t -> Input -> t
encode_input_f ([t] -> t
join_f,Name -> t
_,Int -> t
_,Int -> t
i16_f,Int -> t
_,Sample -> t
_,[Char] -> t
_) (Input Int
u Int
p) = [t] -> t
join_f (forall a b. (a -> b) -> [a] -> [b]
map Int -> t
i16_f [Int
u,Int
p])

encode_control_f :: Encode_Functions t -> Control -> t
encode_control_f :: forall t. Encode_Functions t -> Control -> t
encode_control_f ([t] -> t
join_f,Name -> t
str_f,Int -> t
_,Int -> t
i16_f,Int -> t
_,Sample -> t
_,[Char] -> t
_) (Name
nm,Int
k) = [t] -> t
join_f [Name -> t
str_f Name
nm,Int -> t
i16_f Int
k]

encode_ugen_f :: Encode_Functions t -> Ugen -> t
encode_ugen_f :: forall t. Encode_Functions t -> Ugen -> t
encode_ugen_f Encode_Functions t
enc (Name
nm,Int
r,[Input]
i,[Int]
o,Int
s) =
  let ([t] -> t
join_f,Name -> t
str_f,Int -> t
i8_f,Int -> t
i16_f,Int -> t
_,Sample -> t
_,[Char] -> t
com_f) = Encode_Functions t
enc
  in [t] -> t
join_f [[Char] -> t
com_f [Char]
"ugen-name",Name -> t
str_f Name
nm
            ,[Char] -> t
com_f [Char]
"ugen-rate",Int -> t
i8_f Int
r
            ,[Char] -> t
com_f [Char]
"ugen-number-of-inputs",Int -> t
i16_f (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Input]
i)
            ,[Char] -> t
com_f [Char]
"ugen-number-of-outputs",Int -> t
i16_f (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
o)
            ,[Char] -> t
com_f [Char]
"ugen-special",Int -> t
i16_f Int
s
            ,[Char] -> t
com_f [Char]
"ugen-inputs (ugen-index,port-index)",[t] -> t
join_f (forall a b. (a -> b) -> [a] -> [b]
map (forall t. Encode_Functions t -> Input -> t
encode_input_f Encode_Functions t
enc) [Input]
i)
            ,[Char] -> t
com_f [Char]
"ugen-output-rates",[t] -> t
join_f (forall a b. (a -> b) -> [a] -> [b]
map Int -> t
i8_f [Int]
o)
            ]

encode_graphdef_f :: Encode_Functions t -> Graphdef -> t
encode_graphdef_f :: forall t. Encode_Functions t -> Graphdef -> t
encode_graphdef_f Encode_Functions t
enc (Graphdef Name
nm [Sample]
cs [(Control, Sample)]
ks [Ugen]
us) =
    let ([t] -> t
join_f,Name -> t
str_f,Int -> t
_,Int -> t
i16_f,Int -> t
i32_f,Sample -> t
f32_f,[Char] -> t
com_f) = Encode_Functions t
enc
        ([Control]
ks_ctl,[Sample]
ks_def) = forall a b. [(a, b)] -> ([a], [b])
unzip [(Control, Sample)]
ks
    in [t] -> t
join_f [[Char] -> t
com_f [Char]
"SCgf",Int -> t
i32_f forall n. Num n => n
scgf_i32
              ,[Char] -> t
com_f [Char]
"version",Int -> t
i32_f Int
0
              ,[Char] -> t
com_f [Char]
"number of graphs",Int -> t
i16_f Int
1
              ,[Char] -> t
com_f [Char]
"name",Name -> t
str_f Name
nm
              ,[Char] -> t
com_f [Char]
"number-of-constants",Int -> t
i16_f (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Sample]
cs)
              ,[Char] -> t
com_f [Char]
"constant-values",[t] -> t
join_f (forall a b. (a -> b) -> [a] -> [b]
map Sample -> t
f32_f [Sample]
cs)
              ,[Char] -> t
com_f [Char]
"number-of-controls",Int -> t
i16_f (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Sample]
ks_def)
              ,[Char] -> t
com_f [Char]
"control-default-values",[t] -> t
join_f (forall a b. (a -> b) -> [a] -> [b]
map Sample -> t
f32_f [Sample]
ks_def)
              ,[Char] -> t
com_f [Char]
"number-of-controls",Int -> t
i16_f (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Control]
ks_ctl)
              ,[Char] -> t
com_f [Char]
"controls",[t] -> t
join_f (forall a b. (a -> b) -> [a] -> [b]
map (forall t. Encode_Functions t -> Control -> t
encode_control_f Encode_Functions t
enc) [Control]
ks_ctl)
              ,[Char] -> t
com_f [Char]
"number-of-ugens",Int -> t
i16_f (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ugen]
us)
              ,[t] -> t
join_f (forall a b. (a -> b) -> [a] -> [b]
map (forall t. Encode_Functions t -> Ugen -> t
encode_ugen_f Encode_Functions t
enc) [Ugen]
us)]

-- * Stat

-- | Simple statistics printer for 'Graphdef'.
graphdef_stat :: Graphdef -> String
graphdef_stat :: Graphdef -> [Char]
graphdef_stat (Graphdef Name
nm [Sample]
cs [(Control, Sample)]
ks [Ugen]
us) =
    let f :: (a -> a) -> [a] -> [Char]
f a -> a
g = let h :: [a] -> (a, Int)
h (a
x:[a]
xs) = (a
x,forall (t :: * -> *) a. Foldable t => t a -> Int
length (a
xforall a. a -> [a] -> [a]
:[a]
xs))
                  h [] = forall a. Partial => [Char] -> a
error [Char]
"graphdef_stat"
              in forall a. Show a => a -> [Char]
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall {a}. [a] -> (a, Int)
h forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Eq a => [a] -> [[a]]
group forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => [a] -> [a]
sort forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map a -> a
g
        sq :: ([[Char]] -> [[Char]]) -> [Char]
sq [[Char]] -> [[Char]]
pp_f = forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"," ([[Char]] -> [[Char]]
pp_f (forall a b. (a -> b) -> [a] -> [b]
map Ugen -> [Char]
ugen_name_op [Ugen]
us))
    in [[Char]] -> [Char]
unlines [[Char]
"name                      : " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Name
nm
               ,[Char]
"number of constants       : " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Sample]
cs)
               ,[Char]
"number of controls        : " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Control, Sample)]
ks)
               ,[Char]
"number of unit generators : " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ugen]
us)
               ,[Char]
"unit generator rates      : " forall a. [a] -> [a] -> [a]
++ forall {a} {a}. (Show a, Ord a) => (a -> a) -> [a] -> [Char]
f Ugen -> Int
ugen_rate [Ugen]
us
               ,[Char]
"unit generator set        : " forall a. [a] -> [a] -> [a]
++ ([[Char]] -> [[Char]]) -> [Char]
sq (forall a. Eq a => [a] -> [a]
nub forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => [a] -> [a]
sort)
               ,[Char]
"unit generator sequence   : " forall a. [a] -> [a] -> [a]
++ ([[Char]] -> [[Char]]) -> [Char]
sq forall a. a -> a
id]

-- * Dump Ugens

-- | Pretty print Ugen in the manner of SynthDef>>dumpUgens.
ugen_dump_ugen_str :: [Sample] -> [Ugen] -> Ugen_Index -> Ugen -> String
ugen_dump_ugen_str :: [Sample] -> [Ugen] -> Int -> Ugen -> [Char]
ugen_dump_ugen_str [Sample]
c_sq [Ugen]
u_sq Int
ix Ugen
u =
  let in_brackets :: String -> String
      in_brackets :: [Char] -> [Char]
in_brackets [Char]
x = forall r. PrintfType r => [Char] -> r
printf [Char]
"[%s]" [Char]
x
      input_pp :: Input -> t
input_pp (Input Int
i Int
j) =
        let ui :: Ugen
ui = [Ugen]
u_sq forall a. [a] -> Int -> a
!! Int
i
        in if Int
i forall a. Ord a => a -> a -> Bool
>= Int
0
           then if forall (t :: * -> *) a. Foldable t => t a -> Int
length (Ugen -> [Int]
ugen_outputs Ugen
ui) forall a. Ord a => a -> a -> Bool
> Int
1
                then forall r. PrintfType r => [Char] -> r
printf [Char]
"%d_%s:%d" Int
i (Ugen -> [Char]
ugen_name_op Ugen
ui) Int
j
                else forall r. PrintfType r => [Char] -> r
printf [Char]
"%d_%s" Int
i (Ugen -> [Char]
ugen_name_op Ugen
ui)
           else forall r. PrintfType r => [Char] -> r
printf [Char]
"%f" ([Sample]
c_sq forall a. [a] -> Int -> a
!! Int
j)
      inputs_pp :: [Input] -> [Char]
inputs_pp = [Char] -> [Char]
in_brackets forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"," forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall {t}. PrintfType t => Input -> t
input_pp
  in forall r. PrintfType r => [Char] -> r
printf [Char]
"%d_%s, %s, %s" Int
ix (Ugen -> [Char]
ugen_name_op Ugen
u) (forall a. Show a => a -> [Char]
show (Ugen -> Rate
ugen_rate_enum Ugen
u)) ([Input] -> [Char]
inputs_pp (Ugen -> [Input]
ugen_inputs Ugen
u))

-- | Print graphdef in format equivalent to SynthDef>>dumpUgens in SuperCollider
graphdef_dump_ugens_str :: Graphdef -> [String]
graphdef_dump_ugens_str :: Graphdef -> [[Char]]
graphdef_dump_ugens_str (Graphdef Name
_nm [Sample]
cs [(Control, Sample)]
_ks [Ugen]
us) = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ([Sample] -> [Ugen] -> Int -> Ugen -> [Char]
ugen_dump_ugen_str [Sample]
cs [Ugen]
us) [Int
0..] [Ugen]
us

{- | 'putStrLn' of 'unlines' of 'graphdef_dump_ugens_str'

> import Sound.Sc3.Server.Graphdef
> dir = "/home/rohan/sw/rsc3-disassembler/scsyndef/"
> pp nm = read_graphdef_file (dir ++ nm) >>= graphdef_dump_ugens
> pp "simple.scsyndef"
> pp "with-ctl.scsyndef"
> pp "mce.scsyndef"
> pp "mrg.scsyndef"
-}
graphdef_dump_ugens :: Graphdef -> IO ()
graphdef_dump_ugens :: Graphdef -> IO ()
graphdef_dump_ugens = [Char] -> IO ()
putStrLn forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Char]] -> [Char]
unlines forall b c a. (b -> c) -> (a -> b) -> a -> c
. Graphdef -> [[Char]]
graphdef_dump_ugens_str