我正在开发一个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的缓冲区大小,但声音很快就会失真。为什么会这样?如果回调中的代码不够快,那么声音会在一段时间后出现故障吗?它没有!
答案 0 :(得分:-1)
将ScriptProcessorNode连接到GainNode,增益值初始化为0.按“Play Live”按钮将按下时的增益值设置为1,释放时设置为0。