Core Audio - CARingBuffer 读取音频文件进行回调
Posted
技术标签:
【中文标题】Core Audio - CARingBuffer 读取音频文件进行回调【英文标题】:Core Audio - CARingBuffer to read an audio file for callback 【发布时间】:2011-03-24 04:58:58 【问题描述】:有没有人有一个使用 CARingBuffer 缓冲大型音频文件以及如何在回调中读取它的好例子?
它应该在辅助线程中读取音频文件吗?如何在播放加载的缓冲区之前暂停加载音频文件(如何对音频文件进行预排队)? CAPlayThrough 似乎很接近,但只是从麦克风流式传输音频。
谢谢!
【问题讨论】:
我目前也在寻求解决这个问题的方法。如果你找到一个可行的实现,我很想看看 yoyu 是如何做到的。 @dubbeat 在下面查看我的答案 【参考方案1】:如果您下载book 的示例代码,您可以找到使用此环形缓冲区的示例Learning Core Audio here(在下载 标签下) .跳转到名为 CH08_AUGraphInput 的文件夹中的第 8 章示例。
但是,如果您只是从文件中读取音频,那么使用(额外的)环形缓冲区似乎有点过头了。当您进行实时(或接近实时)输入和输出时,环形缓冲区会派上用场(请阅读上述书中的第 8 章,以更详细地了解何时需要使用环形缓冲区。请注意,第 8 章中的示例是关于在通过麦克风录制音频后立即播放音频,这不是您想要做的)。
我之所以说额外的环形缓冲区,是因为在核心音频中已经有一个音频队列(可以被认为是一个环形缓冲区..或者至少在你的情况下它取代了对环形缓冲区的需要:你用数据填充它,它播放数据,然后触发一个回调,通知你你提供的数据已经播放)。苹果documentation对此提供了很好的解释。
在您的情况下,如果您只是从文件中读取音频,那么您可以轻松控制文件中音频的吞吐量。例如,您可以通过阻止从音频文件中读取数据的线程来暂停它。
有关我所说的一个简单示例,请参阅我在 github 上创建的 example。有关更高级的示例,请参阅 Matt Gallagher 著名的example。
【讨论】:
【参考方案2】:通常对于音频播放,任何可能阻塞或花费无限时间(特别是文件或磁盘 IO)的事情都应该在辅助线程中完成。所以你想在生产者线程中读取音频文件的数据,并在你的 IOProc 或 RemoteIO 回调中使用数据。
同步成为多个线程的问题,但如果您只有一个阅读器和一个编写器,通常不会太难。事实上,对于这种情况,CARingBuffer 是线程安全的。
一般流程应如下所示:
来自主线程:
-
创建生产者线程
告诉它要处理哪个文件
来自生产者线程:
-
打开指定文件
用音频数据填充环形缓冲区的空白空间
等到发出信号或发生超时,然后返回 #2
在您的 IOProc/回调中:
-
从环形缓冲区读取数据
向生产者发出需要更多数据的信号
在此处发布执行此操作的代码太长,难以阅读,但这里有一些提示可以帮助您入门。这些都不是针对 iPhone 的,但原理是一样的。
https://github.com/sbooth/SFBAudioEngine/blob/master/Player/AudioPlayer.cpp http://www.snoize.com/【讨论】:
以上是关于Core Audio - CARingBuffer 读取音频文件进行回调的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iPhone 的 Core Audio (Audio Unit/ Remote IO) 中将录制的声音更改为男人的声音