我使用振荡器节点创建声音,并希望在画布上绘制频率可视化。当振荡器正在播放时,可视化效果如下所示(标准振荡器设置,请参见下面的代码)。 http://i58.tinypic.com/wtvwgz.png
振荡器停止播放后(完全沉默!),这就是我得到的。确切的结果会在不同运行之间发生变化,有时这些值甚至会在停止后略有变化。 http://i62.tinypic.com/2duji81.png
我不明白为什么当声音没有播放时,所有音箱的频率数据都不为零。
在Firefox 30.0和Iron 34.0.1850.0(Chrome)上测试
这是我的示例代码:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
window.onload = function () {
var ctx = document.getElementById("canvas").getContext("2d");
var audioContext = new (window.AudioContext
|| window.webkitAudioContext || window.mozAudioContext)();
var analyser = audioContext.createAnalyser();
analyser.fftSize = 512;
analyser.connect(audioContext.destination);
var frequencyBins = new Uint8Array(analyser.frequencyBinCount);
var osc = audioContext.createOscillator();
osc.connect(analyser);
osc.start(audioContext.currentTime + 2);
osc.stop(audioContext.currentTime + 4);
var WIDTH = 512;
var HEIGHT = 100;
var value, h, w;
function draw() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
for (var i = 0; i < frequencyBins.length; i++) {
value = frequencyBins[i];
h = HEIGHT * (value / 255);
w = WIDTH / frequencyBins.length;
ctx.fillRect(i * w, HEIGHT - 1, w, -h);
}
};
function animate() {
analyser.getByteFrequencyData(frequencyBins);
draw();
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
};
</script>
</head>
<body>
<canvas id="canvas" width="512" height="100"></canvas>
</body>
</html>
答案 0 :(得分:3)
我找到了一个适合我的解决方案。
不是将振荡器直接连接到分析仪,而是首先通过高通滤波器传递频率。看起来截止频率的值可以设置为任意低,只要它不是0.即使截止值为0.00000001,在静默期间可视化也将为空白。
var analyser = audioContext.createAnalyser();
analyser.fftSize = 512;
analyser.connect(audioContext.destination);
var frequencyBins = new Uint8Array(analyser.frequencyBinCount);
var filter = audioContext.createBiquadFilter();
filter.type = "highpass";
filter.frequency.value = 0.0001;
filter.connect(analyser);
var osc = audioContext.createOscillator();
osc.connect(filter);
osc.start(audioContext.currentTime + 2);
osc.stop(audioContext.currentTime + 4);
答案 1 :(得分:0)
遇到相同的问题后,我尝试过:
虽然我使用2K高通/布莱克曼组合获得了最佳结果,但是冻结仍然持续。
最后,我还必须调整分析仪的最小/最大dB设置。我最初将min / max dB设置为-100/0。
从直觉上讲,增加分析仪的响应范围可以解决此问题。我认为它可以追溯到FFT算法中的量化。
注意:
高通滤波器使整体处理开销加倍:(
虽然我还发现将smoothingTimeConstant更改为接近1.0的值可以解决冻结问题,但同时也会导致分析仪的响应滞后(过于平滑)。
答案 2 :(得分:-1)
我遇到了同样的问题。它是analyserNode.smoothingTimeConstant,默认情况下它具有非常高的值。尝试 analyserNode.smoothingTimeConstant = 0; //或0.2 它会修复它