我正在使用 AVAssetReader 将 PCM 数据从 iPod 轨道复制到缓冲区,然后使用 RemoteIO 音频单元播放。我正在尝试创建一个单独的线程来加载声音数据,这样我就可以在加载缓冲区时访问和播放缓冲区中的数据。
我目前有一个大型 NSMutableData 对象,它最终保存了整首歌曲的数据。目前,我使用 NSOperation 在单独的线程中加载音频数据,如下所示:
- AVAssetReaderOutput 一次最多复制 8192 个字节到 CMBlockBuffer
- 将这些字节复制到 NSData 对象
- 将此 NSData 对象附加到更大的 NSMutableData 对象(最终保存整首歌曲)
- 完成后,通过访问 NSMutableData 对象中的每个数据包来播放歌曲
我试图在复制这些字节的同时播放歌曲。我不确定同时写入和读取文件的好方法是什么。
我有一个简短的想法:
- 创建并填充 3 个 NSData 对象,每个对象的长度为 8192 字节,作为缓冲区。
- 开始播放。当我播放完第一个缓冲区后,将新数据加载到第一个缓冲区中。
- 当我播放完第二个缓冲区后,将新数据加载到第二个缓冲区中。第三个也是一样
- 再次从第一个缓冲区开始播放,填充第三个。等等。
或者,创建一个包含 3 * 8192 个 PCM 单元的 NSData 对象,并以某种方式使用两个不同的线程同时对其进行写入和读取。
我的代码现在在两个不同的线程上工作。我将数据附加到数组,直到我按下播放,此时它停止(可能是因为线程被阻塞,但我现在不知道)并播放直到它到达我加载的任何内容的末尾并导致 EXC_BAD_ACCESS 异常。
简而言之,我想找到正确的方式在 PCM 数据被复制时播放,比如一次复制 8192 个字节。我可能不得不使用另一个线程(我现在正在使用 NSOperation)这样做,但不清楚如何同时写入和读取缓冲区,最好使用一些更高级别的 Objective-C 方法。