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

gre*_*600 6 javascript web-audio-api

我将要描述的行为发生在Chrome 44中,但在Firefox 40 中不会发生.

如果您创建一个振荡器,将其设置为220 Hz的频率,然后在一秒钟后将频率更改为440 Hz,您可以听到明显的滑音效果:不是立即从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 );
Run Code Online (Sandbox Code Playgroud)

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

我也搜过谷歌,(令人惊讶的是)我找不到任何其他提及这种现象.

这是怎么回事?这似乎不是正确的行为.如果我想让频率滑动,我会使用linearRampToValueAtTime()方法.将频率直接设置为特定值应该......做到这一点.

这只是一个错误吗?我知道这个API仍在不断变化,但这似乎是一个明显的错误 - 这不会通过最粗略的测试.但我也无法想象谷歌会故意以这种方式实施它.

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

Kev*_*nis 4

很确定这是一个错误。

我在规范中找不到任何说明valueon的直接赋值AudioParam应该进行任何类型的插值的内容。

它可能会被忽视,因为通常人们可能会使用自动化方法修改该值。这让我想到了你的解决方法问题......

如果您确实想要明确的延迟,您可以这样做(注意没有setTimeout)。

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

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

osc.frequency.setValueAtTime( 440, 0 );
Run Code Online (Sandbox Code Playgroud)

希望有帮助。

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