2015-11-03 19 views
5

Tôi cố gắng để triển khai phiên bản đơn giản nhất của Karplus-Strong algorithm sử dụng Euterpea:phản hồi Đệ quy trong Karplus-Strong Algo - mũi tên

schematic of KS algorithm

Mã của tôi: 0,7 giây của tiếng ồn trắng bật

burst :: AudSF() Double 
burst = proc() -> do 
    burstEnv <- envLineSeg [1,1,0,0] [0.7, 0, 9.3] -<() 
    noise <- noiseWhite 42 -<() 
    outA -< burstEnv * noise 

phần có vấn đề:

karplus :: AudSF Double Double 
karplus = proc input -> do 
    rec filtered <- filterLowPass -< (delayed, 2000) 
     delayed <- delayLine 0.7 -< filtered + input  
    outA -< filtered + input 

test1 chức năng nên tạo một file 10 giây với một vài chu kỳ:

test1 = outFile "test1.wav" 10 $ burst >>> karplus 

Theo như tôi biết vòng phản hồi nên chạy vào và cứ tiếp tục.

Vấn đề là đầu vào chỉ bị trễ và được lọc một lần. Nó không được đưa vào vòng lặp nữa.

Tôi nghi ngờ rằng vấn đề nằm trong sự đánh giá lười biếng không hiểu biết hoặc giá trị của tôi.

+3

Đánh giá lười biếng có thể ảnh hưởng đến việc chương trình bị kẹt trong một vòng lặp vô hạn , nhưng nó không thể thay đổi một chương trình thực hiện thành công một thứ vào một chương trình thực hiện thành công một chương trình khác. Là chương trình bị mắc kẹt, hoặc chỉ là sai? – dfeuer

+0

@dfeuer nó sai. Đầu ra singal không được đưa vào vòng lặp. – Lovaz

+3

Nếu nó tạo ra kết quả sai, bạn có thể loại trừ sự lười biếng là nguyên nhân. – dfeuer

Trả lời

2

Vấn đề không phải là đánh giá lười biếng hoặc mũi tên đệ quy; thay vào đó, nó là filterLowPass không hoạt động tốt trên burst: nó trở thành NaN sau khi kết thúc cụm.

Chúng tôi có thể thấy rằng bằng cách chạy nó, ví dụ: trong GHCi:

λ» take 15 $ drop 30870 $ Control.SF.SF.run (strip $ burst >>> arr (,2000) >>> filterLowPass) $ repeat() 
[0.17166330080286152,0.27722776378398983,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN] 

tôi rất nghi ngờ đó là vì burst bản thân cư xử kỳ lạ gần kết thúc của nó:

λ» take 15 $ drop 30870 $ Control.SF.SF.run (strip $ burst) $ repeat() 
[0.5998949495013488,NaN,0.0,-0.0,-0.0,0.0,-0.0,-0.0,0.0,-0.0,-0.0,-0.0,0.0,-0.0,0.0] 

Đề nghị của tôi là để sửa chữa burst để nó không tạo ra một NaN lúc kết thúc của nó, và sau đó xem có khắc phục được mọi thứ không. Dao động 0/-0 có thể vô hại.

Cố gắng sửa chữa tại

Tôi không có ý tưởng về một trong hai Euterpea hoặc tổng hợp âm thanh; tuy nhiên, bằng cách sử dụng thời gian chuyển đổi rất ngắn nhưng không phải 0 từ 01 đến 0 cho burstEnv, tôi có thể loại bỏ các số NaN s. Bằng cách tiếp tục giảm độ dài của cụm và đường trễ, tôi nghĩ rằng tôi có được thứ gì đó gần với âm thanh "giống như chuỗi" mong muốn:

burst :: AudSF() Double 
burst = proc() -> do 
    burstEnv <- envLineSeg [1,1,0,0] [0.01, 0.000001, 9.3] -<() 
    noise <- noiseWhite 42 -<() 
    outA -< burstEnv * noise 

karplus :: AudSF Double Double 
karplus = proc input -> do 
    rec delayed <- delayLine 0.01 -< filtered + input 
     filtered <- filterLowPass -< (delayed, 2000) 
    outA -< filtered + input