2015-06-02 96 views
2

我喜歡從任意數學函數f(x)生成聲音。現在我爲此使用AudioBufferSource,併爲其創建並播放下一個緩衝區的另一個源的onended處理程序等。問題是緩衝區之間的裂痕。這裏是我的示例代碼:使用Web Audio Api連續播放小型聲音緩衝區序列

function init() { 
     var contextClass = (AudioContext || webkitAudioContext 
       || mozAudioContext || oAudioContext || msAudioContext); 
     if (contextClass) { 
      // Web Audio API is available. 
      context = new contextClass(); 

      return true; 
     } else { 
      return false; 
     } 
    } 

// arbitary mathematical function (not just sin) 
function mySoundFunction(i, j, k) { 
    return j*Math.sin(i/10); 
} 
function createBufferSource(j) { 
     var length = 8092; 

     var audioBuffer = context.createBuffer(1, length, 44500); 
     var data = audioBuffer.getChannelData(0); 
     for (var i = 0; i < length; i++) { 
      data[i] = mySoundFunction(i, j, 5); 
     } 

     var source = context.createBufferSource(); 
     source.buffer = audioBuffer; 
     source.connect(context.destination); 
     source.onended = function ended(obj) { 
      createBufferSource(j); 
    } 

     source.start(0); 

    } 


if (init()) { 
    console.log("init was successful"); 
} 
createBufferSource(0.1); 

由於數學函數可以通過用戶在播放聲音時可以改變,緩衝區大小必須保持較小,預緩衝是不是因爲延遲的一個真正的選擇。 ScriptProcessor可能是一個替代品,但它的性能太昂貴了,我猜。由於函數可以是任何東西,OscillatorNode也不好。 所以問題是,如何消除兩個緩衝區之間的裂紋? 感謝

我試圖用ScriptProcessor,但它還是有差距

function feed() { 
    var a = j === 0 ? 5000: 6000; 
    for (var i = 0; i < 2048; i++) { 
     audata[i] = Math.sin(a*k); 
     k++; 
    } 

    j = 1-j ; 
} 


function createProcessor() { 

    processor = context.createScriptProcessor(2048, 0, 1); 

    processor.onaudioprocess = function(e) {;  
     var L = e.outputBuffer.getChannelData(0); 

     L.set(audata); 
     feed(); 
      } 

     processor.connect(context.destination); 

    running=true; 
} 


if (init()) { 
    console.log("init was successful"); 
} 

audata = new Float32Array(2048); 
k=0; 
j=1; 
feed(); 
createProcessor(); 

我缺少什麼?謝謝

回答

1

你不想在這裏使用onended。這會留下一個缺口,因爲音頻在音頻線程中播放完後會被解僱,所以差距很大。

您今天可能想要使用ScriptProcessor,以及將來要使用AudioWorkers。

+0

啊,當然!謝謝。 –

+0

我試過ScriptProcessor,但有些錯誤:請參閱編輯的問題。謝謝 –

+0

嗯。你有沒有對它進行分析以確保它足夠快地完成feed()?你有沒有看過由feed()生成的音頻數據,以確保一個塊的結束與下一個的開始一致?似乎不會基於數學,但我可能會誤讀。 – cwilso