Search code examples
iosstreamingcore-audioextaudiofileread

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. For short sound effects in my game, I load the whole file into a memory buffer using ExtAudioFileRead().

For my background music, let's say I have a 3 minute compressed audio file. Assuming it's encoded as mp3 @ 128 kbps (44,100 Hz stereo), that gives around 1 MB per minute, or 3 MB total. 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.

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:

  1. Prepare two buffers A and B, each big enough to hold (say) 5 seconds of audio. During playback, start reading from one buffer and switch to the other one when reaching the end (i.e., they make up the two halves of a ring buffer).

  2. Read first 5 seconds of audio from file into buffer A.

  3. Read next 5 seconds of audio from file into buffer B.

  4. Begin playback (from buffer A).

  5. Once the play head enters buffer B, load next 5 seconds of audio into buffer A.

  6. Once the play head enters buffer A again, load next 5 seconds of audio into buffer B.

  7. Go to #5

Is this the right approach, or is there a better way?


Solution

  • I'd suggest using the high-level AVAudioPlayer class to do simple background playback of an audio file. See: 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. See AudioUnitProperties.h for a discussion. 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.