我正在尝试用 Common Lisp 来理解宏,并且我有这段代码可以使用 cl-collider 客户端为超级对撞机声音合成语言创建合成定义:
(defmacro make-defsynth (name &key args sig (num-channels 2) (env :asr) (pan t))
"Macro for creating defsynths. Defines some common args: out,
pan, gate, as well as setting up the envelope according to the env
argument. Valid envelopes are :asr and :perc. If pan is nil, then
the signal will not be panned, but passed directly through."
(let ((pan-func nil))
(case num-channels
(2 (setf pan-func '(pan2.ar sig pan)))
(4 (setf pan-func '(pan4.ar sig pan)))
(6 (setf pan-func '(pan-az.ar sig pan))))
`(defsynth ,name (,@args (attack 0) (release 0)
(out 0) (pan 0) (amp 1) (gate 1))
(let* ((env (env-gen.kr (asr attack 1 release)
:gate gate :act :free))
,@sig
(sig (* sig env amp))
(sig (eval pan-func)))
(out.ar out sig)))))
我想使用这个宏来创建一个像这样的synthdef:
(make-defsynth playbuf-mono
:args ((buf 0)
(rate 1)
(start-pos 0)
(loop 0))
:sig ((sig (play-buf.ar 1 buf rate
:start-pos start-pos
:loop loop))))
我收到错误:
The variable PAN-FUNC is unbound.
[Condition of type UNBOUND-VARIABLE]
接下来的问题是:如何让 pan-func 根据
num-channels
正确扩展?
回答我自己...
如果我更换线路
(sig (eval pan-func))
与
(sig (,@pan-func))
看起来有效!尽管我仍然不确定这是“正确”的做法,或者我的方法是否适合我正在尝试处理的问题。