Web音频振荡器意外地滑翔从一个频率到另一个在Chrome

Web Audio oscillators unexpectedly glide from one frequency to another in Chrome

本文关键字:一个 频率 Chrome 另一个 意外 振荡器 音频 Web      更新时间:2023-09-26

我即将描述的行为发生在Chrome 44中,但是在Firefox 40中发生吗?

如果你创建一个振荡器,将其设置为220赫兹的频率,然后在一秒钟后将频率更改为440赫兹,你可以听到一个明显的portamento效果:而不是立即从220到440,振荡器从原始频率滑动到新的频率。

下面的代码说明了这种现象:

var ac = new AudioContext();
var osc = ac.createOscillator();
osc.connect( ac.destination );
osc.type = 'sawtooth';
osc.frequency.value = 220;
osc.start( 0 );
window.setTimeout( function() {
    osc.frequency.value = 440;
}, 1000 );
window.setTimeout( function() {
    osc.stop( 0 );
}, 2000 );

我已经检查了有关OscillatorNode对象的文档,没有提到这种行为。

我也搜索了谷歌,(令人惊讶的是)我找不到任何关于这种现象的其他提及。

怎么回事?这看起来不像是正确的行为。如果我想让频率滑动,我将使用linearRampToValueAtTime()方法。将频率直接设置为特定值应该只是…这样做。

这只是一个bug吗?我知道这个API仍在不断变化,但这似乎是一个非常明显的错误——这不会通过最粗略的测试。但是我也无法想象Google会故意这么做

最重要的是:是否有解决方法?

很确定这是一个bug。

我在规范中找不到任何说valueAudioParam上的直接赋值应该做任何形式的插值。

有可能它没有被注意到,因为通常人们可能会使用自动化方法修改值。这让我想到了你的解决办法的问题…

如果你真的想要显式延迟,你可以这样做(注意没有setTimeout)。

// change the value to 440Hz 1 second from now
osc.frequency.setValueAtTime( 440, ac.currentTime + 1 );

如果您希望能够立即改变频率(例如,响应用户操作),您可以这样做:

osc.frequency.setValueAtTime( 440, 0 );

希望对你有帮助。

顺便说一下,您应该考虑为此提交一个问题(https://code.google.com/p/chromium/issues/list)。

这是内置的" dezipppers "效果,工作组已经在这方面来回进行了几次。到了6月,WG终于决定取消去拉链(状态:https://github.com/WebAudio/web-audio-api/issues/76)。所以,是的,这是一个Chrome"bug"- https://code.google.com/p/chromium/issues/detail?id=496282)。在修复之前,请按照Kevin的建议使用setValueAtTime()。