hsc3-db-0.15: Sound/SC3/UGen/DB/Bindings/Lisp.hs
-- * LISP UGEN BINDINGS
module Sound.SC3.UGen.DB.Bindings.Lisp where
import Data.Char {- base -}
import Data.Maybe {- base -}
import Text.Printf {- base -}
import Sound.SC3.Common {- hsc3 -}
import Sound.SC3.UGen.Name {- hsc3 -}
import Sound.SC3.UGen.Operator {- hsc3 -}
import Sound.SC3.UGen.Rate {- hsc3 -}
import qualified Sound.SC3.UGen.DB as DB {- hsc3-db -}
import qualified Sound.SC3.UGen.DB.Bindings as DB {- hsc3-db -}
import qualified Sound.SC3.UGen.DB.Record as DB {- hsc3-db -}
import qualified Sound.SC3.UGen.DB.Rename as DB {- hsc3-db -}
lisp_rate_id :: Rate -> String
lisp_rate_id = map toLower . show
lisp_list_pp :: [String] -> String
lisp_list_pp x = "(list " ++ unwords x ++ ")"
lisp_rate :: DB.U -> (Maybe String,String)
lisp_rate u =
case DB.ugen_filter u of
Just ix -> (Nothing,lisp_list_pp (map show ix))
Nothing -> case DB.ugen_fixed_rate u of
Just fx -> (Nothing,lisp_rate_id fx)
Nothing -> (Just "rt","rt")
lisp_nc :: DB.U -> String -> (Maybe String,String)
lisp_nc u mc =
case DB.u_fixed_outputs u of
Just d -> (Nothing,show d)
Nothing ->
if DB.ugen_nc_input u
then (Just "nc","nc")
else if DB.ugen_std_mce u
then (Nothing,printf "(length (mce-channels %s))" mc)
else error "NC?"
-- | mk-ugen name rate|[ix] inputs mce-input|nil nc special|nil uid|nil
--
-- > let u = "SinOsc Resonz Demand Drand Dwhite BinaryOpUGen SampleRate Abs"
-- > mapM_ (putStrLn . lisp_mk_ugen) (words u)
lisp_mk_ugen :: String -> String
lisp_mk_ugen nm =
let (nm',sp) = resolve_operator CS nm
u = case DB.uLookup CI nm' of
Nothing -> error ("lisp_mk_ugen: unknown ugen: " ++ nm')
Just r -> r
z = if DB.ugen_nondet u then "(incr-uid 1)" else "nil"
i = DB.u_renamed_inputs u
(i',mc) = DB.bindings_mce u i
mc' = fromMaybe "nil" mc
i_k = if null i' then "nil" else "(list " ++ unwords i' ++ ")"
(rt_var,rt_k) = lisp_rate u
(nc_var,nc_k) = lisp_nc u mc'
sp' = case sp of
Nothing -> "nil"
Just k -> show k
param = mcons nc_var (mcons rt_var i)
lisp_nm = DB.scheme_rename (sc3_name_to_lisp_name nm)
template_f = concat ["(define %s\n"
," (lambda (%s)\n"
," (mk-ugen (list \"%s\" %s %s %s %s %s %s))))\n"]
template_v = "(define %s (mk-ugen (list \"%s\" %s %s %s %s %s %s)))\n"
in if null param
then printf template_v lisp_nm nm rt_k i_k mc' nc_k sp' z
else printf template_f lisp_nm (unwords param) nm rt_k i_k mc' nc_k sp' z
-- | The generated bindings are for @sin-osc@ etc, alias these to @SinOsc@ etc.
--
-- > writeFile "/tmp/alias.lisp" (unlines (map lisp_mk_alias DB.complete_names))
lisp_mk_alias :: String -> String
lisp_mk_alias nm =
let lisp_nm = DB.scheme_rename (sc3_name_to_lisp_name nm)
in printf "(define %s %s)" nm lisp_nm
mcons :: Maybe a -> [a] -> [a]
mcons e = case e of {Nothing -> id; Just e' -> (e' :)}
-- > mapM_ putStrLn operator_sym_def
operator_sym_def :: [String]
operator_sym_def =
let f (bin,sym_nm) =
let sc3_nm = show bin
in printf "(define %s %s)" sym_nm (sc3_name_to_lisp_name sc3_nm)
in map f binaryTable
-- > mapM_ putStrLn scheme_rename_def
scheme_rename_def :: [String]
scheme_rename_def =
let f nm = printf "(define %s %s)" nm (DB.scheme_rename nm)
in map f DB.scheme_names