openal播放pcm缓存数据

175 views
Skip to first unread message

~Y

unread,
Dec 19, 2011, 8:30:51 PM12/19/11
to iOS development
昨天看了一天的播放缓存数据,最终由一位大大帮忙解决了。以下是.h文件
#import <Foundation/Foundation.h>
#import <OpenAL/al.h>
#import <OpenAL/alc.h>

@interface OpenALPlayer : NSObject
{
ALCcontext *mContext;
ALCdevice *mDevice;

ALuint outSourceID;
}

@property(nonatomic) ALCcontext *mContext;
@property(nonatomic) ALCdevice *mDevice;

- (void)initOpenAL;
- (void) openAudioFromQueue:(short*)data dataSize:(UInt32)dataSize
index:(int)aIndex;
- (void)stopSound;

@end


以下是.m文件
#import "OpenALPlayer.h"

@implementation OpenALPlayer
@synthesize mContext;
@synthesize mDevice;

- (void)initOpenAL
{
mDevice = alcOpenDevice(NULL);
if (mDevice) {
mContext = alcCreateContext(mDevice, NULL);
alcMakeContextCurrent(mContext);
}

alGenSources(1, &outSourceID);
alSourcef(outSourceID, AL_LOOPING, AL_FALSE);
alSourcef(outSourceID, AL_SOURCE_TYPE, AL_STREAMING);
}

- (id)init
{
self = [super init];

[self initOpenAL];

return self;
}

- (BOOL)updateQueueBuffer
{
ALint stateVaue;
int processed, queued;


alGetSourcei(outSourceID, AL_SOURCE_STATE, &stateVaue);

if (stateVaue == AL_STOPPED)
{
return NO;
}


alGetSourcei(outSourceID, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei(outSourceID, AL_BUFFERS_QUEUED, &queued);


NSLog(@"Processed = %d\n", processed);
NSLog(@"Queued = %d\n", queued);


while(processed--)
{
ALuint buff;
alSourceUnqueueBuffers(outSourceID, 1, &buff);
alDeleteBuffers(1, &buff);
}

return YES;
}

- (void) openAudioFromQueue:(short*)data dataSize:(UInt32)dataSize
index:(int)aIndex
{
ALenum error = AL_NO_ERROR;

if (data == NULL) {
return;
}
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSCondition* ticketCondition= [[NSCondition alloc] init];

[ticketCondition lock];
[self updateQueueBuffer];

ALuint bufferID = 0;
alGenBuffers(1, &bufferID);
if((error = alGetError()) != AL_NO_ERROR) {
NSLog(@"error alGenBuffers: %x\n", error);
}
else {
NSLog(@"suc alGenBuffers: %x\n", error);
// NSLog(@"%s",data);
// int size = strlen( (const char *)data);

NSData * tmpData = [NSData dataWithBytes:data
length:dataSize];
alBufferData(bufferID, AL_FORMAT_MONO16, (const short*)
[tmpData bytes], (ALsizei)[tmpData length], 8000);
if((error = alGetError()) != AL_NO_ERROR)
{
NSLog(@"error sucalBufferData: %x\n", error);
}
else
{
NSLog(@"sucalBufferData: %x\n", error);
alSourceQueueBuffers(outSourceID, 1, &bufferID);
if((error = alGetError()) != AL_NO_ERROR)
{
NSLog(@"error alSourceQueueBuffers: %x\n", error);
}
else
{
NSLog(@"suc alSourceQueueBuffers: %x\n", error);
ALint value;
alGetSourcei(outSourceID,AL_SOURCE_STATE,&value);
// NSLog(@"%x",value);
if (value != AL_PLAYING)
{
NSLog(@"is playing....");
alSourcePlay(outSourceID);
}
if((error = alGetError()) != AL_NO_ERROR)
{
NSLog(@"error alSourcePlay: %x\n", error);
alDeleteBuffers(1, &bufferID);
}
else
{
NSLog(@"suc alSourcePlay: %x\n", error);
}
}
}
}

[ticketCondition unlock];
[ticketCondition release];
ticketCondition = nil;

[pool release];
pool = nil;
}

-(void)stopSound
{
alSourceStop(outSourceID);
}


用完后记得关闭设备

~Y

unread,
Dec 19, 2011, 8:35:15 PM12/19/11
to iOS development
以上代码在模拟器上可以实现,但是在真机上会出点问题,目前在查原因

[广州]Napolen

unread,
Dec 19, 2011, 8:36:50 PM12/19/11
to iOS development
为什么不直接用avplayer?

xiao-北京

unread,
Dec 19, 2011, 8:39:41 PM12/19/11
to iOS development
用的mediaplayer………………看着好复杂
Reply all
Reply to author
Forward
0 new messages