我可以在 AURenderCallback 函数中限制 iOS 传递的 inNumberFrames 吗?

Posted

技术标签:

【中文标题】我可以在 AURenderCallback 函数中限制 iOS 传递的 inNumberFrames 吗?【英文标题】:Can I limit the inNumberFrames passed by iOS in AURenderCallback function? 【发布时间】:2011-10-05 17:49:44 【问题描述】:

我创建了使用AudioUnitExtAudioFile 的自定义音频播放器类。 在我的课堂上,我准备了自己的渲染回调函数,例如

OSStatus MyAURenderCallack (
   void                        *inRefCon,
   AudioUnitRenderActionFlags  *ioActionFlags,
   const AudioTimeStamp        *inTimeStamp,
   UInt32                      inBusNumber,
   UInt32                      inNumberFrames,
   AudioBufferList             *ioData
);

当我的应用程序在前台时,操作系统传递的参数inNumberFrames总是5121024,我的播放器运行良好。 但是当ios设备休眠时,inNumberFrames变成4096,我的播放器就不能工作了,因为它一次不能准备这么多帧。

帧准备过程很难改进,因为它大量使用extAudioFileRead函数,很难加速。

所以,我想限制inNumberFrames 变得大于1024。 我能做到吗?

【问题讨论】:

你不应该在你的渲染回调中调用ExtAudioFileRead。它可能会阻塞一段未指定的时间并导致故障。 那么我应该调用 ExtAudioFileRead 并在另一个线程中准备缓冲区吗? 是的,典型的方式是让生产者线程填充环形缓冲区,渲染回调从环形缓冲区中读取并向生产者线程发出需要更多数据的信号。 生产者-消费者模式效果很好。非常感谢! 【参考方案1】:

正如@sbooth 所说,您确实应该在另一个线程中写入磁盘。如果没有,这会给应用程序的主线程带来真正的压力,它应该专注于提供音频而不会丢失。

但是要直接回答您的问题:不,您不能直接告诉操作系统用于块大小的确切帧数。你可以建议它使用一定的延迟,结合请求的采样率会给你一个大概的块大小。但是,不能保证 iOS 会返回这个块大小。

但是,您最好的选择是让您的算法适用于任意块大小。除非您正在执行卷积之类的操作,否则通常应该更容易使用更大的块。因此,如果您在 4096 遇到问题,您可能应该分析您的代码并查看潜在问题是什么。

【讨论】:

以上是关于我可以在 AURenderCallback 函数中限制 iOS 传递的 inNumberFrames 吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中注册 AURenderCallback

多个文件播放器上的Core Audio声音测量

使用 getter 时 UnsafeMutableBufferPointer 很慢

我可以在反应组件的构造函数中使用箭头函数吗?

我可以在函数中定义一个简单的函数,以便为函数中的不同情况进行封装和重用吗?

我可以在视图函数中的函数中返回响应吗?