如何正确使用iOS AudioUnit渲染回调

如何正确使用iOS AudioUnit渲染回调,第1张

概述我正在编写一个iOS应用程序,它将播放音频指令作为其中一项功能. 每次应用程序想要播放音频时,它都会从非标准文件中读取,并将该音频的结果PCM数据放入内存中的缓冲区. 即使我有PCM数据的缓冲区,我也无法让应用程序实际播放声音.在搜索iOS文档后,我开始实现AudioUnit.这个AudioUnit的问题是使用渲染回调(据我所知,输出声音的唯一方法).从Apple’s developer docu 我正在编写一个iOS应用程序,它将播放音频指令作为其中一项功能.

每次应用程序想要播放音频时,它都会从非标准文件中读取,并将该音频的结果PCM数据放入内存中的缓冲区.

即使我有PCM数据的缓冲区,我也无法让应用程序实际播放声音.在搜索iOS文档后,我开始实现AudioUnit.这个AudioUnit的问题是使用渲染回调(据我所知,输出声音的唯一方法).从Apple’s developer documentation开始:

… render callbacks have a strict performance requirement that you must
adhere to. A render callback lives on a real-time priority thread on
which subsequent render calls arrive asynchronously. The work you do
in the body of a render callback takes place in this time-constrained
environment. If your callback is still producing sample frames in
response to the prevIoUs render call when the next render call
arrives,you get a gap in the sound. For this reason you must not take
locks,allocate memory,access the file system or a network
connection,or otherwise perform time-consuming tasks in the body of a
render callback function

如果我不能在render回调方法中使用锁,那么在写入时我无法读取缓冲区.没有机会读取文件并写入缓冲区,因为渲染回调将不断访问它.

唯一的例子I found实际上在render方法中生成了PCM数据,这是我做不到的.

这是使用AudioUnits的唯一方法(使用异步渲染回调)吗?

是否可以从内存中播放PCM数据?

解决方法 使用RemoteIO音频单元可能需要在音频单元回调之外有一个单独的数据队列(fifo或循环缓冲区),它可以在音频单元渲染回调之前预先缓冲来自文件读取的足够音频数据,以满足更糟糕的情况延迟.然后,渲染回调只需要快速复制音频数据,然后更新指示音频数据被消耗的只写标志.

iOS内置的替代方案是使用Audio Queue API,它为您进行预缓冲.它允许您的应用提前在主运行循环中填充许多较大的音频缓冲区.您仍然必须预先缓冲足够的数据以允许最大的文件,网络,锁定或其他延迟.

另一种策略是,如果文件或网络读取没有跟上,则可以使用备用音频数据来提供实时渲染回调,例如快速创建逐渐变为静音的音频缓冲区(然后在实际数据开始到达时逐渐减小)再次).

总结

以上是内存溢出为你收集整理的如何正确使用iOS AudioUnit渲染回调全部内容,希望文章能够帮你解决如何正确使用iOS AudioUnit渲染回调所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1051339.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存