Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MP3 streaming on iOS

Tags:

iphone

openal

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;
}
like image 561
Marvin Killing Avatar asked Jul 19 '10 09:07

Marvin Killing


1 Answers

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.

like image 67
tc. Avatar answered Oct 07 '22 04:10

tc.