OpenAL播放音频流

使用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];

}



你可能感兴趣的:(OpenAL播放音频流)