iOS上的MP3流媒体

时间:2010-07-19 09:01:21

标签: iphone openal

我想使用OpenAL在iOS游戏中播放音乐。音乐文件以mp3格式存储,我想使用缓冲队列来传输它们。我使用 AudioFileReadPacketData()将音频数据加载到缓冲区中。但是播放缓冲区只会给我带来噪音。它适用于caf文件,但不适用于mp3。我是否错过了解码文件的一些重要步骤?

我用来打开声音文件的代码:

- (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);
}

我用来填充缓冲区的代码:

- (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;
}

1 个答案:

答案 0 :(得分:1)

因为您正在读取MP3数据的字节并将其视为PCM数据。

你几乎肯定想要AudioFileReadPacketData() 编辑:除了仍然提供MP3数据;它只是以数据包形式提供,并且(可能)解析数据包标头。

如果您不需要OpenAL,AVAudioPlayer可能是更好的方法(根据Multimedia Programming Guide,如果您想要更多控制,还有音频队列服务。)

如果您确实需要使用OpenAL,根据TN2199,您需要以原生字节顺序将其转换为PCM。有关使用扩展音频文件服务执行此操作的示例,请参阅oalTouch/Classes/MyOpenALSupport.c。请注意,TN2199表示“必须......不使用硬件解压缩”格式 - 根据“多媒体编程指南”,自OS 3.0以来,除HE-AAC之外的所有内容都支持软件解码。另请注意,软件MP3解码可能会占用大量的CPU时间。

或者,使用AudioConverter或(可能)AudioUnit使用kAudioUnitSubType_AUConverter显式转换音频。如果你这样做,可能值得将所有内容解压缩一次,并将其保留在内存中以最大限度地减少开销。