iPad鼓机触摸->音频延迟

Posted

技术标签:

【中文标题】iPad鼓机触摸->音频延迟【英文标题】:iPad drumcomputer touch->audio latency 【发布时间】:2011-12-28 17:59:23 【问题描述】:

我们为 iPad 构建了一个鼓机应用程序,可以与现场音乐一起演奏(在舞台上或卧室里)。设置非常基本:您按下其中一个按钮,就会播放相应的样本。一切都很顺利,但不幸的是,在您放下手指的那一刻和声音的播放之间似乎有一个小的(尽管很烦人)延迟。我尝试测量延迟量(通过耳朵),它似乎是 0.05 - 0.1 秒。

音频播放已使用 AudioToolbox 框架(扩展音频文件服务,音频单元)实现。声音从存储在设备上的文件中流式传输,以防止不同音库之间的加载时间。样本采用原始 wav 格式(线性 PCM,16 位小端有符号整数,2 通道,44100 Hz),据我所知,这应该是处理速度最快的(相对于像 mp3 这样的压缩格式)。

我测量了按下按钮(UIButton 触摸事件)与将样本的第一帧传送到混合器(通过播放回调)之间的时间。它相当稳定,在 0.02 到 0.03 秒之间。对我来说,这似乎很快,但可能还不够快。

这可能是问题所在还是可能是其他问题,例如触摸事件的传递延迟?

更新:

按照 Till 的建议,我已经重写了样本的加载。它们现在都预加载到内存中,因此磁盘 IO 不再是问题。最重要的是,我为回声效果做了相当多的 memcpy,我已经禁用了它,稍后将使用链表类型的解决方案来修复它。

虽然这减少了延迟,但按钮按下->播放仍然在 0.005 到 0.02 秒之间(但更常见的是 0.02)。这仍然很明显。我认为这可能是由于播放回调的缓冲区大小,目前为 1024 字节。

关于如何做到这一点的任何想法?设置 kAudioUnitProperty_MaximumFramesPerSlice 似乎不起作用。

【问题讨论】:

我猜流文件是问题所在。使用当前移动设备的文件系统时,您永远不应低估速度(或缺乏速度)。尝试直接从内存中预加载和播放。 【参考方案1】:

我通过指定首选硬件 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 更多的延迟以获得更好的性能。

【讨论】:

【参考方案2】:

您可以将 Instruments 与 TimeProfiler (Apple Documentation on Instruments) 模板一起使用,以准确找出需要大量运行的方法。运行时,请务必取消选中“反转调用树”选项并选中“隐藏系统库”。

【讨论】:

我没有意识到 Instruments 内置了这个功能。这肯定会帮助我解决问题,谢谢!

以上是关于iPad鼓机触摸->音频延迟的主要内容,如果未能解决你的问题,请参考以下文章

iPad Safari 是不是支持 <EMBED> 音频?

在swiftui中按钮的触摸动作播放音频

在 iPad 上播放音频

如何使用 libsndfile 在音频文件中打印静音?

MPMoviePlayerController 音频/视频不同步

点击播放音频时出现不必要的延迟