ios audioqueue 流播放接口

来源:互联网 发布:jsonarray 添加数据 编辑:程序博客网 时间:2024/05/16 17:20

AudioMedia_ios.h

////  AudioMedia_ios.h//  mmsplayer////  Created by Weiny on 12-4-4.//  Copyright (c) 2012年 Weiny Zhou. All rights reserved.//#ifndef mmsplayer_AudioMedia_ios_h#define mmsplayer_AudioMedia_ios_h#include "wdef.h"typedef void* wAudio;#ifdef __cplusplusextern "C"{#endif    wAudio audio_open(int sample,int nchannles,int bits,int nFrameSize);//初始化声音接口    int audio_play(wAudio audio);//播放int audio_pause(wAudio audio);    int audio_wirte(wAudio audio,unsigned char* pcm,size_t count,int64_t dts);//写入音频数据    int audio_stop(wAudio audio);//停止    int audio_close(wAudio audio);//关闭#ifdef __cplusplus};#endif        #endif


AudioMedia_ios.c

////  AudioMedia_ios.cpp//  mmsplayer////  Created by Weiny on 12-4-4.//  Copyright (c) 2012年 Weiny Zhou. All rights reserved.//#include "AudioMedia_ios.h"#include <AudioToolbox/AudioQueue.h>#include "system/thread.h"#include "base/wlist.h"#include "system/lx_lock.h"#define AUDIO_LIST_COUNT 3#define AUDIO_BUFFER_SECONDS  1typedef struct WAudio_Ios{int playRequested;int framesize;Wlock mlock,mdecdonelock,mqueuelock;wlist_t mAudiolist;//声音队列wlist_func mlistfunc;    AudioQueueRef queue;//player list    AudioQueueBufferRef mBuffers[AUDIO_LIST_COUNT];    AudioStreamBasicDescription mDataFormat;AudioQueueBufferRef emptyAudioBuffer;//空音频队列}WAudio_Ios;typedef struct  {void* data;size_t size;    int64_t dst;}WAudio_item;void wAudio_CallBack(void * in,AudioQueueRef intq,AudioQueueBufferRef outQB);void wAudtio_fillAudioBuffer(WAudio_Ios* audio,AudioQueueBufferRef buffer);static inline void waudio_free_back(void* lpvoid,wlist_item_ptr data){WAudio_item* item;INTOFUNC();if(!data){PRINTF_ERROR_VALUE(ERROR_INITPARAM);goto error_lab;}item=(WAudio_item*)data;SAFE_FREE(item->data);SAFE_FREE(item);error_lab:EXITFUNC();}wAudio audio_open(int sample,int nchannles,int bits,int nFrameSize){    WAudio_Ios* ptr=NULL;    uint32_t err=0;int i=0;    INTOFUNC();    ptr=WOS_MALLOC_(WAudio_Ios, 1);    if(!ptr){        PRINTF_ERROR_VALUE(ERROR_NEWMEM);        goto error_lab;    }    memset(ptr,0,sizeof(WAudio_Ios));    ptr->mDataFormat.mSampleRate=sample;//设置采样率ptr->mDataFormat.mChannelsPerFrame=nchannles;ptr->mDataFormat.mBitsPerChannel=bits;    ptr->mDataFormat.mFormatID=kAudioFormatLinearPCM;//设置数据格式    ptr->mDataFormat.mFormatFlags=kLinearPCMFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked;       ptr->mDataFormat.mFramesPerPacket=1;    ptr->mDataFormat.mBytesPerFrame=ptr->mDataFormat.mBitsPerChannel/ptr->mDataFormat.mChannelsPerFrame;     ptr->mDataFormat.mBytesPerPacket= ptr->mDataFormat.mBytesPerFrame*ptr->mDataFormat. mFramesPerPacket;        err=AudioQueueNewOutput(&ptr->mDataFormat,wAudio_CallBack, ptr, NULL,                             NULL/*kCFRunLoopCommonModes*/, 0                            , &ptr->queue);    if(err){        WERROR_A("init audio output error,sample=%d,channles=%d,bits=%d.\n",sample,nchannles,bits);        goto error_lab;    }for (i=0;i<AUDIO_LIST_COUNT;++i){err=AudioQueueAllocateBufferWithPacketDescriptions(ptr->queue,bits*AUDIO_BUFFER_SECONDS/8,sample*AUDIO_BUFFER_SECONDS/nFrameSize+1,ptr->mBuffers+i);if(err){WERROR_A("can't allocate audio queue buffer: %d",err);            goto error_lab;}}ptr->mlock=lx_lock_init();ptr->mdecdonelock=lx_lock_init();ptr->mqueuelock=lx_lock_init();ptr->mlistfunc=wlist_getfunc();ptr->mAudiolist.free=waudio_free_back;ptr->framesize=nFrameSize;#if 1err=AudioQueueStart(ptr->queue,NULL);if(err){WERROR_A("Error: Audio queue failed to start: %d", err);goto error_lab;}    ptr->playRequested=1;WDEBUG_OUT("Started Audio queue.",NULL);#endif#if 0    agc.FrameCount = FRAME_COUNT;      bufferSize = agc.FrameCount * agc.mDataFormat.mBytesPerFrame;      for (i=0; i<AUDIO_BUFFERS; i++)      {          err = AudioQueueAllocateBuffer(agc.queue,bufferSize,&agc.mBuffers[i]);          if(err) return err;          AQBufferCallback(&agc,agc.queue,agc.mBuffers[i]);      }      err = AudioQueueStart(agc.queue,NULL);      if(err) return err;      while (agc.playPtr<agc.sampleLen)      {          select(NULL,NULL,NULL,NULL,1.0);      }  #endiferror_lab:if(err){audio_close(ptr);SAFE_FREE(ptr);}    EXITFUNC();    return (wAudio)ptr;}int audio_play(wAudio audio){    int nResult=0;    WAudio_Ios* ptr=NULL;    INTOFUNC();    if(!audio){        WERROR_A("input audio is null",NULL);        nResult=ERROR_INITPARAM;        goto error_lab;    }    ptr=(WAudio_Ios*)audio;if(ptr->playRequested==0||ptr->playRequested==2){WERROR_A("state is %d",ptr->playRequested);goto error_lab;}ptr->playRequested=1;AudioQueueStart(ptr->queue,NULL);error_lab:    EXITFUNC();    return nResult;}int audio_pause(wAudio audio){int nResult=0;WAudio_Ios* ptr=NULL;INTOFUNC();if(!audio){WERROR_A("input audio is null",NULL);nResult=ERROR_INITPARAM;goto error_lab;}ptr=(WAudio_Ios*)audio;if(1!=ptr->playRequested){WERROR_A("state is %d",ptr->playRequested);goto error_lab;}ptr->playRequested=2;AudioQueuePause(ptr->queue);error_lab:EXITFUNC();return nResult;}int audio_wirte(wAudio audio,unsigned char* pcm,size_t count,int64_t dst){    int nResult=0;    WAudio_Ios* ptr=NULL;WAudio_item* item=NULL;    INTOFUNC();    if(!audio){        WERROR_A("input audio is null",NULL);        nResult=ERROR_INITPARAM;        goto error_lab;    }    ptr=(WAudio_Ios*)audio;item=WOS_MALLOC_(WAudio_item,1);if(!item){nResult=ERROR_NEWMEM;PRINTF_ERROR_VALUE(nResult);goto error_lab;}item->data=pcm;item->size=count;    item->dst=dst;lx_lock(ptr->mqueuelock);//先加入队列ptr->mlistfunc.push_back(&ptr->mAudiolist,item);//if(ptr->emptyAudioBuffer)wAudtio_fillAudioBuffer(ptr,ptr->emptyAudioBuffer);//填充空bufferlx_unlock(ptr->mqueuelock);error_lab:    EXITFUNC();    return nResult;}int audio_stop(wAudio audio){    int nResult=0;    WAudio_Ios* ptr=NULL;    INTOFUNC();    if(!audio){        WERROR_A("input audio is null",NULL);        nResult=ERROR_INITPARAM;        goto error_lab;    }    ptr=(WAudio_Ios*)audio;    AudioQueueStop(ptr->queue,false);ptr->playRequested=0;error_lab:    EXITFUNC();    return nResult;}int audio_close(wAudio audio){    int nResult=0;    WAudio_Ios* ptr=NULL;    INTOFUNC();    if(!audio){        WERROR_A("input audio is null.",NULL);        nResult=ERROR_INITPARAM;        goto error_lab;    }    ptr=(WAudio_Ios*)audio;ptr->mlistfunc.clear(&ptr->mAudiolist);//清空播放队列lx_lock_free(ptr->mqueuelock);lx_lock_free(ptr->mdecdonelock);lx_lock_free(ptr->mlock);    AudioQueueDispose(ptr->queue,false);    SAFE_FREE(ptr);error_lab:    EXITFUNC();    return nResult;}#if 0void AQBufferCallback( void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB)  {      AQCallbackStruct *agc;      short *coreAudiobuffer;      short sample;      int i;      agc=(AQCallbackStruct *) in;      coreAudiobuffer =(short*) outQB->mAudioData;      printf("Sync:%i / %i \n",agc->playPtr,agc->sampleLen);      if (agc->FrameCount >0)       {          outQB->mAudioDataByteSize = 4*agc->FrameCount;          for (i=0; i<agc->FrameCount*2; i++)           {              if(agc->playPtr > agc->sampleLen || agc->playPtr<0)              {                  sample =0;              }              else              {                  sample = (agc->pcmBuffer[agc->playPtr]);              }              coreAudiobuffer[i] = sample;              coreAudiobuffer[i+1] = sample;              agc->playPtr++;          }          AudioQueueEnqueueBuffer(inQ,outQB,0,NULL);      } }#endifvoid wAudtio_fillAudioBuffer(WAudio_Ios* audio,AudioQueueBufferRef buffer){AudioTimeStamp bufferStartTime;uint32_t err;INTOFUNC();buffer->mAudioDataByteSize=0;buffer->mPacketDescriptionCount=0;if(audio->mAudiolist.size<=0){WERROR_A("Warning: No audio packets in queue.",NULL);audio->emptyAudioBuffer=buffer;goto error_lab;}audio->emptyAudioBuffer=NULL;while(audio->mAudiolist.size&&buffer->mPacketDescriptionCount <buffer->mPacketDescriptionCapacity){wlist_item* item=audio->mlistfunc.pop_front(&audio->mAudiolist);WAudio_item* data=(WAudio_item*)item->data;if(buffer->mAudioDataBytesCapacity -buffer->mAudioDataByteSize >=data->size){            if(buffer->mAudioDataBytesCapacity==0)            {                bufferStartTime.mSampleTime=data->dst*audio->framesize;                bufferStartTime.mFlags=kAudioTimeStampSampleTimeValid;            } memcpy((uint8_t *)buffer->mAudioData + buffer->mAudioDataByteSize, data->data, data->size); buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mStartOffset = buffer->mAudioDataByteSize; buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mDataByteSize = data->size; buffer->mPacketDescriptions[buffer->mPacketDescriptionCount].mVariableFramesInPacket = audio->framesize; buffer->mAudioDataByteSize += data->size; ++buffer->mPacketDescriptionCount; lx_lock(audio->mqueuelock); audio->mlistfunc.remove(&audio->mAudiolist,0); lx_unlock(audio->mqueuelock);}elsebreak;}if(buffer->mPacketDescriptionCount>0){if(err=AudioQueueEnqueueBufferWithParameters(audio->queue,buffer,0,NULL,0,0,0,NULL,&bufferStartTime,NULL))WERROR_A("Error enqueuing audio buffer: %d", err);//decodelocklx_lock(audio->mdecdonelock);if(!audio->playRequested&&audio->mAudiolist.size==0){if(err=AudioQueueStop(audio->queue,false))WERROR_A("Error: Failed to stop audio queue: %d", err);elseWERROR_A("Stopped audio queue",NULL);}lx_unlock(audio->mdecdonelock);//decodeunlock}error_lab:EXITFUNC();}void wAudio_CallBack(void * in,AudioQueueRef intq,AudioQueueBufferRef buffer){    wAudtio_fillAudioBuffer((WAudio_Ios*)in,buffer);}