我试图避免在停止振荡器时发出丑陋的“咔哒”声,所以我决定尝试使用exponentialRampToValueAtTime
进行一些淡出。像这样:
var playButton = document.getElementById('play');
var stopButton = document.getElementById('stop');
var context = new AudioContext();
var gainNode = context.createGain();
var oscillator = context.createOscillator();
gainNode.connect(context.destination);
oscillator.connect(gainNode);
gainNode.gain.setValueAtTime(1, context.currentTime);
oscillator.start();
gainNode.gain.exponentialRampToValueAtTime(0.0001, context.currentTime + 1);
效果很好,没有“咔嗒”声,渐减光滑。但是,只要我使用按钮和事件监听器这样做,丑陋的点击就会回来,不知何故,斜坡下降更加粗野
顺便说一句,请在按下“停止”后等待1秒钟,然后重新按“播放”或发生丑陋的事情:)
var playButton = document.getElementById('play');
var stopButton = document.getElementById('stop');
var context = new AudioContext();
var gainNode = context.createGain();
var oscillator;
gainNode.connect(context.destination);
playButton.addEventListener('click', function() {
oscillator = context.createOscillator();
oscillator.connect(gainNode);
gainNode.gain.setValueAtTime(1, context.currentTime);
oscillator.start();
}, false);
stopButton.addEventListener('click', function() {
gainNode.gain.exponentialRampToValueAtTime(0.0001, context.currentTime + 1);
setTimeout(function(){
oscillator.stop();
}, 1000)
}, false);
<button id="play">play</button>
<button id="stop">stop</button>
我在这里显然缺少一些理论。除了听众之外,代码非常相似,两个片段的结果在质量上有很大差异。你能解释一下这个差异来自哪里吗?
使用按钮/听众时,有没有办法实现第一个片段质量?
谢谢!
答案 0 :(得分:6)
问题是斜坡是从先前安排的值完成的,在这种情况下是按下播放按钮的时间。如果在安排斜坡之前再次设置该值,您将再次获得平滑过渡!
var playButton = document.getElementById('play');
var stopButton = document.getElementById('stop');
var context = new AudioContext();
var gainNode = context.createGain();
var oscillator;
gainNode.connect(context.destination);
playButton.addEventListener('click', function() {
oscillator = context.createOscillator();
oscillator.connect(gainNode);
gainNode.gain.setValueAtTime(1, context.currentTime);
oscillator.start();
}, false);
stopButton.addEventListener('click', function() {
gainNode.gain.setValueAtTime(gainNode.gain.value, context.currentTime);
gainNode.gain.exponentialRampToValueAtTime(0.0001, context.currentTime + 1);
setTimeout(function(){
oscillator.stop();
}, 1000)
}, false);
<button id="play">play</button>
<button id="stop">stop</button>
答案 1 :(得分:0)
我还建议为 playButton 事件使用斜坡。在这种情况下,开始播放时也不会出现“点击”效果。
var playButton = document.getElementById('play');
var stopButton = document.getElementById('stop');
var context = new AudioContext();
var gainNode = context.createGain();
var oscillator;
var rampDuration = 0.3;
gainNode.connect(context.destination);
playButton.addEventListener('click', function() {
oscillator = context.createOscillator();
oscillator.connect(gainNode);
gainNode.gain.setValueAtTime(0.0001, context.currentTime);
gainNode.gain.exponentialRampToValueAtTime(1, context.currentTime + rampDuration);
oscillator.start();
}, false);
stopButton.addEventListener('click', function() {
gainNode.gain.setValueAtTime(gainNode.gain.value, context.currentTime);
gainNode.gain.exponentialRampToValueAtTime(0.0001, context.currentTime + rampDuration);
setTimeout(function(){
oscillator.stop();
}, rampDuration*1000)
}, false);
<button id="play">play</button>
<button id="stop">stop</button>