问题描述
我正在使用klank.dev构建一个简单的Karplus Strong字符串效果。它可以正常工作直到中间C上方的F左右,但不能再高一些。该示例粘贴在下面,您也可以尝试here(空白仅适用于Firefox atm)。
有问题的行是del: Tuple (g'delay 0.00305) (SProxy :: SProxy "combine")
。如果您将延迟时间延长,例如0.009
,则延迟会降低。但是,如果您将其缩短,即0.002
,则在某一点音调将停止上升。
网络音频对反馈循环中使用的延迟是否有严格的下限限制? MDN报告最小值为0.0
,该最小值在未用于反馈中时有效,但在反馈循环中我遇到了这个问题。感谢您提供任何见解!
module A.Felicidade.Pluck where
import Prelude
import Data.Symbol (SProxy(..))
import Data.Tuple (Tuple(..))
import Data.Typelevel.Num (D1)
import FRP.Behavior (Behavior)
import FRP.Behavior.Audio (AudioUnit,audioWorkletGenerator,g'add,g'delay,g'gain,graph,runInbrowser,speaker')
import Foreign.Object as O
import Record.Extra (SLProxy(..),SNil)
import Type.Data.Graph (type (:/))
import Math(pi,sin,cos)
import Type.Klank.Dev (Klank,Worklets,klank)
worklets :: Worklets
worklets _ res rej =
( do
res [ "https://klank-share.s3.eu-west-1.amazonaws.com/K16029410960343210.js" ]
)
scene :: Number -> Behavior (AudioUnit D1)
scene time =
pure
$ speaker'
( graph
{ aggregators:
{ out: Tuple g'add (SLProxy :: SLProxy ("combine" :/ SNil)),combine: Tuple g'add (SLProxy :: SLProxy ("gain" :/ "mic" :/ SNil)),gain: Tuple (g'gain 0.9) (SLProxy :: SLProxy ("del" :/ SNil))
},processors:
{ del: Tuple (g'delay 0.00305) (SProxy :: SProxy "combine")
},generators:
{ mic:
audioWorkletGenerator
"klank-lf-burst"
(O.union (O.singleton "nsamples" 15.0) (O.singleton "freq" 1.0))
}
}
) where rad = time * pi
main :: Klank
main =
klank
{ run = runInbrowser scene,worklets = worklets
}
解决方法
循环(周期)中的DelayNode
的延迟被限制为最少1个渲染量子。参见https://webaudio.github.io/web-audio-api/#DelayNode-attributes。一个渲染量子的时间为128 / sampleRate。对于44.1 kHz的采样率大约需要3毫秒。
无法解决此问题,因为WebAudio(当前)以128帧的块工作,如果有循环,则所有块在产生输出之前都需要128帧。
我知道的唯一解决方案是使用AudioWorklet实现图形中处于循环中的部分。这样可以有效地消除图形的循环,因此您可以执行任何操作。