2014-01-09 66 views
8

我試圖構建一個波形發生器,它可以獲取audiofile振幅值,並在javascript中儘可能快地將其顯示在畫布上(快於實時)。所以我使用OfflineAudioContext/webkitOfflineAudioContext,加載文件並開始分析。 波形是用來填充寬闊的畫布。OfflineAudioContext使用鉻進行FFT分析

我分析了processor.onaudioprocess函數中的緩衝區。 (我猜這是它的工作原理?)

它在Firefox中正常工作,但我有一個問題在鉻:它似乎「跳過」了很多分析,以儘快完成它的工作原理,只返回一個很少的座標(類似16)。

這裏是的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; 
} 

(這裏是另一個版本的勢力波形,以適應1920px寬和誰是有興趣產生的波形數據:http://jsfiddle.net/bestiole/E3rSx/

我真的不明白了,鉻沒有對待音頻文件的每一部分?

感謝您的任何幫助!

+0

也可以用Canary 34確認。如果當前的調用無法在給定的時間內完成,它似乎做了一個暴力,但這是一個猜測......如果您實時運行它(正常上下文),它的行爲如何? (將漸變fillStyle移動到全局範圍會產生更好的效果) – K3N

+0

它在實時環境中可以正常工作。感謝fillstyle技巧! – kro

回答

1

Chrome在離線模式下的腳本處理器中存在一個錯誤。

+0

我在safari中遇到同樣的問題,我想這是一個webkit/blink的東西。 這似乎由https://bugs.webkit.org/show_bug.cgi?id=113274和http://lists.w3.org/Archives/Public/public-au/20/2013JulSep/0110.html證實:主要音頻線程不會等待處理器在繼續處理下一個樣本幀之前計算其任務... 太糟糕了我找不到確認的錯誤報告了。 感謝您的回答 – kro

+0

你有沒有發現這個錯誤報告?在chrome v36中渲染振盪器時仍然存在問題。在最新的firefox v30中完美工作。 –

+0

Chromium中的錯誤報告,我真的需要這個工作,我想知道它什麼時候會解決:https://code.google.com/p/chromium/issues/detail?id=374339 – janesconference