2013-05-03 24 views
7

Ben müzisyenim ve Clojure'da A4 ve A5 (sırasıyla 440Hz ve 880Hz frekansları) arasında basit bir glissando oluşturmak için bir işlev yazmakla oynuyorum. üstel eğri, ama başım belaya giriyor. Temelde böyle kullanmak istiyorum: Sonunda da bunu bir üçüncü bağımsız numune-oran vermek istiyorum hariçGlissando İşlevleri, codomain'in cotası olan ekstremler olan

=>(441 484 529 576 625 676 729 784 841) 

:

(def A4 440) 
(def A5 880) 
(gliss A4 A5) 

bana böyle bir şey vermesi gereken.

Bu tür eserlerde:

(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))))) 

Sorunu sanırım işlevini kullanmak istiyorum yoludur. "X1'den x2'ye kadar glissando gibi bir şey söylemek yerine, f (x) = x^2" demek istiyorum ki, "glissando'dan f (x) == 440 ila f (x) == 880" deniyorum) m aslında başlangıçta çalışmak için x bir dizi vermedi, bu yüzden bu durumda sadece 0 10000 kodlanmış neden, ama bu çirkin.

Yapmaya çalıştığım şeyi başarmanın daha iyi bir yolu nedir?

Güncelleme: Düzeltmeye ihtiyaç duyan terminolojide bir hata yaptım (Clojure'da bir glissando'yu notlamak için buraya gelen insanların tüm orduları için). Üçüncü argüman gerçekten örnekleme oranı değildir, örnek sayısı olmalıdır. Diğer bir deyişle, örnekleme hızı (44100Hz veya 48000Hz, vs. olabilir) belirli bir süre için ihtiyaç duyacağınız örnek sayısını belirler. Böyle

(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)) 

cevap

5

Eğer 44100 bir örnekleme hızında 500 milisaniyelik bir süre boyunca A5 A4 bir e üstel eğri ile glissando Gerekirse, bu işlevleri kullanabilir

(ns hello.exp 
    (:require [clojure.math.numeric-tower :as math])) 

(defn gliss [start end rate] 
    (map #(+ start (* (math/expt (/ (inc %) rate) 2.718281828) (- end start))) 
     (range rate))) 

Bu tam çünkü gliss eğrisi uymuyor: burada oran örnekleri ile frekans aralığının aralığında dağılmış basit üstel eğrisi im e kullanarak, overtone için beslerseniz iyi geleceğinden şüpheliyim, ancak;) uygun bir müzikal glümanın, bu işlevdeki 1 numaralı üssü, wikipedia makalesinde okuduğum öğeden kullanacağından şüpheleniyorum.

hello.exp> (gliss 440 880 5)              
(445.5393041947095 476.4535293633514 549.7501826896913 679.8965206341077 880.0) 

hello.exp> (map int (gliss 440 880 100)) 
(440 440 440 440 441 441 442 442 443 444 445 446 447 448 449 
451 452 454 455 457 459 461 463 465 467 469 472 474 477 479 
482 485 487 490 493 497 500 503 506 510 513 517 521 525 529 
533 537 541 545 550 554 558 563 568 573 577 582 588 593 598 
603 609 614 620 625 631 637 643 649 655 661 668 674 680 687 
694 700 707 714 721 728 735 743 750 757 765 773 780 788 796 
804 812 820 828 837 845 853 862 871 880) 
+0

Bu harika bir yanıttır. Ben kesinlikle "e" yi seçtiğini ve overtone 'dan bahsettiğini beğendim. Bunu kesinlikle overtone ile test etmeliyim. 1'in üslubuna gelince, bir müzikal kadrosundaki notasyonun bu şekilde yapılması gerektiği gibi görünmesini sağladığını düşünüyorum, ancak pratikte neredeyse hiç doğrusal olarak yapılmadılar. – tjb1982