问题描述
我试图建立一个波形发生器,获取audiofile振幅值,并在javascript中尽可能快地(快于实时)将它们显示在画布上。所以我使用OfflineAudioContext / webkitOfflineAudioContext,加载文件并开始分析。波形填充宽阔的画布。
我在processor.onaudioprocess函数中分析缓冲区。 (我猜这是它的工作方式?)
它在Firefox中正常工作,但我在Chrome中遇到了一个问题:它似乎跳过了很多分析完成它尽快工作,只返回一些坐标(如16)。
这里是jsfiddle:
<$ c $如果(!window.OfflineAudioContext){
if(!window.webkitOfflineAudioContext){
$('#output')。append('failed:no)创建音频上下文
audiocontext发现,改变浏览器');
}
window.OfflineAudioContext = window.webkitOfflineAudioContext;
}
// var context = new AudioContext();
var length = 15241583;
var samplerate = 44100;
var fftSamples = 2048;
var waveformWidth = 1920;
var context = new OfflineAudioContext(1,length,samplerate);
var source;
var splitter;
var analyzer;
var处理器;
var i = 0;
var average;
var max;
var coord;
processor = context.createScriptProcessor(fftSamples,1,1);
processor.connect(context.destination);
analyzer = context.createAnalyser();
analyser.smoothingTimeConstant = 0;
analyser.fftSize = fftSamples;
source = context.createBufferSource();
splitter = context.createChannelSplitter();
source.connect(splitter);
splitter.connect(analyzer,0,0);
analyser.connect(处理器);
context.oncomplete = function(){
$('#output')。append('< br /> complete');
}
var request = new XMLHttpRequest();
request.open('GET',http://www.mindthepressure.org/bounce.ogg,true);
request.responseType ='arraybuffer';
request.onload = function(){
$('#output')。append('loaded!');
context.decodeAudioData(request.response,function(buffer){
$('#output')。append('starting analysis< br />>');
processor.onaudioprocess =函数(e){
var data = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(data);
average = getAverageVolume(data);
max = Math。 (数学,数据);
coord = Math.min(average * 2,255);
coord = Math.round((max + coord)/ 2);
ctx.fillStyle = gradient;
ctx.fillRect(i,255-coord,1,255);
console.log(i +' - >'+ coord);
i ++;
}
source.buffer = buffer;
source.start(0);
context.startRendering();
},onError);
}
request.send();
函数onError(e){
$('#output')。append('error,check the console');
console.log(e);
}
函数getAverageVolume(array){
var values = 0;
var average;
var length = array.length; (var k = 0; k values + = array [k];
}
average =值/长度;
平均回报;
$ b $ p
$ b(这里是另一个版本,强制波形适合1920px宽,并生成为谁感兴趣的波形数据:)
我真的没有明白,chrome如何处理音频文件的每一部分?
感谢您的帮助! p>
解决方案Chrome在离线模式下的脚本处理器中存在一个bug。
i'm trying to build a waveform generator that get audiofile amplitudes values and display them to a canvas as quick as possible (faster than realtime) in javascript. so i use the OfflineAudioContext / webkitOfflineAudioContext , load the file and start the analyse. the waveform is to fill a wide canvas.
i analyse buffer in a processor.onaudioprocess function. (i guess it's the way it works ?)
it works fine in firefox but i've got an issue in chrome : it seems it "jumps" over much analyse to finish it works as soon as possible and only returns a few coordinates (something like 16).
here is the jsfiddle : http://jsfiddle.net/bestiole/95EBf/
// create the audio context if (! window.OfflineAudioContext) { if (! window.webkitOfflineAudioContext) { $('#output').append('failed : no audiocontext found, change browser'); } window.OfflineAudioContext = window.webkitOfflineAudioContext; } //var context = new AudioContext(); var length = 15241583; var samplerate = 44100; var fftSamples = 2048; var waveformWidth = 1920; var context = new OfflineAudioContext(1,length,samplerate); var source; var splitter; var analyser; var processor; var i=0; var average; var max; var coord; processor = context.createScriptProcessor(fftSamples, 1, 1); processor.connect(context.destination); analyser = context.createAnalyser(); analyser.smoothingTimeConstant = 0; analyser.fftSize = fftSamples; source = context.createBufferSource(); splitter = context.createChannelSplitter(); source.connect(splitter); splitter.connect(analyser,0,0); analyser.connect(processor); context.oncomplete = function(){ $('#output').append('<br />complete'); } var request = new XMLHttpRequest(); request.open('GET', "http://www.mindthepressure.org/bounce.ogg", true); request.responseType = 'arraybuffer'; request.onload = function(){ $('#output').append('loaded ! '); context.decodeAudioData(request.response, function(buffer) { $('#output').append('starting analysis<br />'); processor.onaudioprocess = function(e){ var data = new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(data); average = getAverageVolume(data); max = Math.max.apply(Math, data); coord = Math.min(average*2,255); coord = Math.round((max+coord)/2); ctx.fillStyle=gradient; ctx.fillRect(i,255-coord,1,255); console.log(i+' -> '+coord); i++; } source.buffer = buffer; source.start(0); context.startRendering(); }, onError); } request.send(); function onError(e) { $('#output').append('error, check the console'); console.log(e); } function getAverageVolume(array) { var values = 0; var average; var length = array.length; for (var k = 0; k < length; k++) { values += array[k]; } average = values / length; return average; }
(here is another version that forces waveform to fit in 1920px wide and generate a waveform data for who is interested : http://jsfiddle.net/bestiole/E3rSx/ )
i really dont get the point, how doesn't chrome treat every part of the audio file ?
thanks for any help !
解决方案Chrome has a bug in script processors in offline mode.
这篇关于OfflineAudioContext使用chrome进行FFT分析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!