Comon-lisp:整数不是实数类型

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

我对如何在 common lisp 中设置参数感到困惑,试图设置一个全局变量来在 cl-collider 中生成一堆合成器定义。 此代码有效:

(defs sine
  :args ((freq 440)
         (lag 0.1))
  :sig ((sig (sin-osc.ar (lag.kr freq lag)))
        (sig (* sig (amp-comp-a.kr freq))))
  :num-channels 2)

但是当我这样做时:

(defparameter *num-channels* 2)
...
:num-channels *num-channels*)

我收到此错误:

The value
  *NUM-CHANNELS*
is not of type
  REAL
   [Condition of type TYPE-ERROR]

产生synthdef的宏是这样的:

(defmacro defs (name &key args sig (num-channels 2) (env :asr) (act :free))
  (let ((pan-func nil)
        (env-func nil)
        (arg-list '((attack 0) (release 0)
                    (out 0) (pan 0) (amp 1))))
    (case num-channels
      ((nil) (setf pan-func 'sig))
      (2 (setf pan-func '(pan2.ar sig pan)))
      (4 (setf pan-func '(pan4.ar sig pan)))
      (t (setf pan-func `(pan-az.ar ,num-channels sig pan :width width))))
    (case env
      (:asr (setf env-func `(env-gen.kr (asr attack 1 release) :gate gate :act ,act)))
      (:perc (setf env-func `(env-gen.kr (perc attack release) :act ,act))))
    (if (not(equal env :perc))
        (setf arg-list (append arg-list '((gate 1)))))
    (if (> num-channels 4)
        (setf arg-list (append arg-list '((width 2)))))
    `(defsynth ,name (,@arg-list ,@args)
       (let* ((env ,env-func)
              ,@sig
              (sig (* sig env amp))
              )
         (out.ar out ,pan-func)))))

非常感谢任何帮助!

common-lisp
1个回答
1
投票

宏需要 num-channels 的字面值,但是当您传递

*num-channels*
时,它会计算为符号,而不是存储在其中的值。

您可以在反引号形式中使用 , 来确保

*num-channels*
的值正确插入到宏中。
希望这会起作用

(defparameter *num-channels* 2)

(defmacro defs (name &key args sig (num-channels 2) (env :asr) (act :free))
  (let ((pan-func nil)
        (env-func nil)
        (arg-list '((attack 0) (release 0)
                    (out 0) (pan 0) (amp 1))))
    (case ,num-channels   ; <- use the comma operator here
      ((nil) (setf pan-func 'sig))
      (2 (setf pan-func '(pan2.ar sig pan)))
      (4 (setf pan-func '(pan4.ar sig pan)))
      (t (setf pan-func `(pan-az.ar ,num-channels sig pan :width width))))
    (case env
      (:asr (setf env-func `(env-gen.kr (asr attack 1 release) :gate gate :act ,act)))
      (:perc (setf env-func `(env-gen.kr (perc attack release) :act ,act))))
    (if (not(equal env :perc))
        (setf arg-list (append arg-list '((gate 1)))))
    (if (> ,num-channels 4)
        (setf arg-list (append arg-list '((width 2)))))
    `(defsynth ,name (,@arg-list ,@args)
       (let* ((env ,env-func)
              ,@sig
              (sig (* sig env amp))
              )
         (out.ar out ,pan-func)))))
© www.soinside.com 2019 - 2024. All rights reserved.