Javascript 网络音频“;点击";即使在使用指数RamptoValueTime时也会发出声音

Javascript 网络音频“;点击";即使在使用指数RamptoValueTime时也会发出声音,javascript,web-audio-api,Javascript,Web Audio Api,我试图避免停止振荡器时发出难听的“咔嗒”声,因此我决定尝试使用指数RamptoValueAttime进行一些淡出。像这样: var playButton=document.getElementById('play'); var stopButton=document.getElementById('stop'); var context=新的AudioContext(); var gainNode=context.createGain(); var振荡器=context.create振荡器()

我试图避免停止振荡器时发出难听的“咔嗒”声,因此我决定尝试使用
指数RamptoValueAttime
进行一些淡出。像这样:

var playButton=document.getElementById('play');
var stopButton=document.getElementById('stop');
var context=新的AudioContext();
var gainNode=context.createGain();
var振荡器=context.create振荡器();
连接(context.destination);
振荡器。连接(增益节点);
gainNode.gain.setValueAtTime(1,context.currentTime);
start();

增益节点增益指数RamptoValueAttime(0.0001,context.currentTime+1)问题在于,渐变是从先前的计划值开始的,在这种情况下,是在按下播放按钮时完成的。如果在安排渐变之前再次设置该值,您将再次获得平滑过渡

var playButton=document.getElementById('play');
var stopButton=document.getElementById('stop');
var context=新的AudioContext();
var gainNode=context.createGain();
无功振荡器;
连接(context.destination);
playButton.addEventListener('click',function(){
振荡器=context.create振荡器();
振荡器。连接(增益节点);
gainNode.gain.setValueAtTime(1,context.currentTime);
start();
},假);
stopButton.addEventListener('click',函数(){
gainNode.gain.setValueAtTime(gainNode.gain.value,context.currentTime);
增益节点增益指数RamptoValueAttime(0.0001,context.currentTime+1);
setTimeout(函数(){
振荡器。停止();
}, 1000)
},假)
播放

停止
我还建议在playButton事件中使用坡道。在这种情况下,开始播放时也不会出现“单击”效果

var playButton=document.getElementById('play');
var stopButton=document.getElementById('stop');
var context=新的AudioContext();
var gainNode=context.createGain();
无功振荡器;
var rampDuration=0.3;
连接(context.destination);
playButton.addEventListener('click',function(){
振荡器=context.create振荡器();
振荡器。连接(增益节点);
gainNode.gain.setValueAtTime(0.0001,context.currentTime);
gainNode.gain.exponentialRampToValueAtTime(1,context.currentTime+rampDuration);
start();
},假);
stopButton.addEventListener('click',函数(){
gainNode.gain.setValueAtTime(gainNode.gain.value,context.currentTime);
增益节点增益指数RampToValueAttime(0.0001,context.currentTime+rampDuration);
setTimeout(函数(){
振荡器。停止();
},持续时间*1000)
},假)
播放

停止
哇,谢谢,这正是我想要的。我还是不明白为什么。。。“渐变是根据以前的计划值完成的”,为什么不考虑在“播放”按钮中完成计划?为什么还必须在“停止”按钮中再次设置它?是的,我可以理解为什么它令人困惑。:)因此,所发生的是,它看到发生的最后一个事件是播放侦听器中的setValueAtTime。该事件发生在当时上下文的当前时间。指数RAMPTOVALUEATTIME的设计目的是,它采用时间轴上发生的最后一个事件的时间,然后从该时间点到作为参数提供的时间形成一条曲线。API规范实际上对此有很好的可视化;