[英]Smooth volume change with Web Audio API
javascript newbie here. javascript 新手在这里。 So I've been messing around with the Web Audio API trying to figure stuff out and I found that exponentialRampToValueAtTime does just what I want except it only seems to do it once(?) Take this generic code:
所以我一直在搞乱 Web 音频 API 试图弄清楚事情,我发现exponentialRampToValueAtTime正是我想要的,除了它似乎只做一次(?)拿这个通用代码:
context = new AudioContext();
oscillator = context.createOscillator();
contextGain = context.createGain();
oscillator.type = 'sine';
oscillator.frequency = 440
oscillator.connect(contextGain);
contextGain.connect(context.destination);
oscillator.start(0);
contextGain.gain.value = 1 by default so if I run contextGain.gain.exponentialRampToValueAtTime(0.1,context.currentTime + 2)
it drops nice and smoothly from 1 to 0.1.默认情况下 contextGain.gain.value = 1 所以如果我运行
contextGain.gain.exponentialRampToValueAtTime(0.1,context.currentTime + 2)
它会从 1 平稳地下降到 0.1。 But if I try to get it back at 1, say contextGain.gain.exponentialRampToValueAtTime(1,context.currentTime + 2)
it instead jumps suddenly to 1. Why does this happen?但是如果我试图让它回到 1,比如
contextGain.gain.exponentialRampToValueAtTime(1,context.currentTime + 2)
它会突然跳到 1。为什么会发生这种情况? Is there any way I can do this ramp as many times as I want?有什么方法可以让我想多少次就做多少次? Thanks in advance.
提前致谢。
You need to call setValueAtTime()
first to mark beginning of a change:您需要先调用
setValueAtTime()
来标记更改的开始:
contextGain.gain.setValueAtTime(contextGain.gain.value, context.currentTime);
contextGain.gain.exponentialRampToValueAtTime(0.1, context.currentTime + 2);
Without this, your gradual change starts in the past.没有这个,你的渐进变化就从过去开始。
This is needed because the gradual change of an audio param starts from the previous event .这是必要的,因为音频参数的逐渐变化是从前一个事件开始的。 That previous event is a previous gain change using the methods
setValueAtTime()
, linearRampToValueAtTime()
, exponentialRampToValueAtTime()
, etc.先前的事件是使用
setValueAtTime()
、 linearRampToValueAtTime()
、 exponentialRampToValueAtTime()
等方法的先前增益变化。
Quote from the documentation at MDN :引用MDN 上的文档:
The
exponentialRampToValueAtTime()
method of theAudioParam
Interface schedules a gradual exponential change in the value of theAudioParam
.AudioParam
接口的exponentialRampToValueAtTime()
方法调度AudioParam
值的逐渐指数变化。 The change starts at the time specified for the previous event , follows an exponential ramp to the new value given in thevalue
parameter, and reaches the new value at the time given in theendTime
parameter.更改从前一个事件指定的时间开始,按照指数斜坡上升到
value
参数中给定的新值,并在endTime
参数中给定的时间达到新值。
Here is small demo:这是一个小演示:
var context = new AudioContext(); var oscillator = context.createOscillator(); var gain = context.createGain(); oscillator.type = 'sine'; oscillator.frequency = 440 oscillator.connect(gain); gain.connect(context.destination); document.getElementById('bplay').addEventListener('click', function() { context.resume(); oscillator.start(0); gain.gain.setValueAtTime(0.01, context.currentTime); gain.gain.exponentialRampToValueAtTime(1, context.currentTime + 2); }); document.getElementById('bdown').addEventListener('click', function() { gain.gain.cancelScheduledValues(context.currentTime); gain.gain.setValueAtTime(gain.gain.value, context.currentTime); gain.gain.exponentialRampToValueAtTime(0.01, context.currentTime + 2); }); document.getElementById('bup').addEventListener('click', function() { gain.gain.cancelScheduledValues(context.currentTime); gain.gain.setValueAtTime(gain.gain.value, context.currentTime); gain.gain.exponentialRampToValueAtTime(1, context.currentTime + 2); });
<button type="button" id="bplay">Play</button> <button type="button" id="bdown">Volume down</button> <button type="button" id="bup">Volume up</button>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.