Web audio api Web音频API的性能问题
我已经创建了一个简单的网络音频API脚本,流本地mp3,并有一个增益控制和3波段均衡器 这些节点的设置使得源连接到增益节点,然后狭缝到低通、带通和高通节点。这些节点中的每一个在连接到目的地之前都连接到增益。这是一个简单的等式(下图和代码) 这在配备i7和16GB RAM的Windows 8桌面上运行良好,但当我尝试在配备赛扬处理器和2GB RAM的Acer C7 Chromebook上运行此功能时,音频会变得混乱。听起来好像每个分割路径都不同步。听起来节奏也加快了。你可以在下面的youtube视频中看到/听到这一点 赛扬处理器应该能够轻松处理3波段均衡器。我能做些什么来防止这种情况发生?有没有人在低端硬件上遇到过类似的问题 一如既往地感谢您的回复。继续表现得很棒 注意:如果不分割音频源,音频播放效果良好Web audio api Web音频API的性能问题,web-audio-api,chromebook,Web Audio Api,Chromebook,我已经创建了一个简单的网络音频API脚本,流本地mp3,并有一个增益控制和3波段均衡器 这些节点的设置使得源连接到增益节点,然后狭缝到低通、带通和高通节点。这些节点中的每一个在连接到目的地之前都连接到增益。这是一个简单的等式(下图和代码) 这在配备i7和16GB RAM的Windows 8桌面上运行良好,但当我尝试在配备赛扬处理器和2GB RAM的Acer C7 Chromebook上运行此功能时,音频会变得混乱。听起来好像每个分割路径都不同步。听起来节奏也加快了。你可以在下面的youtube视
对于一个简单的3波段均衡器,我可能会建议尝试低架、峰值和高架的双四阶滤波器。通过这种方式,您可以消除所有这些额外的增益节点,因为这些滤波器类型接受增益值-并且您不必分割信号。过滤器只能串联连接 通过消除所有这些分裂并保持单一信号路径,您可以保证没有任何东西会失去同步
另外,当你并行连接时,你更有可能出现相位怪异。biQuad 1试图消除你的低点,但它们仍然存在于biQuad 2和biQuad 3中。因此,您的过滤器有点相互争斗。正如Kevin所说,使用LP/BP/HP过滤器并行实施低音/中音/高音控制不是一个好主意。相位变化会给谐波含量带来很多问题。工作起来很有魅力。我早该意识到这一点。非常感谢!此外,OP所描述的图形应该完美地运行,即使在土豆上也不会出现性能问题。我在这里做的图表是这个复杂度的500多倍(纯粹是节点数量),并且没有性能问题。
function setupChain(outNode) {
soundSource = context.createBufferSource();
soundSource.buffer = audioBuffer;
volumeNode = context.createGainNode();
volumeNode.gain.value = gainValue;
highPassFilter = context.createBiquadFilter();
highPassFilter.type = 1;
highPassFilter.frequency.value = 4000;
highPassGain = context.createGainNode();
highPassGain.gain.value = highValue;
medPassFilter = context.createBiquadFilter();
medPassFilter.type = 2;
medPassFilter.frequency.value = 2125;
medPassFilter.Q = 1.1333333333333333;
medPassGain = context.createGainNode();
medPassGain.gain.value = medValue;
lowPassFilter = context.createBiquadFilter();
lowPassFilter.type = 0;
lowPassFilter.frequency.value = 250;
lowPassGain = context.createGainNode();
lowPassGain.gain.value = lowValue;
// Wiring
volumeNode.connect(lowPassFilter);
lowPassFilter.connect(lowPassGain);
lowPassGain.connect(outNode);
volumeNode.connect(medPassFilter);
medPassFilter.connect(medPassGain);
medPassGain.connect(outNode);
volumeNode.connect(highPassFilter);
highPassFilter.connect(highPassGain);
highPassGain.connect(outNode);
return volumeNode;
}
function stopSound() {
if (source) {
source.noteOff(0);
}
}
function playSound() {
// source is global so we can call .noteOff() later.
source = context.createBufferSource();
source.buffer = audioBuffer;
source.loop = false;
source.connect(setupChain(context.destination));
source.noteOn(0); // Play immediately.
}
function initSound(arrayBuffer) {
context.decodeAudioData(arrayBuffer, function(buffer) {
// audioBuffer is global to reuse the decoded audio later.
audioBuffer = buffer;
var buttons = document.querySelectorAll('button');
buttons[0].disabled = false;
buttons[1].disabled = false;
}, function(e) {
console.log('Error decoding file', e);
});
}
var fileChangeEventListener = function(e) {
var reader = new FileReader();
reader.onload = function(e) {
initSound(this.result);
};
reader.readAsArrayBuffer(this.files[0]);
}