程序名:oalTouch (OpenAL的一个应用)
功能:通过AVAudioPlayer播放背景音乐,通过OpenAL播放自定音乐,其中自定音乐可播放、暂停,当两个音乐同时播放时可实现混音效果。(我去掉了重力检测和AudioSession两个非主要功能)实现步骤:直接调用AVAudioPlayer播放音乐较为简单:- 通过AVAudioPlay的init方法设定音乐文件的路径
- 通过其play方法播放背景音乐
使用openAL播放音乐实现步骤较为烦琐,此处由于用OpenAL播放的只有一个音乐,去掉了创建Session的内容。
- 得到设备device
- 创建一块设备的音频存储空间context
- 把音频数据data添加到缓存buffer中
- 把缓存buffer附加到数据源source中
- 播放数据源source
关键代码:
一、AVAudioPlayer播放音乐1 NSURL *bgURL = [[NSURL alloc] initFileURLWithPath: [[NSBundle mainBundle] pathForResource:@"background" ofType:@"m4a"]]; 2 bgPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:bgURL error:nil]; 3 bgPlayer.numberOfLoops = -1; // infinite loop 4 if (bgPlayer) { 5 [bgPlayer play]; 6 }
二、OpenAL
1. 初始化设备device和音频存储空间context1 -(void)initOpenAL 2 { 3 // Initialization 4 mDevice = alcOpenDevice(NULL); // select the "preferred device" 5 if (mDevice) { 6 // use the device to make a context 7 mContext = alcCreateContext(mDevice,NULL); 8 // set my context to the currently active one 9 alcMakeContextCurrent(mContext); 10 } 11 }
2. 得到音乐文件长度
1 -(AudioFileID)openAudioFile:(NSString*)filePath // 给出文件路径调用此方法得到fileID 2 { 3 AudioFileID outAFID; 4 // use the NSURl instead of a cfurlref cuz it is easier 5 NSURL * afUrl = [NSURL fileURLWithPath:filePath]; 6 7 // do some platform specific stuff.. 8 OSStatus result = AudioFileOpenURL((CFURLRef)afUrl, kAudioFileReadPermission, 0, &outAFID); 9 if (result != 0) NSLog(@"cannot openf file: %@",filePath); 10 return outAFID; 11 } 12 -(UInt32)audioFileSize:(AudioFileID)fileDescriptor // 给出fileID调用此方法,得到fileSize 13 { 14 UInt64 outDataSize = 0; 15 UInt32 thePropSize = sizeof(UInt64); 16 OSStatus result = AudioFileGetProperty(fileDescriptor, kAudioFilePropertyAudioDataByteCount, &thePropSize, &outDataSize); 17 if(result != 0) NSLog(@"cannot find file size"); 18 return (UInt32)outDataSize; 19 }
3. 得到音乐数据
1 unsigned char * outData = malloc(fileSize); 2 // this where we actually get the bytes from the file and put them 3 // into the data buffer 4 OSStatus result = noErr; 5 result = AudioFileReadBytes(fileID, false, 0, &fileSize, outData); 6 AudioFileClose(fileID); //close the file
4. 得到缓存buffer
1 alGenBuffers(1, &bufferID); 2 // jam the audio data into the new buffer 3 // 16位立体声格式,8k采样频率 4 alBufferData(bufferID, AL_FORMAT_STEREO16, outData, fileSize, 8000);
5. 得到数据源source
1 alGenSources(1, &sourceID); 2 // attach the buffer to the source 3 alSourcei(sourceID, AL_BUFFER, bufferID); 4 // loop the sound 5 alSourcei(sourceID, AL_LOOPING, AL_TRUE);
程序效果:
背景音乐播放的是一个进行曲按Play/Pause可播放或暂停自己的音乐文件(一个bubble声)附件:附件中的项目OpenALTest实现了oalTouch中的主要功能,大家可以下载源码看看