You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CL-Collider中使用全局变量设置num-channels参数报错求助

解决CL-Collider中使用全局变量设置:num-channels的类型错误

问题原因

你的问题核心在于宏的编译期求值特性:

  • 直接传入:num-channels 2时,宏在编译阶段拿到的是数值2,后续的case判断、> num-channels 4比较都能正常执行,生成的合成器代码符合CL-Collider的要求。
  • 传入:num-channels *num-channels*时,宏在编译阶段拿到的是符号*NUM-CHANNELS*而非它的数值2:
    1. case判断找不到匹配分支,进入默认分支,将符号直接插入到pan-az.ar的参数列表中;
    2. > num-channels 4是用符号和数字做比较,编译阶段不会报错,但生成的合成器代码运行时,CL-Collider要求pan-az.ar的第一个参数为REAL类型,符号显然不符合,因此抛出类型错误。

解决方法

修改defs宏,在编译阶段对num-channels参数求值,确保拿到的是实际数值而非符号。修改后的宏代码如下:

(defmacro defs (name &key args sig (num-channels 2) (env :asr) (act :free))
  (let* ((num-channels-val (eval num-channels)) ; 关键:编译期求值num-channels参数
         (pan-func nil)
         (env-func nil)
         (arg-list '((attack 0) (release 0)
                     (out 0) (pan 0) (amp 1))))
    (case num-channels-val
      ((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-val 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-val 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)))))

使用验证

先定义全局变量:

(defparameter *num-channels* 2)

再调用defs宏时传入:num-channels *num-channels*,宏会在编译阶段自动获取全局变量的数值2,生成与直接传入数值完全一致的合成器定义,运行时不再出现类型错误。

内容的提问来源于stack exchange,提问作者kflak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 07:45:59