简体   繁体   English

核心音频大(压缩)文件播放和内存占用

[英]Core Audio Large (Compressed) File Playback and Memory Footprint

So, I have setup a multichannel mixer and a Remote I/O unit to mix/play several buffers of PCM data that I read from audio files. 因此,我设置了一个多通道混合器和一个远程I / O单元,以混合/播放从音频文件中读取的PCM数据的多个缓冲区。 For short sound effects in my game, I load the whole file into a memory buffer using ExtAudioFileRead() . 为了在游戏中产生短暂的声音效果,我使用ExtAudioFileRead()将整个文件加载到内存缓冲区中。

For my background music, let's say I have a 3 minute compressed audio file. 对于我的背景音乐,假设我有一个3分钟的压缩音频文件。 Assuming it's encoded as mp3 @ 128 kbps (44,100 Hz stereo), that gives around 1 MB per minute, or 3 MB total. 假设它被编码为mp3 @ 128 kbps(44,100 Hz立体声),则每分钟大约1 MB,或总计3 MB。 Uncompressed, in memory, I believe it's around ten times that if I remember correctly. 如果没有记错的话,在内存中,如果没有记错的话,我相信它大约是它的十倍。 I could use the exact same method as for small files; 我可以使用与小型文件完全相同的方法; I believe ExtAudioFileRead() takes care of the decoding, using the (single) hardware decoder when available, but I'd rather not read the whole buffer at once, and instead 'stream' it at regular intervals from disk. 我相信ExtAudioFileRead()会在可能的情况下使用(单个)硬件解码器来处理解码,但是我宁愿不要一次读取整个缓冲区,而应该定期从磁盘“流式处理”它。

The first thing that comes to mind is going one step below to the (non-"extended") Audio File Services API and use AudioFileReadPackets() , like so: 首先想到的是将音频文件服务API(非“扩展”)向下移动一个步骤,并使用AudioFileReadPackets() ,如下所示:

  1. Prepare two buffers A and B, each big enough to hold (say) 5 seconds of audio. 准备两个缓冲区A和B,每个缓冲区足够大以容纳(说)5秒钟的音频。 During playback, start reading from one buffer and switch to the other one when reaching the end (ie, they make up the two halves of a ring buffer). 在播放过程中,从一个缓冲区开始读取,并在到达末尾时切换到另一缓冲区(即,它们组成了环形缓冲区的两半)。

  2. Read first 5 seconds of audio from file into buffer A. 从文件中读取音频的前5秒到缓冲区A。

  3. Read next 5 seconds of audio from file into buffer B. 从文件中读取接下来的5秒钟音频到缓冲区B。

  4. Begin playback (from buffer A). 开始播放(从缓冲区A开始)。

  5. Once the play head enters buffer B, load next 5 seconds of audio into buffer A. 播放头进入缓冲区B后,请将接下来的5秒钟音频加载到缓冲区A中。

  6. Once the play head enters buffer A again, load next 5 seconds of audio into buffer B. 播放头再次进入缓冲区A后,请将接下来的5秒钟音频加载到缓冲区B中。

  7. Go to #5 转到#5

Is this the right approach, or is there a better way? 这是正确的方法,还是有更好的方法?

I'd suggest using the high-level AVAudioPlayer class to do simple background playback of an audio file. 我建议使用高级AVAudioPlayer类对音频文件进行简单的后台播放。 See: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Chapters/Reference.html#//apple_ref/doc/uid/TP40008067 参见: https : //developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Chapters/Reference.html#//apple_ref/doc/uid/TP40008067

If you require finer-grained control and lower latency, check out Apple's AUAudioFilePlayer. 如果您需要更细粒度的控制和更低的延迟,请查看Apple的AUAudioFilePlayer。 See AudioUnitProperties.h for a discussion. 有关讨论,请参见AudioUnitProperties.h。 This is an Audio Unit that that abstracts the complexities of streaming an audio file from disk. 这是一个音频单元,从磁盘上提取流音频文件的复杂性。 That said, it's still pretty complicated to set up and use, so definitely try AVAudioPlayer first. 也就是说,它的设置和使用仍然非常复杂,因此请务必首先尝试AVAudioPlayer。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM