音量控制与Web音频API
Volume control with Web Audio API
我正在做一个简单的项目来创建一个乐器,使用Web Audio API,并编写了以下代码片段(您可以按'Q'来播放音符):
var audio = new AudioContext();
var volume = 0;
var attack = 1;
var release = 1;
var carrier = audio.createOscillator();
carrier.frequency.value = 440.00;
carrier.type = "sine";
carrier.start();
var carrier_volume = audio.createGain();
carrier_volume.gain.linearRampToValueAtTime(volume, 0);
carrier.connect(carrier_volume);
carrier_volume.connect(audio.destination);
document.addEventListener("keydown", function(e) {
if(e.keyCode == 81) {
carrier_volume.gain.linearRampToValueAtTime(1, audio.currentTime + attack);
}
});
document.addEventListener("keyup", function(e) {
if(e.keyCode == 81) {
carrier_volume.gain.linearRampToValueAtTime(0, audio.currentTime + release);
}
});
(如果你不熟悉术语:'attack'是音符达到峰值所需的时间,在我的例子中是1秒,'release'是在有人释放键后逐渐消失所需的时间,在这个例子中也是1秒)
问题是这个"点击"的声音,你可以听到之前和之后的音符播放。我做了一些调查:
如何避免'点击'当我停止播放一个声音时,会发出声音吗?
http://modernweb.com/2014/03/31/creating-sound-with-the-web-audio-api-and-oscillators/,发现这是由切割声波引起的,所以我应该保持音符在0 dB播放,并根据需要提高/降低音量。然而,它只适用于特别是 Chrome ,只有如果我直接设置音量,像这样:carrier_volume.gain.value = 1
。它不工作,即使在Chrome中,如果我使用linearRampToValueAtTime()
功能。
如果我试图直接将初始音量设置为0,会发生其他奇怪的事情。在初始化时使用carrier_volume.gain.value = 0
,播放的第一个音符将被切断,但接下来的音符将正常播放。
是否有人找到了解决这个恼人的点击噪音和什么是延迟问题时使用gain.value
和linearRampToValueAtTime()
?
所以,这里是交易-一个linearRampToValueAtTime需要一个START时间。你想让它是"现在"——当键被按下的时候——但是你需要通过设置键被按下的当前值来明确它。此外,你不应该在创建时使用linearRamp -直接设置值。
如果你直接将初始音量设置为0(通过.value),它不应该完全切断,但第一个斜坡不会有一个起点-所以它将保持零,直到线性斜坡的时间过去,然后它将跳转到1。
试试这个:
var audio = new AudioContext();
var volume = 0;
var attack = 1;
var release = 1;
var carrier = audio.createOscillator();
carrier.frequency.value = 440.00;
carrier.type = "sine";
carrier.start();
var carrier_volume = audio.createGain();
carrier_volume.gain.linearRampToValueAtTime(volume, 0);
carrier.connect(carrier_volume);
carrier_volume.connect(audio.destination);
// remember whether we're playing or not; otherwise the keyboard repeat will confuse us
var playing = false;
document.addEventListener("keydown", function(e) {
if((e.keyCode == 81) && !playing) {
// first, in case we're overlapping with a release, cancel the release ramp
carrier_volume.gain.cancelScheduledValues(audio.currentTime);
// now, make sure to set a "scheduling checkpoint" of the current value
carrier_volume.gain.setValueAtTime(carrier_volume.gain.value,audio.currentTime);
// NOW, set the ramp
carrier_volume.gain.linearRampToValueAtTime(1, audio.currentTime + attack);
// Note that ideally, we would check the current value from above, and calculate
// the length of the attack based on it to keep a constant angle of the attack,
// rather than a constant time. (If we're half-way through a release when we
// start a new attack, the attack should only take 0.5s since we're already at 0.5.)
playing = true;
}
});
document.addEventListener("keyup", function(e) {
if((e.keyCode == 81) && playing) {
// first, in case we're overlapping with an attack, cancel the attack ramp
carrier_volume.gain.cancelScheduledValues(audio.currentTime);
// now, make sure to set a "scheduling checkpoint" of the current value
carrier_volume.gain.setValueAtTime(carrier_volume.gain.value,audio.currentTime);
// NOW, set the ramp
carrier_volume.gain.linearRampToValueAtTime(0, audio.currentTime + release);
// Note that ideally, we would check the current value from above, and calculate
// the length of the release based on it to keep a constant angle of the release,
// rather than a constant time. (If we're half-way through an attack when we
// start a new release, the release should only take 0.5s since we're already at 0.5.)
playing = false;
}
});
音量设置键
gainNode.gain.setValueAtTime(0.5, context.currentTime);
<button id="start">playSound</button>
const audioPlay = async url => {
const context = new AudioContext();
var gainNode = context.createGain();
const source = context.createBufferSource();
const audioBuffer = await fetch(url)
.then(res => res.arrayBuffer())
.then(ArrayBuffer => context.decodeAudioData(ArrayBuffer));
source.buffer = audioBuffer;
source.connect(gainNode);
gainNode.connect(context.destination);
gainNode.gain.setValueAtTime(0.5, context.currentTime); // volume, 0 means mute
source.start();
};
document.querySelector('#start').onclick = () => audioPlay('music/2.ogg');
- javascript函数包含两个元素和web音频api
- 网络音频API,设置高音和低音
- 从 Web SQL 数据库检索音频并使用 Web 音频 API 播放
- 环形缓冲区 - Web 音频 API
- 多个音频播放器和 Web 音频 API
- 使用 Web 音频 API 设置侦听器方向
- 如何通过API或JS组合视频和音频
- 如何使用JQueryUI滑块控制web音频API振荡器参数,而无需经过HTML表单参数
- 基于网络音频API的和弦检测算法
- iOS6/7使用网络音频API阻止声音进入背景
- 转换Web音频API中的采样率
- HTML5网络音频API wavesurfer.js在大型mp3文件上崩溃
- Web音频API 24db筛选器
- 用于直播的网络音频API
- 如何在使用网络音频api播放多种声音时消除噪音
- 如何使用 Web 音频 API 访问输出缓冲区
- 网络音频 API:声相音频(左/右)+ 控制增益
- 为什么这个声音在网络音频 API 中不断重新触发自己
- 使用 Web 音频 API 使用 start/noteOn 进行非法调用
- Web音频api音频文件抽象只识别初始播放时的预定时间.然后它会立即回放