OpenAL的简单示例
首先,需要导入AudioToolbox.framework和OpenAL.framework。
#import <UIKit/UIKit.h>#import <OpenAL/alc.h>@interface OpenALViewController : UIViewController {ALCcontext *mContext;ALCdevice *mDevice;NSUInteger sourceID;NSUInteger bufferID;BOOL isPlaying;}- (IBAction)playPause:(id)sender;@end
#import "OpenALViewController.h"#import <AudioToolbox/AudioFile.h>#import <OpenAL/al.h>@implementation OpenALViewController- (void)initOpenAL {mDevice = alcOpenDevice(NULL); if (mDevice) {mContext = alcCreateContext(mDevice, NULL);alcMakeContextCurrent(mContext);}}- (AudioFileID)openAudioFile:(NSString *)filePath {AudioFileID outAFID;NSURL *afUrl = [NSURL fileURLWithPath:filePath]; #if TARGET_OS_IPHONEOSStatus result = AudioFileOpenURL((CFURLRef)afUrl, kAudioFileReadPermission, 0, &outAFID);#elseOSStatus result = AudioFileOpenURL((CFURLRef)afUrl, fsRdPerm, 0, &outAFID);#endifif (result != 0) NSLog(@"cannot open file: %@", filePath);return outAFID;}- (UInt32)audioFileSize:(AudioFileID)fileDescriptor {UInt64 outDataSize = 0;UInt32 thePropSize = sizeof(UInt64);OSStatus result = AudioFileGetProperty(fileDescriptor, kAudioFilePropertyAudioDataByteCount, &thePropSize, &outDataSize);if(result != 0) NSLog(@"cannot find file size");return (UInt32)outDataSize;}- (void)cleanUpOpenAL {alDeleteSources(1, &sourceID);alDeleteBuffers(1, &bufferID);alcDestroyContext(mContext);alcCloseDevice(mDevice);}- (IBAction)playPause:(id)sender {UIButton *btnPlay = (UIButton *)sender;if(!isPlaying) {alSourcePlay(sourceID);isPlaying = YES;[btnPlay setTitle:@"Pause" forState:UIControlStateNormal];} else {alSourceStop(sourceID);isPlaying = NO;[btnPlay setTitle:@"Play" forState:UIControlStateNormal];}}#pragma mark -- (void)viewDidLoad { [super viewDidLoad];isPlaying = NO;[self initOpenAL]; NSString *fileName = [[NSBundle mainBundle] pathForResource:@"outSound" ofType:@"caf"];AudioFileID fileID = [self openAudioFile:fileName];UInt32 fileSize = [self audioFileSize:fileID]; unsigned char *outData = malloc(fileSize);OSStatus result = noErr;result = AudioFileReadBytes(fileID, false, 0, &fileSize, outData);AudioFileClose(fileID); if (result != 0) NSLog(@"cannot load effect: %@", fileName); alGenBuffers(1, &bufferID);alBufferData(bufferID, AL_FORMAT_STEREO16, outData, fileSize, 8000); alGenSources(1, &sourceID); alSourcei(sourceID, AL_BUFFER, bufferID);alSourcef(sourceID, AL_PITCH, 1.0f);alSourcef(sourceID, AL_GAIN, 1.0f);alSourcei(sourceID, AL_LOOPING, AL_TRUE); if (outData) {free(outData);outData = NULL;}}- (void)dealloc {[self cleanUpOpenAL]; [super dealloc];}@end