形式
(eval pan-func)
在宏观扩张时不会进行评估,而且无论如何都不会起作用,因为
EVAL
不能
看见
本地词汇绑定。
您希望插入代码
(defmacro make-defsynth (name &key args sig
(num-channels 2) (env :asr) (pan t))
(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 ,pan-func))
(out.ar out sig)))))
你现在需要考虑在哪里
env
和
pan
应该使用,绑定应该来自哪里。现在在上面的代码中
env
和
平底锅
论点
make-defsynth
未使用。
风格:我不会称之为
制作defsynth
.
make-something
意味着某些东西是在运行时制作的。但这是一个定义宏,在宏扩展/编译时展开。
使用
macroexpand
,
macroexpand-1
和
pprint
要调试代码,请检查使用宏创建的代码:
CL-USER 35 > (defmacro make-defsynth (name &key args sig
(num-channels 2) (env :asr) (pan t))
(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 ,pan-func))
(out.ar out sig)))))
MAKE-DEFSYNTH
然后调试它:
CL-USER 36 > (pprint
(macroexpand-1
'(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))))))
(DEFSYNTH
PLAYBUF-MONO
((BUF 0)
(RATE 1)
(START-POS 0)
(LOOP 0)
(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 (PLAY-BUF.AR 1 BUF RATE :START-POS START-POS :LOOP LOOP))
(SIG (* SIG ENV AMP))
(SIG (PAN2.AR SIG PAN)))
(OUT.AR OUT SIG)))