MP3 streaming on iOS
Asked Answered
S

1

7

I want to use OpenAL to play music in an iOS game. The music files are stored in mp3 format and I want to stream them using a buffer queue. I load audio data into the buffers using AudioFileReadPacketData(). However playing the buffers only gives me noise. It works perfectly for caf files, but not for mp3s. Did I miss some vital step in decoding the file?

Code I use to open the sound file:

- (void) openFile:(NSString*)fileName {
   NSBundle *bundle = [NSBundle mainBundle];
   CFURLRef url = (CFURLRef)[[NSURL fileURLWithPath:[bundle pathForResource:fileName ofType:@"mp3"]] retain];
   AudioFileOpenURL(url, kAudioFileReadPermission, 0, &audioFile);
   AudioStreamBasicDescription theFormat;
   UInt32 formatSize = sizeof(theFormat);
   AudioFileGetProperty(audioFile, kAudioFilePropertyDataFormat, &formatSize, &theFormat);  
   freq = (ALsizei)theFormat.mSampleRate;
   CFRelease(url);
}

Code I use to fill in buffers:

- (void) loadOneChunkIntoBuffer:(ALuint)buffer {
    char data[STREAM_BUFFER_SIZE];
    UInt32 loadSize = STREAM_BUFFER_SIZE;
    AudioStreamPacketDescription packetDesc[STREAM_PACKETS];
    UInt32 numPackets = STREAM_PACKETS;
    AudioFileReadPacketData(audioFile, NO, &loadSize, packetDesc, packetsLoaded, &numPackets, data);
    alBufferData(buffer, AL_FORMAT_STEREO16, data, loadSize, freq);
    packetsLoaded += numPackets;
}
Spherical answered 19/7, 2010 at 9:1 Comment(0)
B
1

Because you're reading bytes of MP3 data and treating them as PCM data.

You almost certainly want AudioFileReadPacketData(). EDIT: Except that still gives you MP3 data; it just gives it in packets and (possibly) parses packet headers.

If you don't require OpenAL, AVAudioPlayer is probably the better way to go (according to the Multimedia Programming Guide, there's also Audio Queue services if you want more control).

If you really need to use OpenAL, according to TN2199 you'll need to convert it to PCM in the native byte order. See oalTouch/Classes/MyOpenALSupport.c for an example of using Extended Audio File Services to do this. Note that TN2199 says the format "must ... not use hardware decompression" — according to the Multimedia Programming Guide, software decoding is supported for everything except HE-AAC since OS 3.0. Also note that software MP3 decoding can use a significant amount of CPU time.

Alternatively, explicitly convert the audio using AudioConverter or (possibly) AudioUnit with kAudioUnitSubType_AUConverter. If you do this, it might be worthwhile decompressing everything once and keeping it in memory to minimize overhead.

Bromidic answered 19/7, 2010 at 18:46 Comment(3)
Thanks for your reply. I replaced AudioFileReadBytes() by AudioFileReadPacketData(). I updated the question with my new code. The problem persists though, all I get is noise.Spherical
What did you decide to go with, out of interest?Bromidic
I'm using AVAudioPlayer, it fits my needs quite well. Still don't know how I could miss it. Thanks again for your great answer.Spherical

© 2022 - 2024 — McMap. All rights reserved.