所以我正在制作一个游戏模拟器,我现在正在制作音频部分。 基本上我将样本推送到单声道音频缓冲区(1 通道,2048 长度,22000 采样率),如果重要的话。 所以我推到这个缓冲区,每次它满了,我就玩它。但这会导致双重生锈的噼啪声。太可怕了。
我听说最佳方法是在缓冲区已满时将其排队,等待“内部缓冲区”完成播放,然后播放该缓冲区。 但是,我在 api 中找不到类似的东西。我在想可能是在完成后回调或其他什么,但没有。
有人知道有没有类似的东西?或者如果有不同的方法来解决这个问题? 提前谢谢大家!
答案 0 :(得分:0)
AudioBufferSoruce 播放完毕后会发生 onended
事件。但是,这可能会在缓冲区结束和您开始播放新缓冲区之间存在间隔。之所以会出现这种差距,是因为音频线程需要时间通知主线程缓冲区已结束,而且您接收事件并启动新缓冲区也需要时间。
正如您提到的,正确的是缓冲数据,然后安排缓冲源在前一个缓冲区结束时开始播放。类似于以下内容:
s0 = new AudioBufferSourceNode(context, {buffer: buffer0});
// delta is a small amount of time, about 3 ms or so to allow for the fact that
// by the time you call start(), the audio thread may have already incremented
// currentTime. If it has, the calculations of when the buffer ends will be
// wrong.
startTime = context.currentTime + delta;
s0.start(startTime);
// Create second buffer in buffer1. Then
s1 = new AudioBufferSourceNode(context, {buffer: buffer1});
startTime += buffer0.duration;
s1.start(startTime);
s1
应该在 s0
结束时开始播放。它们之间应该没有间隙。 (但是,如果 buffer0 中的最后一个值不接近 buffer1 中的第一个值,则可能会出现点击或故障。)