如何在common-lisp中将函数传递给宏

问题描述 投票:0回答:1

我正在尝试用 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
正确扩展?

common-lisp lisp-macros
1个回答
0
投票

回答我自己...

如果我更换线路

(sig (eval pan-func))

(sig (,@pan-func))

看起来有效!尽管我仍然不确定这是“正确”的做法,或者我的方法是否适合我正在尝试处理的问题。

© www.soinside.com 2019 - 2024. All rights reserved.