如何确保iOS上的时间限制内呈现的音频?

时间:2016-07-08 15:35:58

标签: ios audio audiounit

我通过iOS Audio Unit render callback从我的自定义合成代码中呈现低延迟音频。显然,如果我的渲染代码太慢,那么它将从回调中返回太迟,并且将有一个缓冲区欠载。我从经验中知道这导致了输出的沉默。

我想知道我的时间限制,以便我可以管理处理级别以匹配设备限制等。

显然,缓冲区的长度(在样本中)决定了呈现音频的持续时间,并设置了总体限制。但是我怀疑Apple音频引擎在发出渲染回调和要求响应之间的时间限制较短。

  1. 如何找出这个时间限制,这是我在回调函数中可以做的事情吗?
  2. 如果我碰巧超过了时间限制并造成缓冲区欠载,是否有我可以收到的通知或我可以查询的状态对象?
  3. 注意:在我的应用程序中,我正在创建一个“输出”音频单元,因此我不必担心将音频单元链接在一起。

2 个答案:

答案 0 :(得分:2)

可以在音频单元回调中完成的音频渲染量取决于iOS设备型号和操作系统版本,以及由于温度或背景模式导致的潜在CPU时钟速度限制。因此,需要在您支持的应用程序支持的最老,最慢的iOS设备上进行分析,并保留一些余量。

为了支持iOS 9,我非常保守地在iPhone 4S测试设备(800 Cortda的ARM Cortex A9 CPU)或使用早期iOS版本的更慢的设备上配置我的应用程序。在进行此分析时,可以添加一定比例的" make work"测试音频回调并查看是否有任何余量(50%的保证金,生成样本缓冲两次等)其他开发人员似乎不那么保守。

这就是为什么移动音频开发人员拥有(或有权访问)多个iOS设备(越旧越好)的原因。如果回调符合旧慢速文本设备的时间限制,则在任何较新的iOS设备上回调的速度都非常快。

根据操作系统版本的不同,欠载可能会导致静音,或者音频设备停止或崩溃(在一段可预测的时间内可以检测到更多或没有足够的回调)。

但是避免欠载的最好方法是在音频单元线程之外的另一个线程中完成大部分繁重的音频工作,并使用无锁的循环fifo /队列将样本传入/传出音频单元回调。

答案 1 :(得分:0)

除了hotpaw2所说的,我遇到的性能最差的iOS设备是没有后置摄像头的iPhone touch 16G。我已经完成了除了ipod touch 16G之外的所有设备都能顺利播放音频的项目。我不得不将缓冲持续时间提高到下一个大小以适应。

我通常在渲染回调之前在单独的无锁环缓冲区中完成所有音频预处理,并使渲染回调仅限于复制数据。我让应用程序"处理"缓冲区不足。

我个人从未测量渲染回调方差,但我猜它会一直等于缓冲持续时间,并且会产生非常小的抖动(例如5ms)。我怀疑它一次是4.9毫秒,下一次是5.1毫秒。

要获取一些时间信息,请在mach_time.h中使用mach_absolute_time()来获取时间。

你并没有真正说明你的时间要求是什么。我假设您需要低延迟音频。否则,您可以将缓冲区持续时间设置得相当大。我假设您希望使用此代码增加慢速设备的延迟。我经常发现什么在iPod 16G上运行,并将其作为最坏的情况使用。

NSTimeInterval _preferredDuration = ...
NSError* err;
[[AVAudioSession sharedInstance]setPreferredIOBufferDuration:_preferredDuration error:&err];

当然,你应该得到实际使用的持续时间。操作系统将根据采样率选择2的幂:

NSTimeInterval _actualBufferDuration;
_actualBufferDuration = [[AVAudioSession sharedInstance] IOBufferDuration];

至于调整设备性能。您可以设置缓冲持续时间