我正在尝试使用webaudio和canvas生成类似于音频编辑应用程序的静态波形。现在我正在加载一个mp3,创建一个缓冲区,迭代getChannelData返回的数据。
问题是......我真的不明白回来了什么。
为什么~50%的值是负数?
ctx.decodeAudioData(req.response, function(buffer) {
buf = buffer;
src = ctx.createBufferSource();
src.buffer = buf;
//create fft
fft = ctx.createAnalyser();
var data = new Uint8Array(samples);
fft.getByteFrequencyData(data);
bufferL = buf.getChannelData(0)
for(var i = 0; i<buf.length; i++){
n = bufferL[i*(1000)]
gfx.beginPath();
gfx.moveTo(i +0.5, 300);
gfx.lineTo(i +0.5, 300 + (-n*100));
gfx.stroke();
我正在产生什么:
我想要产生的内容:
由于
答案 0 :(得分:7)
我写了一个样本来做这个 - https://github.com/cwilso/Audio-Buffer-Draw。这是一个非常简单的演示 - 你必须自己进行缩放,但这个想法就在那里。
1)是的,getChannelData返回该频道的音频缓冲区样本。 2)嗯,这取决于样品中峰的频率,并且不一定一致。我所做的抽取样本确实缩小了(这是方法的第34步),但您可能希望针对您的方案进行优化。 3)一半的值是负的,因为声音样本介于-1和+1之间。声波是正负压波;这就是为什么&#34;沉默&#34;是中间的扁平线,而不是底部。
代码:
var audioContext = new AudioContext();
function drawBuffer( width, height, context, buffer ) {
var data = buffer.getChannelData( 0 );
var step = Math.ceil( data.length / width );
var amp = height / 2;
for(var i=0; i < width; i++){
var min = 1.0;
var max = -1.0;
for (var j=0; j<step; j++) {
var datum = data[(i*step)+j];
if (datum < min)
min = datum;
if (datum > max)
max = datum;
}
context.fillRect(i,(1+min)*amp,1,Math.max(1,(max-min)*amp));
}
}
function initAudio() {
var audioRequest = new XMLHttpRequest();
audioRequest.open("GET", "sounds/fightclub.ogg", true);
audioRequest.responseType = "arraybuffer";
audioRequest.onload = function() {
audioContext.decodeAudioData( audioRequest.response,
function(buffer) {
var canvas = document.getElementById("view1");
drawBuffer( canvas.width, canvas.height, canvas.getContext('2d'), buffer );
} );
}
audioRequest.send();
}
window.addEventListener('load', initAudio );