[CM] The simplest defsynth possible
Mario Lang
mlang at delysid.org
Fri Sep 30 02:01:12 PDT 2005
Hi.
Since I am a SC fanatic with a bias towards Lisp, I'd really
like to play with CM's SC support, but the fact that SynthDef
and scheduling code is separate really turns me off. This
is soooo csound! :-/ Ideally, we should be able to define
the synth graph in the same language IMO. Below is the probably
simplest implementation to do this, as an inspiration. It uses
Emacs's interface to SCLang, translating synth definition in
Lisp into sclang code and evaluating it in sclang to
generate the required def (actually, it already sends it to the server
using .store).
I see two approaches if someone wants to do this in CM directly:
1: Either do the same as below, but send the string to
sclang as a subprocess, simply fork sclang and pass the code to it
so it can write the def file or send the def to the server.
2: Emulate the behaviour of SynthDef.writeDef in the macro
directly and generate the necessary binary blob. Its actually
not *that* complicated, the most important issue is
that we don't know the class definitions of sclang in Lisp
so we *need* to make defsynth a macro to be able to
use arbitrary symbol names.
Now, here is the code, with a usage example at the end. Now, wouldnt
that be sweet for CM directly? Ideally, the macro should
be a little more intelligent, allowing real lisp code inside
the definition which is evaluated at macro expansion time.
But for a pure graph definition, the system below is enough.
(defmacro defsynth (name args &rest body)
"Define a synth graph with NAME and ARGS and BODY.
Returns NAME as symbol with property 'sclang-code.
Use `sclang-store-synth' to actually send the generated code to sclang."
(put name 'sclang-code
(sclang-format
"SynthDef(%o, {%s%s})"
name
(if args
(concat "arg "(mapconcat
(lambda (arg)
(if (consp arg)
(sclang-format "%s=%o" (car arg) (cadr arg))
(sclang-format "%s" arg)))
args ", ")";\n")
"")
(mapconcat #'sclang-lisp-to-sc body "\n")))
`',name)
(defun sclang-lisp-to-sc (expr)
(cond
((consp expr)
(cond
(t (sclang-format "%s(%s);" (car expr) (mapconcat
#'sclang-lisp-to-sc (cdr expr)
", ")))))
(t (format "%S" expr))))
(defun sclang-store-synth (synth)
(sclang-eval-string (sclang-format "%s.store" (get synth 'sclang-code))))
;; USAGE
(sclang-store-synth
(defsynth fasl ((freq 440) (amp 0.2) (out 0))
(Out.ar out (SinOsc.ar freq 0 amp))))
--
CYa,
Mario
More information about the Cmdist
mailing list