私はミュージシャンで、A4 と A5 のピッチ (それぞれ周波数 440Hz と 880Hz) の間の単純なグリッサンドを指数曲線で再現する関数を Clojure で書いて遊んでいますが、問題が発生しています。基本的には、次のように使用したいと思います。
(def A4 440)
(def A5 880)
(gliss A4 A5)
これは私に次のようなものを与えるはずです:
=>(441 484 529 576 625 676 729 784 841)
ただし、最終的には、3 番目の引数としてサンプルレートも指定したいと考えています。
この種の作品:
(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)))))
問題は、関数を使用したい方法だと思います。「f(x) = x^2 の場合、x1 から x2 へのグリッサンド」のようなことを言う代わりに、「f(x) == 440 から f(x) == 880 へのグリッサンド」と言いたいので、 m には、最初に使用する x の範囲が実際には与えられていないため、この場合は 0 から 10000 をハードコードしただけですが、これは醜いです。
私がやろうとしていることを達成するためのより良い方法は何ですか?
更新:修正が必要な用語の誤りを犯しました (Clojure でグリッサンドを記譜しようとしてここに来る大勢の人々のために)。3 番目の引数は実際にはサンプルレートではなく、サンプル数でなければなりません。つまり、サンプル レート (44100Hz または 48000Hz など) によって、特定の期間に必要なサンプル数が決まります。44100 のサンプリング レートで 500 ミリ秒にわたって A4 から A5 までの指数曲線を持つグリッサンドが必要な場合は、e
次の関数を使用できます。
(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))