web-audio-api - 使用 Web Audio Api 连续播放小声音缓冲区序列

标签 web-audio-api

我喜欢从任意数学函数 f(x) 生成声音。现在我使用 AudioBufferSource 来实现此目的,并且我为下一个缓冲区创建并播放另一个源,依此类推。问题是缓冲器之间的裂纹。这是我的示例代码:

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();

我错过了什么?谢谢

最佳答案

你不想在这里使用onend。这会留下一个间隙,因为它是在音频线程中的音频播放完毕后触发的,因此存在很大的间隙。

您今天可能想使用 ScriptProcessor,将来可能想使用 AudioWorkers。

关于web-audio-api - 使用 Web Audio Api 连续播放小声音缓冲区序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30597980/

相关文章:

javascript - Web Audio 可视化波形并与之交互

javascript - 媒体元素音频源节点如何播放

javascript - Web Audio API Panner 节点 - 如何在 100% pan 上剪切声音?

javascript - Firefox Audiocontext 暂停

javascript - 如何使用 Web Audio API 获取采样率、位深度和 channel 数?

javascript - Web Audio API 如何命名声音

javascript - 通过 WebSocket 解码音频 block

javascript - 网络录音,预设: 16000Hz 16bit

javascript - 如何使用网络音频 api 获得音轨样本的正确幅度(不播放)

audio - 使用Web音频自动进行两输入混音