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();
我缺少什麼?謝謝
啊,當然!謝謝。 –
我試過ScriptProcessor,但有些錯誤:請參閱編輯的問題。謝謝 –
嗯。你有沒有對它進行分析以確保它足夠快地完成feed()?你有沒有看過由feed()生成的音頻數據,以確保一個塊的結束與下一個的開始一致?似乎不會基於數學,但我可能會誤讀。 – cwilso