Javascript中的现场声音合成:任何减少延迟的方法?

时间:2013-10-29 19:23:51

标签: javascript audio web-audio

我正在开发一个Javascript音乐应用。

离线渲染工作正常,即生成缓冲区,使用AudioBufferSourceNode在给定时间播放它。时间几乎是完美的。

但我需要生成无法使用API​​的默认节点创建的音调。所以我将声音生成逻辑放在ScriptProcessorNode的回调中。

我非常肯定我的ScriptProcessorNode中的代码足够快,因为一旦启动,声音就会在我想要的任何数量的缓冲周期内没有毛刺播放 - 所以在这里填充缓冲区可能不是问题。根据我的实验,我发现ScriptProcessorNode的onaudioprocess事件是定期触发的,而不是取决于创建处理器节点的时间。这会在应用程序中产生不可预测的延迟:如果用户在回调开始后立即按下某个键,则等待直到下一个时段播放。

我已创建this fiddle来演示它。有一个简单的仪器和两个按钮来控制它。一个播放预先录制的缓冲区:

function playBuffer()
{
    source = ac.createBufferSource();
    source.buffer = buffer;
    source.connect(ac.destination);
    source.start(0);
};

而另一个播放同样的声音但是活着:

function playLive()
{
    processor = ac.createScriptProcessor(4096, 0, 1);
    processor.onaudioprocess = function(e)
    {
        sineStrument.fillBuffer(e.outputBuffer.getChannelData(0), e.outputBuffer.length);
    }
    processor.connect(ac.destination);
};

使用第一个按钮可以产生节奏并听到它完美无瑕。使用第二个按钮是不可能的,因为声音开始需要大约50 + ms。

现在注意到仪器非常简单,我认为这里没有计算速度问题。另外,如果你正确的时间,你可以得到实时处理的声音与你的点击同步 - 我认为你只需要在调用onaudioprocess回调之前点击。

1)playBuffer函数立即播放的事实2)可以通过playLive函数获得正确的时序告诉我应该有一种技术方法来使ScriptProcessorNode正确计时。

我该怎么办?为什么播放缓冲区没有固定的开始时间?

我也尝试过减少ScriptProcessorNode的缓冲区大小,但声音很快就会失真。为什么会这样?如果回调中的代码不够快,那么声音会在一段时间后出现故障吗?它没有!

1 个答案:

答案 0 :(得分:-1)

将ScriptProcessorNode连接到GainNode,增益值初始化为0.按“Play Live”按钮将按下时的增益值设置为1,释放时设置为0。