[英]How to fix sound multiple oscillators playing at the same time with javascript web audio api
我正在构建一个同时播放多个振荡器的声音装置(在给定时间最多会有 5/6 个振荡器播放)。 它在 Firefox 和 Chrome 的桌面上正常工作,但在 Safari 中,如果我一次播放多个振荡器,它会发出可怕的“kkrkrkrkrkrkrkrkrkr”声音。 我用同一台电脑测试过,所以这不是扬声器的问题。 在电话上,它适用于 iphone,但在 android 上,如果有更多的振荡器,无论我使用什么浏览器,它都会产生相同的“krkrkrkr”效果。 安装的最终目标是在手机上显示,我无法控制将使用哪些浏览器
这是代码的简化版本
let audioContext;
let touchEvent = 'ontouchstart' in window ? 'touchstart' : 'click';
let oscillators = [];
window.addEventListener(touchEvent, makeSound);
function makeSound(){
audioContext = new (window.AudioContext || window.webkitAudioContext)();
createOsc(43.653528929125486);
createOsc(220);
createOsc(164.81377845643496);
currentTime = audioContext.currentTime;
oscillators.forEach(function(oscillator){
currentTime = audioContext.currentTime;
oscillator.start(currentTime);
oscillator.stop(currentTime + 2);
});
}
function createOsc(freq){
oscillator = audioContext.createOscillator();
oscillator.frequency.value = freq;
oscillator.connect(audioContext.destination);
oscillators.push(oscillator);
}
我试过使用 ChannelMergerNode 但它没有改变任何东西
Chrome/Firefox 和 Safari 在处理超出 -1 到 +1 范围的信号的方式上似乎有所不同。
如果连接所有三个振荡器,理论上信号可以达到最大值 -3 和 +3。
如果您通过添加增益约为 0.333(1 / 振荡器数量)的 GainNode 确保信号始终保持在 -1 到 +1 的范围内,则所有浏览器听起来都一样。
我更新了您的代码片段以添加这样的 GainNode:
let audioContext;
let gainNode;
let touchEvent = 'ontouchstart' in window ? 'touchstart' : 'click';
let oscillators = [];
window.addEventListener(touchEvent, makeSound);
function makeSound(){
audioContext = new (window.AudioContext || window.webkitAudioContext)();
gainNode = audioContext.createGain();
gainNode.connect(audioContext.destination);
createOsc(43.653528929125486);
createOsc(220);
createOsc(164.81377845643496);
const currentTime = audioContext.currentTime;
oscillators.forEach(function(oscillator){
// The next line is probably not needed.
// currentTime = audioContext.currentTime;
oscillator.start(currentTime);
oscillator.stop(currentTime + 2);
});
}
function createOsc(freq){
const oscillator = audioContext.createOscillator();
oscillator.frequency.value = freq;
oscillator.connect(gainNode);
oscillators.push(oscillator);
gainNode.gain.value = 1 / oscillators.length;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.