OfflineAudioContext使用chrome进行FFT

OfflineAudioContext使用chrome进行FFT

本文介绍了OfflineAudioContext使用chrome进行FFT分析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图建立一个波形发生器,获取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分析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 01:44