中音如何在泛音中起作用?

时间:2014-07-24 19:41:51

标签: clojure overtone

我正在尝试添加一些微调功能来泛音,但是在处理函数midicps方面我遇到了问题,这似乎是处理midi输入的必要条件。

这就是我想要的:

(definst instrument [note 64 amp 0.5 gate 1]
  (* amp (lpf (lf-tri (foo note) ) 1100)
  (env-gen (adsr 0.1 0.2 2 2 0.3) gate :action FREE)))

foo是一个函数,它接受midi值并将其映射到hz中的值(有点像midicps),但是,上面的代码无法正确运行。

为了测试,我将foo定义为:

(defn foo [x] (if (= 64 x) 880 440))

因此,(instrument 64)应该比任何其他foo更高一个八度音符,但事实并非如此。

我相信发生的事情是,当我运行(instrument x)时,它会将其他内容(midi事件?)传递给foo而不是整数本身。

每当我尝试midi->hz超过midicps时,我都会收到错误:

CompilerException java.lang.ClassCastException: overtone.sc.machinery.ugen.sc_ugen.SCUGen 
cannot be cast to java.lang.Number, compiling:(form-init7628662755818333410.clj:1:1)

在没有midicps的情况下调用midi-> hz会产生相同的错误。

如何将此ugen(或midi事件)转换为表示midi音符的整数?

注意:我正在使用midi-poly-player为我的乐器添加midi处理程序。如果我只是制作一个常规的音符事件处理程序,我可以让我的音调映射函数工作,但我宁愿使用midi-poly-player,所以我不必重新实现它的所有功能。

1 个答案:

答案 0 :(得分:1)

当你像这样调用foo函数时,你正在混合scsynth ugens和Clojure代码。在definst中,它是一个宏,它采用Clojure代码并将其转换为supercollider合成器代码。我实际上并不理解代码为什么会这样,但我想我可以告诉你如何让它做你想做的事情。只需将代码保存在definst宏中即可。

这是Clojure中的midi> hz函数。 midicps为你做超级滑翔的ugen:

(defn midi->hz
  "Convert a midi note number to a frequency in hz."
  [note]
  (* 440.0 (java.lang.Math/pow 2.0 (/ (- note 69.0) 12.0))))

您可以在definst中列出note->频率转换:

(definst instrument2 [note 64 amp 0.5 gate 1]
  (let [freq (* 440.0 (pow 2.0 (/ (- note 69.0) 12.0)))]
    (* amp (lpf (lf-tri freq) 1100)
       (env-gen (adsr 0.1 0.2 2 2 0.3) gate :action FREE))))

并听取每个比例输出的标准12个音符,如:

(def x (instrument2 69))
(ctl x :gate 0)
(def x (instrument2 70))
(ctl x :gate 0)
(def x (instrument2 71))
(ctl x :gate 0)
例如,

调整更多的每八度音调,这给出了24 ...

(definst instrument3 [note 64 amp 0.5 gate 1]
  (let [freq (* 440.0 (pow 2.0 (/ (- note 69.0) 24.0)))]
    (* amp (lpf (lf-tri freq) 1100)
       (env-gen (adsr 0.1 0.2 2 2 0.3) gate :action FREE))))

(def x (instrument3 69))
(ctl x :gate 0)
(def x (instrument3 70))
(ctl x :gate 0)
(def x (instrument3 71))
(ctl x :gate 0)

我听到一系列较小的步骤。我希望你也这样做。

干杯,

罗杰