0

所以我正在制作一个游戏机模拟器,我现在在音频部分。如果重要的话,基本上我将样本推送到单声道音频缓冲区(1 个通道,2048 长度,22000 采样率)。所以我推到这个缓冲区,每次它满了,我就玩它。但这会导致双倍生锈的爆裂声。这太糟糕了。

我听说最佳方法是在缓冲区满时排队,等待“内部缓冲区”完成播放然后播放该缓冲区。但是,我在 api 中找不到类似的东西。我在想可能是完成后的回调或其他任何事情,但没有。

有谁知道是否有这样的事情?或者如果有不同的方法来解决这个问题?谢谢大家 !

4

1 回答 1

0

onended当 AudioBufferSoruce 完成播放时会发生一个事件。但是,这可能会在缓冲区结束和您开始播放新缓冲区之间存在间隙。之所以会出现这种差距,是因为音频线程需要时间通知主线程缓冲区已结束,并且您接收事件并启动新缓冲区也需要时间。

正如您所提到的,权利是缓冲数据,然后安排缓冲源开始播放,就像前一个缓冲区结束一样。类似于以下内容:

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 中的第一个值,则可能会出现点击或故障。)

于 2021-03-29T15:07:02.313 回答