我们为 iPad 构建了一个鼓机应用程序,可以与现场音乐一起演奏(在舞台上或在您的卧室里)。设置非常简单:您按下其中一个按钮,相应的样本就会播放。一切都非常顺利,但不幸的是,在您放下手指和播放声音之间似乎有一小段(尽管很烦人)延迟。我试图测量延迟量(通过耳朵),它似乎是 0.05 - 0.1 秒。
音频播放已使用 AudioToolbox 框架(扩展音频文件服务、音频单元)实现。声音从存储在设备上的文件流式传输,以防止不同音库之间的加载时间。样本采用原始 wav 格式(线性 PCM,16 位小端符号整数,2 channel ,44100 Hz),据我所知这应该是最快的处理方式(与 mp3 等压缩格式相反)。
我测量了按下按钮(UIButton 触摸事件)和将样本的第一帧传送到混音器(通过回放回调)之间的时间。它非常稳定,在 0.02 到 0.03 秒之间。对我来说,这似乎很快,但可能还不够快。
这可能是问题所在,还是其他原因,例如触摸事件的传递延迟?
更新:
按照 Till 的建议,我重写了示例的加载。它们现在都预加载到内存中,因此磁盘 IO 不再是问题。最重要的是,我为回声效果做了相当多的 memcpy,我已经禁用它,稍后将使用链表类型的解决方案修复它。
虽然这减少了延迟,但按钮按下 -> 播放的时间仍然在 0.005 到 0.02 秒之间(但更常见的是 0.02)。这仍然很明显。我认为这可能是由于播放回调的缓冲区大小所致,目前为 1024 字节。
关于如何做到这一点有什么想法吗?设置 kAudioUnitProperty_MaximumFramesPerSlice 似乎不起作用。
最佳答案
我通过指定首选硬件 I/O 缓冲持续时间解决了延迟问题,如 Audio Session Cookbook 中所述
NSTimeInterval preferredBufferDuration = 0.005;
[audioSession setPreferredIOBufferDuration:preferredBufferDuration error:&audioSessionError];
if (audioSessionError != nil)
{
NSLog (@"Error setting preferred buffer duration.");
return;
}
通过将缓冲持续时间设置为 0.005,您的应用程序将只需要在每个周期提供 256 个字节(在 44Khz 下)。这(显然)将延迟从 0.02 减少到 0.005,但必须以更快的速度生成音频。
iPad 2 完全能够应对这种速度,即使是从磁盘读取 IO。不幸的是,第一代 iPad 不够快(有和没有磁盘 IO)所以我希望我能找到一些方法来区分两者并给 iPad 1 多一点延迟以获得更好的性能。
关于objective-c - iPad drumcomputer touch->音频延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8659478/