haskell - Karplus-Strong Algo 中的递归反馈 - 箭头

标签 haskell reactive-programming arrows

我正在尝试实现 Karplus-Strong algorithm 的最简单版本使用Euterpea :

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

据我所知,反馈循环应该不断地运行。

问题是输入仅被延迟和过滤一次。它不会再次进入循环。

我怀疑问题在于我不理解惰性求值或值传递。

最佳答案

问题不是惰性求值或递归箭头;而是问题。相反,filterLowPassburst 上表现不佳:在burst 结束后它变成 NaN

我们可以通过运行它来看到这一点,例如在 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]

我强烈怀疑这是因为burst本身在接近结束时表现得很奇怪:

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

我的建议是修复burst,这样它就不会在末尾生成NaN,然后看看是否可以解决所有问题。 0/-0 振荡可能是无害的。

尝试修复

我对 Euterpea 或声音合成一无所知;然而,通过对burstEnv使用非常短但非0的从1到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

关于haskell - Karplus-Strong Algo 中的递归反馈 - 箭头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33490143/

相关文章:

haskell - 带约束的箭头的可重新绑定(bind)语法

haskell - fun 声明中的类型错误

haskell - '@' 在 Haskell 中是什么意思?

sqlite - 将 ReaderT 和 runReaderT 与 SQLite 一起使用?

haskell - 使用 Haskell 镜头库,我如何将 setter/getter 视为 `first class' ?

java - 如何合并并行处理 Observables,同时将同一 Observable 中的项目分组在一起

dart - 构建函数返回 null 有问题的小部件是 : StreamBuilder<Response>

java - RxJava 无法调用路由处理程序

haskell - 什么是箭头,我该如何使用它们?

generics - Haskell 中的泛型类型转换