WebAudio:setTargetAtTime的不规则行为?

时间:2017-10-25 02:47:43

标签: javascript web-audio

下面的代码(also live here)似乎表明来自setTargetAtTime的性能不一致...它应该“2”时膨胀到最大值,然后在7秒时淡入静音,然后在12秒时终止振荡器(安全安静,以避免"the ugly click"。)

相反,它在2秒时膨胀到最大值,然后开始淡化,但在12秒时尚未完成,此时我们确实听到了丑陋的咔哒声。

任何人都可以解释为什么会这样吗?请注意,较短的值(注释为//0.3)会快速降低它以避免点击。我已经在各种情况下尝试过这种情况,看起来好像(无论如何渐渐变为0)第三个参数随着值的增加而按比例延伸超出正确的停止时间。

<button id = "button" >
Start then stop oscillators
</button>

<script>
var audioContext = new AudioContext();
var fadeIn = 2;
var fadeOut = 5; //0.3
var gainNode = audioContext.createGain();
var osc = audioContext.createOscillator();
osc.type = "sine";
osc.frequency.value = 300;
osc.connect(gainNode);
gainNode.gain.value = 0;
gainNode.connect(audioContext.destination);

function startAndStop() {
    osc.start(audioContext.currentTime);
    gainNode.gain.setTargetAtTime(1, audioContext.currentTime, fadeIn);    
    gainNode.gain.setTargetAtTime(0, audioContext.currentTime + fadeIn, fadeOut);
    osc.stop(audioContext.currentTime + fadeIn + fadeOut + 5);
};

var button = document.getElementById("button");
button.addEventListener("click", startAndStop);

</script>

1 个答案:

答案 0 :(得分:1)

setTargetAtTime的第三个参数不是时间参数,所以不,它不应该在2秒时膨胀到最大值,然后在7秒时淡出到静音,然后在12秒时终止振荡器

此参数设置值将更改的指数衰减率

因此,值为5会产生非常缓慢的衰减,如此缓慢以至于当达到t'时它将无法完成。

时间应在第二个参数中完成。

使用0.5的固定衰减率修复代码会删除点击:

var audioContext = new AudioContext();

var fadeIn = 2;
var fadeOut = 5;

var gainNode = audioContext.createGain();
var osc = audioContext.createOscillator();
osc.type = "sine";
osc.frequency.value = 300;
osc.connect(gainNode);
gainNode.gain.value = 0;
gainNode.connect(audioContext.destination);

function startAndStop() {
  osc.start(audioContext.currentTime);
  gainNode.gain.setTargetAtTime(1, audioContext.currentTime + fadeIn, 0.5);
  gainNode.gain.setTargetAtTime(0, audioContext.currentTime + fadeOut, 0.5);
  osc.stop(audioContext.currentTime + fadeIn + fadeOut + 5);
};

var button = document.getElementById("button");
button.addEventListener("click", startAndStop);
<button id="button">
Start then stop oscillators
</button>

但实际上,您似乎想要使用linearRampValueAtTime而不是setTargetAtTime