2015-11-03 11 views
5

私はEuterpeaを使用してKarplus-Strong algorithmの最も簡単なバージョンを実装しようとしています:再帰的なフィードバック - 矢印

schematic of KS algorithm

マイコード:ホワイトノイズの 0.7秒は

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

問題部分:

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

test1の機能は、いくつかのサイクルで10秒のファイルを作成する必要があります。

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

を私の知る限りは、フィードバックループが上と上とで実行する必要があります知っています。

問題は入力が遅延され、一度しかフィルタリングされないことです。それはループに再び供給されません。

私は、問題が怠惰な評価や値渡しを理解していないと思っています。

+3

遅延評価は、プログラムが無限ループで立ち往生かどうかに影響を与えることができます。さらに、バーストの長さと遅延線を減らすことで、私は私が所望の「紐状」の音に近いものを得たと思いますしかし、あるプログラムを正常に実行するプログラムを、別のプログラムを正常に実行するプログラムに変更することはできません。プログラムが止まったのか、それとも間違っていますか? – dfeuer

+0

@dfeuerそれは間違っています。出力信号はループに供給されません。 – Lovaz

+3

出力が間違っている場合は、原因として怠惰を除外することができます。 – dfeuer

答えて

2

問題は遅延評価または再帰的な矢印ではありません。むしろ、はburstで正常に動作しません。バーストが終了した後にはNaNになります。

GHCiの中で:

λ» 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] 

私の提案は、それはその端部にNaNを発生させないようにburstを修正することです:

λ» 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] 

私は強くburst自体が終わり近くに奇妙な振る舞いので、それは疑いますそれがすべてを修正するかどうかを確認します。おそらく0/-0の振動は無害です。私はEuterpeaや音合成のいずれかについては考えている

を固定で

試み。しかし、burstEnvの1から0までの非常に短い、しかし0以外の遷移時間を使用すると、私はNaNを取り除くことができました。

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