Core Audio - CARingBuffer 读取音频文件以进行回调
有谁有使用 CARingBuffer 缓冲大型音频文件以及如何在回调中读取它的好例子吗?
它应该在辅助线程中读取音频文件吗?如何暂停加载音频文件,直到播放加载的缓冲区(如何对音频文件进行预排队)? CAPlayThrough 看起来很接近,但只是从麦克风传输音频。
谢谢!
Does anyone have a good example of using CARingBuffer to buffer a large audio file and how to read it in a callback?
Should it be reading the audio file in a secondary thread? How do I pause loading the audio file until the loaded buffers have been played (how do I pre-queue the audio file)? CAPlayThrough seems close but is only streaming audio from a microphone.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您下载 一本书的示例代码,您可以找到使用此环形缓冲区的示例< /a> 学习核心音频 此处(在下载选项卡下)。跳转到名为 CH08_AUGraphInput 的文件夹中的第 8 章示例。
但是,如果您只是从文件中读取音频,那么使用(额外的)环形缓冲区似乎有点过分了。当您进行实时(或接近实时)输入和输出时,环形缓冲区会派上用场(阅读章节请注意,第 8 章中的示例是关于通过麦克风录制音频后立即播放音频,这不是您想要做的)。
我之所以说额外的环形缓冲区,是因为在核心音频中已经有一个音频队列(可以将其视为环形缓冲区..或者至少在您的情况下它取代了对环形缓冲区的需要:您填充它与数据一起播放数据,然后触发回调通知您提供的数据已播放)。苹果文档对此提供了很好的解释。
就您而言,如果您只是从文件中读取音频,那么您可以轻松控制文件中音频的吞吐量。例如,您可以通过阻止从音频文件读取数据的线程来暂停它。
有关我所讨论内容的简单示例,请参阅我在 github 上创建的示例。有关更高级的示例,请参阅 Matt Gallagher 著名的示例。
You can find an example that uses this ring buffer if you download the example code of the book Learning Core Audio here (under the downloads tab). Jump to the chapter 8 example in a folder called CH08_AUGraphInput.
However, if you are simply reading audio from a file, then using an (extra) ring buffer seems like an overkill.. A ring buffer comes in handy when you are having real time (or near real time) input and output (read chapter 8 in the said book for a more detailed explanation of when a ring buffer is necessary.. note that the example in chapter 8 is about playing audio immediately after recording it by a mic, which isn't what you want to do).
The reason why I said extra ring buffer, is because in core Audio there is already an audio Queue (which can be thought of as a ring buffer.. or at least it in your case it replaces the need for a ring buffer: you populate it with data, it plays the data, then fires a callback that informs you that the data you supplied has been played). The apple documentation offers a good explanation on this one.
In your case, if you are simply reading audio from a file, then you can easily control the throughput of the audio from the file. You can pause it by blocking the thread that reads data from the audio file for example.
For a simple example of what I'm talking about, see this example I created on github. For a more advanced example, see Matt Gallagher's famous example.
通常,对于音频播放,任何可能阻塞或花费无限时间(特别是文件或磁盘 IO)的事情都应该在辅助线程中完成。因此,您希望在生产者线程中读取音频文件的数据,并在 IOProc 或 RemoteIO 回调中使用数据。
同步成为多线程的一个问题,但如果只有一个读取器和一个写入器,通常这并不太难。事实上,对于这种情况,CARingBuffer 是线程安全的。
一般流程应如下所示:
从主线程:
从生产者线程:
在您的 IOProc/callback 中:
在此发布执行此操作的代码太长,难以阅读,但这里有一些入门指南。这些都不适用于 iPhone,但原理是相同的。
Generally for audio playback anything that can block or take an unbounded amount of time (in particular file or disk IO) should be done in a secondary thread. So you want to read the audio file's data in a producer thread, and consume the data in your IOProc or RemoteIO callback.
Synchronization becomes an issue with multiple threads, but if you have only one reader and one writer generally it isn't too hard. In fact, CARingBuffer is thread safe for this case.
The general flow should look like:
From the main thread:
From the producer thread:
In your IOProc/callback:
Posting code to do this here would be much too long to read, but here are a few pointers to get you started. None of these are for the iPhone, but the principles are the same.