简体   繁体   English

使用 Web 音频 API 平滑音量变化

[英]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 the AudioParam Interface schedules a gradual exponential change in the value of the AudioParam . AudioParam接口的exponentialRampToValueAtTime()方法调度AudioParam值的逐渐指数变化。 The change starts at the time specified for the previous event , follows an exponential ramp to the new value given in the value parameter, and reaches the new value at the time given in the endTime 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM