如何控制(音频缓冲区)AudioContext() 的音量?
Posted
技术标签:
【中文标题】如何控制(音频缓冲区)AudioContext() 的音量?【英文标题】:How to control the sound volume of (audio buffer) AudioContext()? 【发布时间】:2017-04-13 07:38:31 【问题描述】:我在 javascript 中有以下 AudioContext() 声音对象。 它的音量是 100%。我想以 10% 的音量播放(其中音量 = 0.1)。 我怎样才能将它的音量减少到 10%?
const aCtx = new AudioContext();
let source = aCtx.createBufferSource();
let buf;
fetch('https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav') // can be XHR as well
.then(resp => resp.arrayBuffer())
.then(buf => aCtx.decodeAudioData(buf)) // can be callback as well
.then(decoded =>
source.buffer = buf = decoded;
source.loop = true;
source.connect(aCtx.destination);
check.disabled = false;
);
check.onchange = e =>
if (check.checked)
source.start(0); // start our bufferSource
else
source.stop(0); // this destroys the buffer source
source = aCtx.createBufferSource(); // so we need to create a new one
source.buffer = buf;
source.loop = true;
source.connect(aCtx.destination);
;
<label>Start Playing</label>
<input type="checkbox" id="check" disabled><br>
<br>Its volume is 100%. Please help me to reduce it to 10%.
【问题讨论】:
所以我在这里认出了my code,如果你完整地阅读了答案,你会看到在第二个sn-p中我使用了gainNode,它会给你控制权在输出音量上。 【参考方案1】:我们使用GainNodes来控制音量。
var gainNode = aCtx.createGain()
gainNode.gain.value = 0.1 // 10 %
gainNode.connect(aCtx.destination)
// now instead of connecting to aCtx.destination, connect to the gainNode
source.connect(gainNode)
解决方案
const aCtx = new AudioContext();
const gainNode = aCtx.createGain();
gainNode.gain.value = 0.1; // setting it to 10%
gainNode.connect(aCtx.destination);
let source = aCtx.createBufferSource();
let buf;
fetch('https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav') // can be XHR as well
.then(resp => resp.arrayBuffer())
.then(buf => aCtx.decodeAudioData(buf)) // can be callback as well
.then(decoded =>
source.buffer = buf = decoded;
source.loop = true;
source.connect(gainNode);
check.disabled = false;
);
check.onchange = e =>
if (check.checked)
source.start(0); // start our bufferSource
else
source.stop(0); // this destroys the buffer source
source = aCtx.createBufferSource(); // so we need to create a new one
source.buffer = buf;
source.loop = true;
source.connect(gainNode);
;
<label>Start Playing</label>
<input type="checkbox" id="check" disabled><br>
<br>Its volume is 100%. Please help me to reduce it to 10%.
【讨论】:
@Kaiido 谢谢。应该看到的。我也很痛……现在我看到了。【参考方案2】:您可以为此目的使用 AudioContext 的 createGain。
如下图,
欲了解更多信息,请查看createGain
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain
const aCtx = new AudioContext();
let source = aCtx.createBufferSource();
let buf;
var gainNode = aCtx.createGain(); // Create a gainNode reference.
gainNode.connect(aCtx.destination); // Add context to gainNode
fetch('https://dl.dropboxusercontent.com/s/knpo4d2yooe2u4h/tank_driven.wav') // can be XHR as well
.then(resp => resp.arrayBuffer())
.then(buf => aCtx.decodeAudioData(buf)) // can be callback as well
.then(decoded =>
source.buffer = buf = decoded;
source.loop = true;
source.connect(gainNode); //Connecting gain to source
gainNode.gain.value = 1; // 100% VOLUME RANGE OF VALUE IS 0-1
check.disabled = false;
);
check.onchange = e =>
if (check.checked)
source.start(0); // start our bufferSource
else
source.stop(0); // this destroys the buffer source
source = aCtx.createBufferSource(); // so we need to create a new one
source.buffer = buf;
source.loop = true;
source.connect(gainNode); //Connecting gain to source
gainNode.gain.value = 0.1; // 10% VOLUME RANGE OF VALUE IS 0-1
;
【讨论】:
你也需要在check.onchange中把buffer source连接到gainNode,否则第二次修改后就不行了 您不需要将 gainNode 重新连接到上下文,只需执行一次,例如在 gloabl 范围内。您还仍然将缓冲区直接连接到上下文的目的地,这一点都不好。 这只是为了演示使用 gainNode 来控制音量,可以通过多种方式进行优化。 我不是在谈论优化。您的代码不起作用,在 gainNode 演示的范围内。只需尝试将其 gain.value 设置为低于 1,您就会看到,由于您将缓冲区源直接连接到音频上下文,因此该缓冲区源仍将以音量 1 播放。=> 只需删除所有source.connect(aCtx.destination);
这不是我添加的代码的一部分。检查问题。以上是关于如何控制(音频缓冲区)AudioContext() 的音量?的主要内容,如果未能解决你的问题,请参考以下文章
尝试运行 AudioContext.createMediaElementSource() 时如何解决“音频无法识别调用‘连接’的对象”错误?