我是一名音乐家,我正在使用 Clojure 编写一个函数来重现音高 A4 和 A5(频率分别为 440Hz 和 880Hz)之间的简单滑音,具有指数曲线,但我遇到了麻烦。基本上我想像这样使用它:
(def A4 440)
(def A5 880)
(gliss A4 A5)
这应该给我类似的东西:
=>(441 484 529 576 625 676 729 784 841)
除了我最终还想给它一个采样率作为第三个参数。
这种作品:
(defn gliss
[start-pitch end-pitch s-rate]
(let [f (fn [x]
(expt x 2))]
(remove nil?
(map
(fn [x]
(when (and
(>= (f x) start-pitch)
(<= (f x) end-pitch))
(f x)))
(range 0 10000 s-rate)))))
我想问题是我想使用该功能的方式。而不是说“从 x1 到 x2 的滑奏,其中 f(x) = x^2”我真的想说“从 f(x) == 440 到 f(x) == 880 的滑奏”所以我m 最初并没有真正给出 x 的范围,因此在这种情况下我只是硬编码 0 到 10000,但这很难看。
有什么更好的方法来完成我想做的事情?
更新:我在需要修复的术语上犯了一个错误(对于所有来到这里希望在 Clojure 中标记滑音的人)。第三个参数并不是真正的采样率,它应该是样本数。换句话说,采样率(可能是 44100Hz 或 48000Hz 等)决定了您在特定时间段内需要的采样数。如果您需要一个具有e
从 A4 到 A5 的指数曲线的滑音,持续时间为 500 毫秒,采样率为 44100,您可以使用以下函数:
(defn gliss
[start end samples]
(map #(+ start
(*
(math/expt (/ (inc %) samples) 2.718281828)
(- end start)))
(range samples)))
(defn ms-to-samps
[ms s-rate]
(/ (* ms s-rate) 1000))
像这样:
(def A4 440)
(def A5 (* A4 2))
(def s-rate 44100) ;; historic CD quality sample rate
(gliss A4 A5 (ms-to-samps 500 s-rate))