我喜欢从任意数学函数f(x)生成声音。现在我为此使用AudioBufferSource,并且我创建了它的onended处理程序并为下一个缓冲区播放另一个源,依此类推。问题是缓冲区之间的裂缝。这是我的示例代码:
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();
我错过了什么?感谢
答案 0 :(得分:1)
你不想在这里使用。这将留下一个空白,因为它在音频完成音频线程播放后被解雇,因此存在很大差距。
您可能希望今天使用ScriptProcessor,以及将来使用AudioWorkers。