【问题标题】:clojure, literal vector differs from function resultclojure,文字向量与函数结果不同
【发布时间】:2013-09-27 12:34:19
【问题描述】:

我正在尝试使用 clojure 的泛音库制作音乐。为了产生有趣的声音,加法合成很有用,这意味着我需要几个频率的正弦振荡器并简单地添加它们。在泛音中,要创建一个合成器,实现这一点,我可以写:

(definst myinst [freq 100]
  (* 0.2 (reduce + (map sin-osc [101.0 100 99.0]))))

为了更可重用,我写了一个函数,它接受一个频率并返回一个包含所有这些频率的列表,你可以在代码 sn-p 中看到:

(defn split-freq [freq]
  (apply vector (map #(* freq %) [1.01 1 0.99])))

当执行(split-freq 100) 时,REPL 给了我以下信息:

[101.0 100 99.0]

和输入一模一样,我提供了上面的map函数。事实上,我复制了结果。现在,我试试这个:

(definst myinst [freq 100]
  (* 0.2 (reduce + (map sin-osc (split-freq freq)))))

不幸的是,REPL 告诉我,我做错了:

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

但是这段代码可以正常工作:

(definst myinst [freq 100]
  (* 0.2 (reduce + (map sin-osc (apply vector (map #(* freq %) [1.01 1 0.99]))))))

虽然,我只是简单地把函数定义放进去。

我认为我主要缺乏理解。我想,如果其中一个版本有效,那么其他版本也必须有效。

我的问题是: 为什么我的“改进”版本不起作用? 为什么第一个 sn-p 工作? 如何规避这种行为?

Clojure 1.3.0
Overtone 0.8
(use 'overtone.core)

【问题讨论】:

  • 尝试宏扩展对 definst 的调用。可能 definst 是一个复杂的宏,它将通常是函数(如+)解释为对一组信号求和的合成器定义,而您的新定义形式会破坏宏。 Clojure 代码无法在 sc 合成器进程中运行,因此您的表单需要翻译成 sc 合成器定义,并且实际上不能是真正的 clojure 代码。

标签: clojure type-conversion sound-synthesis


【解决方案1】:

ups,你是对的,我不明白noisesmith的评论。确实,你不能在你的函数中直接使用这个值“freq”,因为这个值在你的函数需要它的时候(在宏执行之前)没有被绑定

所以这里有一个解决这个问题的方法,同样使用 let 形式,它不像制作自己的宏那么优雅,但可以工作

(defn myinst [inst-name]
  (let [the-freq 100]
   (definst inst-name [freq the-freq] (* 0.2 (reduce + (map sin-osc (split-freq the-freq)))))))

你可以像普通函数一样执行

((myinst "my-instrument"))

希望对你有帮助

胡安


以前的评论,现在无效的回复

也许您在改进版本中的参数值声明有误

这是你的代码

(definst myinst [freq 100]
  (* 0.2 (reduce + (map sin-osc (split-freq freq)))))

而且,就像在 clojure 中一样,您不能为参数函数分配默认值,如果您使用 let 形式分配默认值,您的改进版本将可以工作

(definst myinst []
  (let [freq 100]
    (* 0.2 (reduce + (map sin-osc (split-freq freq))))))  

【讨论】:

  • 谢谢,首先。正如noisesmith 指出的那样,definst 是一个宏。它需要偶数个参数,每一秒代表一个默认值。有趣的是,您的版本可以编译,但我无法再使用参数调用myinst。我跟着,definst 把它的论点变成了我上面提到的这些奇怪的类型。我需要转换它们...
  • 嗯。并不真地。我想“实例化”一种乐器(definst)并以不同的频率使用它。如果我正确理解您的解决方案,我需要为每个频率实例化一个仪器。我应该在我的问题中澄清这一点。另外,我认为这个问题与泛音有关,而不是与clojure有关。感谢您的努力!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多