使用OpenAL播放网路接收到的音频数据流。
////////////////.h 文件
#import <OpenAL/al.h>
#import <OpenAL/alc.h>
OpenAL.framework
ALCcontext *mContext;
ALCdevice *mDevice;
ALuint sourceID;
NSOperationQueue *operationQueue;
#define HZ 8000.0
//////////////////.m文件
-(void)initOpenAL{
//多线程管理
operationQueue = [[NSOperationQueue alloc] init];
[operationQueue setMaxConcurrentOperationCount:1];
mDevice=alcOpenDevice(NULL);
if (mDevice) {
mContext=alcCreateContext(mDevice, NULL);
alcMakeContextCurrent(mContext);
}
//連接到數據源
alGenSources(1, &sourceID);
if(alGetError() != AL_NO_ERROR) {
NSLog(@"Error generating sources! \n");
}
alSourcef(sourceID, AL_PITCH, 1.0f);
alSourcef(sourceID, AL_GAIN, 1.0f); //设置音量
//设置不循环,
alSourcei(sourceID, AL_LOOPING, AL_FALSE);
alSourcef(sourceID, AL_SOURCE_TYPE, AL_STREAMING);
}
- (BOOL) updataQueueBuffer:(id)data {
ALint stateVaue;
int processed, queued;
alGetSourcei(sourceID, AL_SOURCE_STATE, &stateVaue);
if (stateVaue != AL_PLAYING ){
NSLog(@"---- ------ not playing ");
[self playSound];
return NO;
}
alGetSourcei(sourceID, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei(sourceID, AL_BUFFERS_QUEUED, &queued);
NSLog(@"11...processed = %d.queued = %d \n",processed,queued);
while(processed--){
ALint buffer;
alSourceUnqueueBuffers(sourceID, 1, &buffer);
alDeleteBuffers(1, &buffer);
}
return YES;
}
- (void)openAudioFromQueue:(short*)data Len:(UInt32)dataSize {
ALenum error = AL_NO_ERROR;
if(data == NULL)
return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSCondition* ticketCondition= [[NSCondition alloc] init];
[ticketCondition lock];
ALuint bufferID = 0;
alGenBuffers(1, &bufferID);
if((error = alGetError()) != AL_NO_ERROR) {
NSLog(@"222..Error Generating Buffers: %x", error);
}
else{
NSData * data1 = [NSData dataWithBytes:(void *)data length:dataSize];
alBufferData(bufferID, AL_FORMAT_MONO16, (short*)[data1 bytes], (ALsizei)[data1 length], HZ);
alSourceQueueBuffers(sourceID, 1, &bufferID);
if((error = alGetError()) != AL_NO_ERROR){
NSLog(@"3333333 %x\n", error);
}
else{
NSInvocationOperation* oper = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(updataQueueBuffer:) object:nil];
[operationQueue addOperation:oper];
}
}
[ticketCondition unlock];
[ticketCondition release];
ticketCondition = nil;
[pool drain];
}
-(void)playSound {
alSourcePlay(sourceID);
}
-(void)stopSound {
alSourceStop(sourceID);
}
-(void)cleanUpOpenAL {
alDeleteSources(1, &sourceID);
alcDestroyContext(mContext);
alcCloseDevice(mDevice);
}
- (void)audioDatas:(NSData *)data Len:(int)nLen {
[self openAudioFromQueue:(short *)data Len:nLen];
}