WebAudio:setTargetAtTime 的异常行为?
WebAudio: Irregular behavior of setTargetAtTime?
下面的代码(also live here) seems to demonstrate inconsistent performance from setTargetAtTime... it "should" swell to maximum at 2 seconds, then fade to silence at 7 seconds, then terminate the oscillator at 12 seconds (safely quiet enough to avoid "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>
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
。
下面的代码(also live here) seems to demonstrate inconsistent performance from setTargetAtTime... it "should" swell to maximum at 2 seconds, then fade to silence at 7 seconds, then terminate the oscillator at 12 seconds (safely quiet enough to avoid "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>
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
。